2011
Feb
02

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 檔。


require html 範例 : nullByte.php
  1. <?php
  2. $filename=$_GET['name'];
  3. 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:

file_get_contents.php
  1. <?php
  2. $file = $_GET['name'];
  3. $r=file_get_contents('/var/www/'.$file.'.php');
  4. echo $r;

其他如:readfile($_GET['file'].'.php'); $f=fopen($_GET['file'].'.php', 'r');

以上這些碰到Null字元,都會出錯。

PHP程式解決 poison null byte 的辦法

solution.php
  1. <?php
  2. $filename = $_GET['name'];
  3. $filename = preg_replace(chr(0),'',$filename);

或是升級至 php 5.3.4 以上版本





回應 (Leave a comment)