目录
Pass-11
什么鬼,我都做好了上传不成功的准备,结果sh.php居然上传成功了。
一看Response报文,果然事情没有这么简单,后端自动把文件名中的php去掉了,文件名变成sh.了
这样的话,盲猜可以用双写绕过。这关直接在repeater中试一下,就不劳intruder大驾了。
果然,双写php之后,服务器上保存的文件名是sh.php,成功绕过黑名单过滤。
代码分析:
本关代码在文件名中出现黑名单中的字符串时,用str_ireplace()函数替换为啥也没有,但是这个替换它不迭代,所以采用套娃的方式双写敏感后缀就可以绕过了。
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = str_ireplace($deny_ext,"", $file_name);
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
Pass-12
上传sh.php之后,看这关页面返回的提示,似乎是白名单过滤呢
不死心,burp中把上图所示的报文send to repeater,发现filename改成sh.xxx上传失败,改成sh.jpg上传成功。看来真是文件名后缀的白名单过滤……
白名单还怎么玩呢(如果没有文件包含漏洞的话)……幸好这关看上去上传的文件的保存路径是用户可控的。如上图所示,请求报文的url中有个save_path参数,文件上传到服务器后的位置似乎是由这个参数决定的,这就给了%00截断发挥的机会。
构造请求报文,filename保持sh.jpg,为的是通过对文件名后缀的白名单校验;save_path的值改为 ../upload/sh.php%00,为的是使程序以为上传的文件应该保存为../upload/sh.php
虽然Response报文中显示的图片路径挺奇葩,但是后面分析代码的时候就知道显示的这个并不是文件真正的路径,实际上文件被保存为C:\phpstudy_pro\WWW\upload-labs\upload\sh.php