Poison Null Byte就是指使用 Null 字元,造成程式執行錯誤,本來指定要讀取的檔案,變成駭客想要讀取的檔案, Null 在 c語言中就是以「\0」來表示,這個字元代表者一個字串的結尾,如 string = "abc"; , 這個 string 在 memory 中會用掉四個 bytes ,內容是「abc\0」,而假設我故意將 Null 插在 a 與 b 的中間,那麼 string 就會變成 「a\0bc\0」,這時再將 string 印出來到螢幕上時,就會印出 「a」,因為當程式碰到 「\0」,就認定字串已經結束了。
「\0」是程式使用的,在瀏覽器要生出一個 Null Byte 的方式是使用 %00,只要在 url 中輸入 %00 ,瀏覽器會自動將 %00 轉換成 Null Byte
以 php 為例來說,poison null byte 的用法如下
在 include, require, file_get_contents,readfile,fopen 等等, 都有相同的漏洞
例如有些網站為了避免 End User 隨意輸入參數,而在 require 檔案的時候,會自動帶上副檔名 「.html」,強迫程式一定要讀取一個 html 檔。
- <?php
- $filename=$_GET['name'];
- require_once('/var/www/'.$filename.'.html');
程式看起來沒有多大的問題,伺服器裡的 html 檔,本來就是要給 End User 來瀏覽的,就算被亂填檔名,似乎也沒多大的傷害。
但駭客只要使用 「nullByte.php?name=../../etc/passwd%00」 ,當傳入的變數 name = ../../etc/passwd%00, 這時 php 就會讀取 /var/www/../../etc/passwd%00.html 的檔案內容,剛剛有說 %00 代表字串的結尾,所以最後會 require 到 /etc/passwd ,而把系統帳號資料印出來。
若是使用file_get_contents:
- <?php
- $file = $_GET['name'];
- $r=file_get_contents('/var/www/'.$file.'.php');
- echo $r;
其他如:readfile($_GET['file'].'.php'); $f=fopen($_GET['file'].'.php', 'r');
以上這些碰到Null字元,都會出錯。
PHP程式解決 poison null byte 的辦法
- <?php
- $filename = $_GET['name'];
- $filename = preg_replace(chr(0),'',$filename);
或是升級至 php 5.3.4 以上版本