目录
第十二关(都是00截断,只不过一个是post,一个是get):
实验环境:
upload-labs
实验函数:可以去php官网查看---php.net
小皮的php版本调低一点
具体内容实现:
第十关(双写绕过):
源码:
$is_upload = false; $msg = null; 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"); $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 . '文件夹不存在,请手工创建!'; } }
源码分析:先来看一下这几个函数

先使用此函数去掉两边的空白字符以及转义的字符,然后下一个函数再将上传的文件名跟黑名单里面的作比较,如果相同,则从$file_name中删除对应部分
**$file_name = str_ireplace($deny_ext,"", $file_name);
**这段代码试图替换掉不允许的扩展名,但问题是它只是简单地删除了这些扩展名,而不是验证文件名是否合法。
str_ireplace这个函数的工作模式是直接匹配这个字符串中的php字符串,像我们的pphphp中他把"php"匹配走了过后,还是仍然保留的是php所以就是此漏洞形成
思路形成,实践开始:
上传此文件:

查看upload文件夹

上传成功!下一关!
第十一关:(%00截断,此漏洞在5.2版本中)
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
这关的主要一个漏洞来自这里这串代码,我们知道get传参是可以手动修改的,我们先来介绍一下%00截断的原理:
0x00是字符串的结束标识符,攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测。
正确用法
只有数据包中必须含有上传路径的情况下才可以用,比如本次测试中数据包中存在save_path: ../uploads/
,那么攻击者可以通过修改path的值来构造paylod,并且PHP<5.3.29,且magic_quotes_gpc关闭

错误用法
只有文件名的情况下,是不能让%00截断生效的,因为只是文件名可控,即使通过00截断test.php%00.txt
,但是此时经过服务器处理后,文件名仍然为test.php
,不能通过对后缀的检测
思路:
使用 %00
可以绕过这种检测机制,这是因为 PHP 在处理字符串时会将 %00
解释为 NUL 字符,这可能导致某些函数提前终止字符串处理。所以当文件名为 test.php%00.jpg
时,PHP 会将 %00
解释为 NUL 字符,并在处理字符串时将其视为字符串的结束。因此substr($_FILES['upload_file']['name'], strrpos($_FILES['upload_file']['name'], ".") + 1)
会提取到 .jpg
而不是 .php
。
操作过程:
这里主要是通过%00截断的,他是什么原理呢?请看下图,相信你看了就会懂:
所以我们在bs抓包给他改成web.php%00send一下:

先上传一个正确的jpg格式的文件,让服务器能够正常上传
然后打开bs抓包上传


打开upload查看上传情况:

第十二关(都是00截断,只不过一个是post,一个是get):
post传参跟get传参的区别就在于编码的格式不同,一个是传到地址栏进行url编码,%00=/0;而post传参是hex,需要抓包,然后直接修改他的16进制编码:

找20字段,因为我在上传之前在upload/后面打了个空格,URL编码是一种将字符集中的字符编码为仅包含字母、数字以及一些安全符号的方式。具体来说,空格在URL编码中被替换为%20,这里的20是空格字符在ASCII表中的16进制表示。
查看upload文件夹:

ok,继续下一关!
第十三关(图片码绕过):
先来看看源码和说明:

三种后缀原理和思路都是一样的,直接做一类,这里我们用.jpg的来做,注意:构造图片马的时候一句话木马应该加到图片后面,因为我们看源码可以知道,这个是要检测我们的图片头的,所以加到图片的最后面,就不会被检测,我们先用Windows来复制一个图片马,然后上传实现文件包含

只检测两个字节:
然后生成图片马:
copy /b 02.png + 2.php /a test02.png

打开图片看一下一句话木马还有没有:

有我们的一句话木马,好,开始上传文件,然后进行文件包含:
发现,他报了个这样的错,说明他试图在解析我们的php代码,ok,那我们继续换一张图片继续尝试(文件越小越好):
TNND试了7-8次都不行(怀疑是版本太高了,但是我这最低都是5.4),下一关,待会再说,第十四关,十五关一样的跳过:
emmm,查资料看到他说我php.ini那个配置文件里面的allow_url_include=off要修改为On,修改过后我们再次上传:

ok,成功了!!!
第十六关(二次渲染(重要)):

这个函数的作用通过查php的官方文档可以知道,他是将图片进行了重新排列组合,但是人的肉眼看到的新的图片是一样的,就是说他会将我的图片的一句话木马给打乱,所以我们需要借助工具(010editor)或者其他的对比工具,找出这个图片编码没有变化的位置,将一句话木马写到那个位置去,然后再接着上传:
思路大概就是这样,理论形成,实践开始:
上传前看看我们的图片马:

上传后:

看那个函数就知道我的一句话木马没了,所以我们需要去找到不变的位置,然后将一句话木马写进去,这样不管他怎么变化我的一句话木马都还是会留在哪里
借助010editor找到00区域或者空白区域:(找了很久没找到):
经过不懈努力终于找到了这片00区域,然后将我们的一句话木马加进去

然后再次将这个图片上传:我的一句话木马仍然还存在:ok


上传!!!完成此关!