1、通过本次实验掌握
00
截断的原理。
2、通过upload-labs-master
闯关游戏Pass-11
,Pass-12
,掌握00截断绕过
技术。
BurpSuite
火狐/谷歌浏览器
靶 机: windows10虚拟机:
192.168.100.150
upload-labs-master
闯关游戏
phpstudy2018
搭建网站
攻击机: 物理机
magic_quotes_gpc魔术函数
:
magic_quotes_gpc魔术函数
的作用就是将我们输入的敏感字符进行自动转义。
切换php版本:
如果 windows10虚拟机里面的环境无法使用,可以偿试在物理面里面进行实验,或者在windows2008中实验。
虽然web应用做了校验,但是由于文件上传后的
路径用户可以控制
,攻击者可以利用手动添加字符串标识符0X00
的方式来将后面的拼接的内容进行截断
,导致后面的内容无效,而且后面的内容又可以帮助我们绕过黑白名单的检测。
在
C语言
中,空字符
有一个特殊含义,代表字符串的拼接结束。
这里我们使用的是php语言
,属于高级语言,底层靠C语言
来实现的,也就是说空字符
的字符串拼接结束功能在PHP
中也能实现。但是我们在URL中不能直接使用空
,这样会造成无法识别;我们通过查看ASCII对照表
,发现ASCII对照表
第一个就空字符
,它对应的16进制是00
,这里我们就可以用16进制的00
来代替空字符
,让它截断
后面的内容。
点击进入:ASCII对照表
页面源码:
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){ //接收上传的图片;
$ext_arr = array('jpg','png','gif'); //声明一个数组,里面有'jpg','png','gif';
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1); //截取文件的后缀名
if(in_array($file_ext,$ext_arr)){ //验证后缀名是否在数组里面;
$temp_file = $_FILES['upload_file']['tmp_name']; //如果数组里面有这个后缀名,就获取临时文件名;
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; //进行构造上传后的文件存储路径;
/*
$_GET['save_path'] 通过GET的请求方式获得文件路径;通过这种方式获得的文件路径是用户可控的;
.rand(10, 99).date("YmdHis").".".$file_ext; 这里主要是对文件名进行重构;
*/
if(move_uploaded_file($temp_file,$img_path)){ //将上传的文件进行转存,从临时路径转存到构造的路径;
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
通过上面源码可以看出,这里的上传路路径是用户可控的;这关主要看$_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
中的$_GET['save_path']
请求, 是通过GET的请求方式获得文件上传后的存储路径,然后通过URL的方式传递到后台;通过这种方式获得的文件路径是用户可控的。
1、创建一个文本文件,并给它重命名为1.jpg,重命名是为了让它通过白名单的检测:
内容:
phpinfo(); ?>
2、 上传2.jpg
文件:
3、使用burpsuite
进行抓包,因为这里是通过URL
进行传递的文件上传后存储路径,所以需要对16进制
的00
进行URL编码
,编码的结果就是%00
,通过这种方式,就可以%00
截断后面的内容,让拼接的文件名不再进行生效:
5、需要删除php后面的内容,再进行访问,可以正常进行解析:
1、修改文件为
*.jpg
;
2、使用burpsuite
进行抓包,修改文件名为:*.php%00.jpg
文件上传后的存储路径相当于:$img_path=../upload/*.php%00.jpg
。
页面源码:
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = "上传失败";
}
} else {
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
1、上传一个1.jpg
的文件,重命名是为了让它通过白名单的检测:
2、使用burpsuite
进行抓包,修改为%00
发现上传文件失败:
注:出现这个问题的原因是因为前面Pass11
是通过GET请求
方式获得的文件上传路径,而GET请求
方式是通过URL
进行传输数据的,需要进行URL编码
,%00
是16进制
进行URL编码
后的结果;而Pass12
是POST请求
方式,不是通过URL
进行传输数据,所以不用进行URL编码,使用URL编码后截断就会导致上传失败。
3、通过下面的方式对%00
进行URL
解码,并发送数据: