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)