當前位置:
首頁 > 新聞 > 源碼級剖析PHP 7.2.x GD拒絕服務漏洞

源碼級剖析PHP 7.2.x GD拒絕服務漏洞

*本文原創作者:chilau,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載


觸發條件:



php 7.2.x,開啟gd庫。只需要三行代碼即可完成!


我在本地調試php的時候發現某個老代碼能夠直接把php給crash掉,因此成文。



php沒有報錯,直接死掉了,應該是內部邏輯有問題。再傳到伺服器上試試:



啊哈,一樣的結果。觸發這個問題的代碼如下:

$im=imagecreate(100,100);
imageantialias($im,true);
imageline($im,0,0,10,10,0xffffff);

話不多說,上vs調試。先看調用堆棧吧。


從這裡可以看出是在GD庫的畫像素點的地方出了錯,被調試器斷在了gdImageSetAAPixelColor這個函數里。



再看對應代碼,訪問了gdImagePtr結構體中的一個成員,導致訪問違例。我們再從即時窗口檢查一下:



沒錯,tpixels是個空指針!


那tpixels是幹啥的呢?在gd.h裡面有如下說明:

/* Truecolor flag and pixels. New 2.0 fields appear here at the
end to minimize breakage of existing object code. */
int trueColor;
int ** tpixels;

看來是和真彩色相關的東西,我們再沿著調用堆棧往前看。



這裡是gdImageAALine函數,一個個點地畫線,乾的是苦力活。從gdImageLine里調用了它:


這裡的條件判斷是是否開啟了

防鋸齒

功能。如果我們調用imageantialias函數打開這個功能,那麼就會走這裡來。



上面圖裡就是我們從php調用的imageline函數的實現啦,非常簡單。可以看出圖片是真彩色的時候它會默認開啟防鋸齒功能。


這裡問題就在於,我們創建(imagecreate)的圖片不是真彩色的圖,而後我們手動開啟了防鋸齒(imageantialias),調用進去想當然地把它當作一張真彩色圖,從而導致了錯誤。


最後我們來看看兩個函數的不同:



跟進去,可以看到imagecreate函數調用的gdImageCreate里直接把真彩色相關的成員設為了null。


與之對比,imagecreatetruecolor函數調用的gdImageCreateTrueColor函數里為每個像素點都分配了對應內存並初始化為0了:


 

總結一下,從上面分析可以看出,觸發這個問題的條件有3個:



1.php版本為7.2.x且開啟了gd庫


2.創建了非真彩色圖且開啟抗鋸齒


3.在創建的圖句柄上進行像素點寫入


導致這個問題的原因還是代碼修改考慮不周全,引入了新的漏洞;沒有對所有可能條件進行測試,所以從php 7.2.0一直到php 7.2.4都還存在問題。


已經向php官方報告,如果正在生產環境使用相關版本請退回舊版本,舊版本里不存在這個問題。


*本文原創作者:chilau,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

將REMnux部署到雲上,在雲上完成惡意軟體的逆向分析
技術解析 | Web緩存欺騙測試

TAG:FreeBuf |