我使用了一個特殊的圖片上傳技巧,繞過PHP GD庫對圖片的轉換處理,最終成功實現了遠程代碼執行。php
事情是這樣的。當時我正在測試該網站上是否存在sql注入漏洞,不經意間我在網站我的頁面發現了一個用於上傳頭像的文件上傳表單。開始時我並沒期望在上傳功能處發現漏洞,但我決定試試。html
我上傳了一個圖片文件,經過截斷http數據包,修改jpg圖片的文件名後綴爲php,而後繼續上傳。我驚訝的竟然上傳成功了,我幾乎不敢相信這麼簡單的漏洞竟然存在。因而我複製了圖片url而且在瀏覽器上打開。進入我眼簾的是圖片的二進制代碼,這意味着圖片以php解析了,並根據響應包裏的content-type以text/html格式返回。sql
我如今要作的是在jpg文件中注入php代碼以進行遠程代碼執行,因而我嘗試將代碼<? phpinfo(); ?>寫入圖片的EXIF頭裏,可是悲劇的是再次上傳發現php代碼沒有被執行。瀏覽器
在本機進行了測試,結果仍然無效——代碼沒有被執行服務器
在上傳到服務器後,EXIF裏的代碼都被刪除了,應用經過imagecreatefromjpeg()函數調用了PHP GD庫(GD庫,是php處理圖形的擴展庫),對圖片進行了轉換。那麼若是不將代碼注入EXIF頭而是注入到圖片裏呢?編輯器
本機測試經過,但當我上傳「1.jpg」到服務器上,返回如下結果:ide
報錯上寫着「文件必須是合法的圖片(.gif, .jpg, .jpeg, 或.png)」,我驚歎於應用是怎麼判斷圖片不合法的。我又測試了一些其餘jpg文件,結果發現修改任何一個圖片字符都會引發php-gd庫的錯誤判斷,進而形成上傳失敗。函數
接下來我又使用gif圖片進行了一樣的操做,結果是:圖片上傳成功了,可是圖片中的php代碼徹底被刪除了。測試
雖然這看起來難以想象,可是我不能放棄,由於如今距離成功利用遠程代碼執行(RCE)只有一步之遙,我必須繞過imagecreatefromgif()函數。我對圖片的處理和php GD庫的運行知之甚少,但是這不影響我使用一些傳統滲透測試方法。網站
我想到一個方法:對比兩張通過php-gd庫轉換過的gif圖片,若是其中存在相同之處,這就證實這部分圖片數據不會通過轉換。而後我能夠注入代碼到這部分圖片文件中,最終實現遠程代碼執行。連我本身都佩服個人機智!
如圖,我用十六進制編輯器打開圖片文件,找到了php轉換先後仍然保持相同的十六進制串「3b45d00ceade0c1a3f0e18aff1」並修改它爲<?phpinfo()?>。
保存圖片,上傳到服務器:
個人PHP代碼被執行了,我最終成功實現了遠程代碼執行。
POC圖片下載地址:
POC.rar 密碼freebuf