截斷在文件包含和上傳中的利用 2016-06-16
本文轉自http://www.joychou.org/index.php/web/truncated.html
截斷大概可以在以下情況適用
- include(require)
- file_get_contents
- file_exists
- 所有url中參數可以用%00控制
0x01. 本地文件包含
1.1 截斷類型:php %00截斷
截斷條件:
php版本小于5.3.4 詳情關注CVE-2006-7243
php的magic_quotes_gpc為OFF狀態
漏洞文件lfi.php
要include的password文件
Password
利用代碼:lfi.php?action=password%00
注意:url正宗%00是被會url解碼成0x00,所以可能導致截斷。
password文件被成功包含并且執行phpinfo()函數。
如果沒有截斷條件,lfi.php就只能包含php擴展名的文件。
相反,如果有截斷條件,lfi.php可以包含任意文件的擴展名。
當把magic_quotes_gpc打開,php版本依然是5.2.9時,再測試,結果%00被轉義成了0兩個單體字符,不再具有截斷功能。
原因是:當打開magic_quotes_gpc
時,所有的 ‘(單引號),”(雙引號),(反斜線)和 NULL字符(%00)都會被自動加上一個反斜線進行轉義。還有很多函數有類似的作用 如:addslashes()
、mysql_escape_string()
、mysql_real_escape_string()
等
當把magic_quotes_gpc
關閉,php版本依然是5.3.10時,依然不能截斷。所以證明,php版本和gpc兩個條件都必須滿足,才能截斷。
除了上面的include、require、include_once、require_once還有file_get_contents也能配合php %00利用。
FileGetContents.php
利用方式:http://www.victim.com/FileGetContents.php?file=password%00
此時可以看到當前目錄put.txt是上面password中的內容。
Password
1.2 文件路徑長度截斷
除了1.1說的%00可以截斷,還可以用字符.或者/.,或者./(注意順序)來截斷,不能純用/,至于為什么,不能用其他字符,想必應該和php實現有關。
系統文件路徑長度限制:
windows 259個bytes
linux 4096個bytes
具體可以看這篇文章:http://joychou.org/index.php/Misc/filename-length-limit-on-windows-linux.html
截斷條件:
php版本為5.3.4以下(具體哪個版本不是很清楚,烏云上kukki寫的5.2.8以下,這明顯是不對的,因為我測試用的5.2.9)
GPC是否開啟沒關系
漏洞代碼lfi.php,和1.1中的lfi.php一樣
在windows下需要.字符最少的利用POC:
lfi.php?action=password..............................................................................................................................................................................................................................................
成功包含,執行password里面的phpinfo函數
加上根目錄路徑一共為258個字節。所以需要的最少的.數為
258 - (lfi.php文件的路徑長度即C:/wamp/www/+strlen(‘password’))
或者用./截斷,最短的POC為,并且最短路徑長度為258
lfi.php?action=password./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
將password文件名改為password123后,最短的POC為,最短路徑長度依然為258
lfi.php?password123/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
注意這兩者一個是/開始,一個是.開始,這和路徑長度的奇偶有關系,真正遇到這樣的情況,就丟很長的/.,最后再跳整下第一個/或者.即可。
linux就自行測試吧。
0x02. 文件上傳
截斷類型:php的%00截斷。所以截斷的條件依然是php %00截斷的條件
- php版本5.3.4以下
- gpc關閉
測試環境:
php版本5.2.9
gpc關閉
漏洞代碼 upload.php
File Upload Vulnerability
文件:
這個漏洞代碼是我YY的,可能實際情況不一定能夠用上。只是證明截斷可以達到上傳的功能。
先將一個php木馬重命名為上面擴展名為白名單的后綴,比如.jpg
訪問:http://www.victim.com/upload.php?jieduan=xxoo.php%00
點擊submit按鈕,就在server上生成了一個xxoo.php的馬。
0x03. file_exists判斷文件是否存在
file_exists在判斷文件存在的時候也有被截斷的現象。
截斷條件:
- php版本小于5.3.4
- GPC關閉狀態
- 漏洞代碼如下,和CVE-2014-8959 phpmyadmin的這個漏洞一樣。
當前目錄存在一個shell.jpg文件,此時訪問?file=shell.jpg%00,返回結果是文件存在。
有一個小技巧:
當上面文件第五行變成$filename = 'xxoo' . $file . '.php';
,如果仍然要用shell.jpg,那么只需這樣構造:?file=/../shell.jpg%00
,利用/../回到當前目錄。
在php中一些目錄切換
- ../表示上一層目錄
- ./表示當前目錄
- /單獨使用不能表示當前目錄,只用xx/這樣才能表示xx這個目錄
參考文章