一、00截断的原理
00截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0(即0x00)作为字符串的结尾。操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符号。因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的。00截断通常用来绕过web软waf的白名单限制。
二、php环境00截断的条件
- php版本小于5.3.29
- magic_quotes_gpc = Off
三、php环境00截断详解
1、文件上传后端源码:
<?php
var_dump($_FILES['upload_file']); //打印接收的文件变量数组
echo "<br />";
$file_ext = substr($_FILES['upload_file']['name'],strrops($_FILES['upload_file']['name'],".")+1); //截取文件名后缀
var_dump($file_ext);
echo "<br />";
$tmp_file = $FILES['upload_file']['tmp_name'] //文件临时存储位置
vardump($tmp_file);
echo "<br />";
$img_path = $_POST['save_path']."/".rand(100,999).date("YmdHis").".".$file_ext; //将上传目录、随机数、时间戳和扩展名拼接为文件保存路径
var_dump($img_path);
echo "<br />";
move_upload_file($tmp_file,$img_path); //将临时文件移动到文件保存路径上
?>
<form enctype="multipart/form-data" method="post">
<p>请选择要上传的图片:</p>
<input type="hidden" name="save_path" value="upload" />
<input class="input_file" type="file" name="upload_file" />
<input class="button" type="submit" name="submit" value="上传" />
</form>
2、客户端页面:
3、上传info.png文件burp抓包。可以看到,当前端提交请求时,系统自动产生一个filename=“info.png"。后端则由$_FILES[‘upload_file’][‘name’]变量进行接收。
4、错误截断方式。改包filename="info.png\0.jpg"重放,发现$_FILES[‘upload_file’][‘name’]变量在接收filename的值时,自动将\0后的字符串进行的截断,此处取后缀仍然为.php,因此不能通过修改filename的值来进行00截断。
5、正确截断姿势。改包:在upload后加\0/1.php,重放后返回路径$img_path值为
string(34) “upload/1.php/6920200330192442.png”,其中包含\0,因此可以总结出,除了$_FILES[‘upload_file’][‘name’]这种变量,其他变量都会将字符串原封不动进行拼接,形成字符串变量中存在\0字符,一旦这个字符串被操作系统用作文件的命名,就会产生00截断的情况。
此时后端upload文件夹,生成1.php文件
- 00截断时,实际上传的变量值
$destination = uploading/1.php\0time().random(100,999)".".$ext
- get方法中,当url中加入%00时,通过urlencode,%00得到字符\0。
6、总结此类截断的几个关键参数
上传目录 | 时间戳+随机数 | 扩展名 |
---|---|---|
upload/ | time().random(1000,9999) | ext |
上传目录可控 | 修改文件名防止重复命名 | 扩展名符合白名单 |