PHP %00漏洞,在很多網站的安全測試中被廣泛使用。它是一種利用PHP語言中空字符(%00)的特性,在文件名等參數中插入攻擊代碼的一種攻擊方式。通過%00這個字符,攻擊者可以將正常請求參數截斷,相當于修改了請求參數,造成安全漏洞。
具體來說,攻擊者可以構造一個請求,包含惡意payload,然后在請求中插入%00字符,截斷后面的參數。這樣服務器在判斷傳入參數的時候就會出現誤判,將惡意payload也帶上了。
例如以下URL: http://example.com/index.php?file=example.txt%00.php 如果服務器后臺未對$files參數加以過濾處理,解析的結果為: $file = "example.txt"; 可是,由于%00的存在,后面的".php"部分被截斷了,最后服務器得到的文件名是"example.txt.php"。這顯然是不安全的,攻擊者可以非法操作被下發的惡意文件。
另外,這種攻擊方式還可以利用幾乎所有的PHP函數和擴展,例如serialize和unserialize等。因為這兩個方法也可以將二進制數據轉化成字符串中的變量。假如攻擊者在傳遞數值時,在%00后加入一些對unserialize的關鍵字,就可以導致反序列化漏洞,進一步造成危害。
例如以下代碼: $json = '[1, 2, {"a": "value","b": false}]'; $obj = json_decode($json); $serialized = serialize($obj); // Serialized value: 'a:3:{i:0;i:1;i:1;i:2;i:2;a:2:{s:1:"a";s:5:"value";s:1:"b";b:0;}}' // 注意是a:[si]:即0、1、2 $serialized = str_replace("a:2:{s:1:\"a\";s:5:\"value\";s:1:\"b\";b:0;}","a:1:{s:1:\"c\";s:2:\"hi\";}",$serialized); $deserialized = unserialize($serialized); // if ($_REQUEST['pass'] == "toooo"){ // var_dump($deserialized[2]); // exit(); // }
在上述代碼中,攻擊者可以通過繞過后端安全檢測,在getQuery中插入%00,使得后端繞過防火墻后,使用get參數pass,就可以達到魔改json,危害服務器的效果。
一些PHP開發者可能僅僅注意到了代碼的正確性,卻忽略了對用戶的輸入進行過濾等安全性方面的措施。可以看出,PHP %00漏洞隱藏性強、利用方法多樣,這也給PHP開發人員的工作帶來了更大的責任。