安全圈 | 专注于最新网络信息安全讯息新闻

首页

php安全開發中常見的dos風險

作者 lervik 时间 2020-02-27
all

近期收到某友方SRC發來的郵件,迴響網站中存在可被Dos的風險,複測後發現確實存在此類風險。

隨後嘗試對其進行修復,過程滿有意思的,所以匯總了一下在PHP開發中容易引起Dos的幾個點。

Ps:所有內容僅供學習研究及分析,請勿用於進行互聯網惡意攻擊行為,因惡意攻擊造成的損失均與本文作者無關。

會引起Dos的幾種案例

CVE-2015-4024

CVE-2015-4024

早起危害較大的Dos漏洞,挺有代表性的。其原理是php解析body part的header時進行字串拼接,而拼接過程重複拷貝字元導致DOS。對應官方bug:

https://bugs.php.net/bug.php?id=69364

https://bugs.php.net/bug.php?id=69364

XML待辦事項

XML Dos

也叫XML Bomb,其原理是通過無限制的遞迴,或傳遞的實體內容過大造成記憶體占滿,從而實現Dos。

XML Bomb

背部

Json Dos

它主要利用了PHP Hash Collision,早在2013年被發現並收到重視。但是在開發中,濫用相關函數便會造成此類Dos的出現。

PHP Hash Collision

在較老的版本中通過提交POST參數,也能實現PHP Hash Collision。

POST PHP Hash Collision

攻擊實例

CVE-2015-4024

該漏洞是比較老的一個的,已被修復很久網上也有很多文章及介紹,當然官方bugs裏寫個人認為是描述最全的,給Shusheng Liu大佬點贊。

bugs Shusheng Liu

具體產生原因則需要追PHP的引擎程式碼了,在這我就不贅述了應用說明概括

由於php沒有妥善處理multipart/form-data請求的body part請求頭,對於換行內容多次重新申請記憶體,導致耗盡CPU資源,拒絕服務電腦。-- PHITHON

multipart/form-data body part

複現過程:

复现过程:

首先通過docker運行一個未升級版的php-fpm容器

docker php-fpm 容器

nginx應用為物理機,php-fpm則啟動容器方便切換不同版本。

nginx php-fpm

PHP檔案(post_exp.php)簡單構造一個from表單,接收POST過來的參數並輸出:

post_exp.php

現在我們來看看,正常提交參數的回應時間是多少:

僅0.03/s,通過BurpSuite改成惡意請求後提交查看本次服務器響應時長。

0.03/s BurpSuite

服務器回應時間為:11.16/s,說明本次複現成功。

11.16/s

XML Dos

該風險常發生在對外提供介面,並接收惡意XML(對接過Dot Net的同學都知道WSDL吧)實體,從而讓應用進行無限制的遞迴,導致耗盡CPU資源。

XML Dot Net WSDL

PHP檔案(xml_exp.php)用於接收POST過來的XML實體,處理後輸出:

xml_exp.php

前面已知一個正常的請求相應時長一般在0.03/s之內,超出時間則表示攻擊成功。現在發送一個可遞迴的POST請求並發送。

0.03/s

本次攻擊並沒有生效,懷疑是SimpleXML擴展已被修復並限制了遞迴深度,超出則終止應用。

SimpleXML

將要提交的xml內容修改為只保留一行,並引用&a:

&a

就像圖中看到的,雖然單個請求看起來效果不大,如果是多個呢?(文章中用的壓測工具是Jmeter)

當然,我的小水管電腦肯定和服務器級別的沒法比,這裡僅供學習研究了。

然後我在官方bugs中又看到一個有意思場景,可直接占滿伺服器記憶體(當前php-fpm版本:5.5.30)。

bugs php-fpm版本:5.5.30

抱歉此處沒有配圖,電腦的記憶體被php-fpm行程占滿,多達6G內容使用量。直至超過50秒行程被kill

Json Dos

這類攻擊早在2011年就被發現並利用,根據搜尋引擎找到大神Laruence的個人部落格,其在2011-12-29日至30日的文章中有詳細介紹。攻擊的原理很簡單,就是將語言底層保存POST數據的Hash錶因為衝突(碰撞)而退化成鏈表.

Laruence 冲突(碰撞)

詳見:http://www.laruence.com/2011/12/30/2435.html

通過情况下,只要給提交POST參數一個接收最大個數即可緩解此類情况。但隨著業務越來越複雜,數據互動時類型的多樣性而變的脆弱。

POST

假設該場景,用戶在頁面視窗填寫帳號密碼並點擊登入,此時會通過AJAX發送拼接好的json字串到介面。

PHP檔案(json_exp.php)用於接收POST過來的json字串,並處理成數組:

json_exp.php

一次正常的請求應用回應時間是在毫秒以內,現在我們構造一段惡意的json,並發送至介面。

{“0”:0,“65536”:0,“131072”:0,“196608”:0,“262144”:0,“327680”:0,“393216”:0,“458752”:0,……,“4294836224”:0,“4294901760”:0}

看到了嗎,一次請求的響應時長是20多秒,至於如何避免該問題請看防禦章節(高效一招防)。

20多秒

順便實驗了一下現時5.6.×以下所有版本均有這個問題,直到PHP7才被減緩優化至4秒(贊鳥哥)。

5.6.× PHP7

如何防禦

知攻不知防,幾年都瞎忙

對於CVE-2015-4024的利用只需要升至最新的PHP版本即可。

CVE-2015-4024

XML Dos

我們都知道在PHP中防禦外部DTD攻擊,只需要在解析XML內容之前,加入libxml_disable_entity_loader(true);函數即可。

libxml_disable_entity_loader(true);

但這種XML Bomb使用的是內部DTD,遺憾的是我翻過官方手册也google了一圈,並沒有發現PHP中有禁用內部DTD的函數及方法。

XML Bomb

所以這裡只能使用正則匹配去識別攻擊了,匹配DTD中的關鍵字:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。

<!DOCTYPE 和 <!ENTITY,或者 SYSTEM 和PUBLIC。

而解析大的XML檔案可能會花費大量時間和記憶體。如果你的體系結構允許,可以考慮將大的XML檔案解析放在非同步進行。當XML文件上傳時,將它們移到隊列中,並有一個單獨的行程將它們從隊列中取出並處理解析任務。

這種方法將提高系統的可擴展性和穩定性,因為繁重的分析工作不會使Web服務器離線。

Json Dos

該攻擊的防禦蠻簡單的,不要使用json_decode函數中的第二個參數。也是就常用來將json對象轉數組的參數。

json_decode 第二个参数

我的解決辦法是用PHP的強制類型轉換,替換json_decode的功能(不知道是我搜尋引擎使用方法不對還是咋的,居然沒有看到用這種方法去解决的栗子,也是醉了)。

PHP的强制类型转换 json_decode

耗時0.112秒!!!

0.112

隨後對$arrays變數怎麼使用就不說了,基本操作。但有一點很重要:不要去遍歷它,不要去遍歷它,不要去遍歷它

$arrays

.21442;.32771

https://www.leavesongs.com/PHP/PHP-Multipart-form-date-remote-DOS-Vulnerability.html

http://nikic.github.io/2011/12/28/supercalliding-a-PHP-array.html

https://yq.aliyun.com/articles/92194

https://msdn.microsoft.com/zh-cn/magazine/ee335713.aspx