PHP文件包含漏洞(利用phpinfo)復現
0x01 簡介
PHP文件包含漏洞中,如果找不到可以包含的文件,我們可以通過包含臨時文件的方法來getshell。因為臨時文件名是隨機的,如果目標網站上存在phpinfo,則可以通過phpinfo來獲取臨時文件名,進而進行包含。
0x02 漏洞利用原理
在給PHP發送POST數據包時,如果數據包里包含文件區塊,無論你訪問的程式碼中有沒有處理文件上傳的邏輯,PHP都會將這個文件保存成一個臨時文件(通常是/tmp/php[6個隨機字元]),文件名可以在$_FILES變數中找到。這個臨時文件,在請求結束後就會被刪除。
同時,因為phpinfo頁面會將當前請求上下文中所有變數都列印出來,所以我們如果向phpinfo頁面發送包含文件區塊的數據包,則即可在返回包里找到$_FILES變數的內容,自然也包含臨時文件名。
在文件包含漏洞找不到可利用的文件時,即可利用這個方法,找到臨時文件名,然後包含之。
但文件包含漏洞和phpinfo頁面通常是兩個頁面,理論上我們需要先發送數據包給phpinfo頁面,然後從返回頁面中匹配出臨時文件名,再將這個文件名發送給文件包含漏洞頁面,進行getshell。在第一個請求結束時,臨時文件就被刪除了,第二個請求自然也就無法進行包含。
這個時候就需要用到條件競爭,具體流程如下:
- 發送包含了webshell的上傳數據包給phpinfo頁面,這個數據包的header、get等位置需要塞滿垃圾數據
- 因為phpinfo頁面會將所有數據都列印出來,1中的垃圾數據會將整個phpinfo頁面撐得非常大
- php默認的輸出緩衝區大小為4096,可以理解為php每次返回4096個位元組給socket連接
- 所以,我們直接操作原生socket,每次讀取4096個位元組。只要讀取到的字元里包含臨時文件名,就立即發送第二個數據包
- 此時,第一個數據包的socket連接實際上還沒結束,因為php還在繼續每次輸出4096個位元組,所以臨時文件此時還沒有刪除
- 利用這個時間差,第二個數據包,也就是文件包含漏洞的利用,即可成功包含臨時文件,最終getshell
0x03 漏洞復現
漏洞環境在vulhub上可以獲取
//github.com/vulhub/vulhub/tree/master/php/inclusion
直接在docker上拉取環境
環境啟動後,訪問//ip:8080/phpinfo.php即可看到一個PHPINFO頁面,訪問//ip:8080/lfi.php?file=/etc/passwd,可見的確存在文件包含漏洞。
用exp.py腳本來不斷的上傳數據,利用條件競爭實現包含文件。
成功包含臨時文件後,會執行‘)?>,寫入一個新的文件g到/tmp/目錄。
用python2執行:python exp.py your-ip 8080 100
看到只用了100個數據包的時候就寫入成功了,之後就可以配合lfi.php執行任意命令,然後配合之前存在文件包含漏洞的php文件,就可以任意命令執行。
查看文件
0x04 參考文章
//github.com/vulhub/vulhub/tree/master/php/inclusion
//dl.packetstormsecurity.net/papers/general/LFI_With_PHPInfo_Assitance.pdf