需要了解的前置知识:
1.什么是文件上传:
- 文件上传就是通过流的方式将文件写到服务器上
- 文件上传必须以POST提交表单
- 表单中需要
<input type="file" name="upload">
2.一句话木马
<?php eval($_POST['a']) ?>
其中eval就是执行命令的函数,**$_POST[‘a’]**就是接收的数据。eval函数把接收的数据当作PHP代码来执行。这样我们就能够让插入了一句话木马的网站执行我们传递过去的任意PHP语句。这便是一句话木马的强大之处。详解参考文章
3.文件上传漏洞的类型
实例:
1 前端验证:
将一句话木马写进php文件里,然后上传,弹出:
这是前端JavaScript控制的,按F12可以看到
function checkfilesuffix() {
var file=document.getElementsByName('file')[0]['value'];
if(file==""||file==null) {
alert("请添加上传文件"); return false; }
else { var whitelist=new Array(".jpg",".png",".gif");
var file_suffix=file.substring(file.lastIndexOf(".")); if(whitelist.indexOf(file_suffix) == -1) {
alert("该文件不允许上传"); return false; } } }
我们可以在前端把JavaScript关掉,这里我用的是火狐的JavaScript switch插件 ,关掉浏览器的JavaScript,然后重新提交:
成功上传,我们打开蚁剑连接
找到FLAG
2.文件头检查:
文件头检查是指当浏览器上传到服务器的时候,白名单进行的文件头检测,符合,则允许上传,否则不允许上传。我们可以自己造一个图片木马,打开电脑画图,画一条直线,保存然后打开方式选为记事本,将一句话木马插入进去,我们在进行上传:
上传成功,但是使用蚁剑无法连接,因为上传进去的是PNG文件,不是PHP文件,所以无法解析,这时候我们用brupsuit抓包:
我们把filename改成1.php然后再上传:
这时候已经上传成功,我们连接蚁剑查看
我们上传的两个文件,然后在上一级就可以找到FLAG了
- .htaccess
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置,通过.htaccess文件可以实现网页301重定向、自定义404页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。详细请参考文章连接
需要写进.htaccess文件里的代码
<FilesMatch >Sethandlerapplication/x-httpd-php
</Filesmatch >
也可以直接写 Sethandlerapplication/x-httpd-php
意思是将文件都按照PHP文件来执行,这样插进去一个PNG的文件也可以作为PHP文件执行,从而控制网站
第一步先将.htaccess文件传输进去,然后再传含一句话木马的PNG文件:
然后再上传一张含有一句话木马的图片:
使用蚁剑进行连接:
可以看到我们上传的两个文件,返回上一级可以拿到flag
4.MIME绕过(关于MIME的详解)
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
我们先上传一张图片,抓个包:
可以看到类型是 image/png
然后我们上传一个PHP文件,将Content-Type改为 image/png 从而进行绕过:
然后成功上传,用蚁剑连接拿到flag:
5.%00绕过()
- www.xxx.com/qq.jpg
- www.xxx.com/qq.php%00.jpg => www.xxx.com/qq.php
%00就是截断符号,%00后面的直接舍弃掉,如果用get提交,直接加%00阶段即可,若是用POST提交,则需要对%00进行编码,这是因为 %00 截断在 GET 中被 url 解码之后是空字符。但是在 POST 中 %00 不会被 url 解码,所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断。
这里我没有操作成功,点击可以参考大佬文章
6.双写绕过:
先看代码:
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.'文件夹不存在,请手工创建!';
}
}
绕过方法
这里我们可以看到将文件名替换为空,我们可以采用双写绕过:1.pphphp
7.空格绕过 点绕过 ::$DATA绕过
• 在上传文件的时候用bp抓包 ,在filename后面加入一个空格即可,不会被吞噬掉
• 在上传文件的时候用bp抓包 ,在filename后面加入一个点即可,不会被吞噬掉
• 在window的时候如果文件名+":: D A T A " 会 把 : : DATA"会把:: DATA"会把::DATA之后的数据当成文件流处理,不会检测后缀名,且保持:: D A T A 之 前 的 文 件 名 , 他 的 目 的 就 是 不 检 查 后 缀 名 例 如 : " p h p i n f o . p h p : : DATA之前的文件名,他的目的就是不检查后缀名 例如:"phpinfo.php:: DATA之前的文件名,他的目的就是不检查后缀名例如:"phpinfo.php::DATA"Windows会自动去掉末尾的::$DATA变成"phpinfo.php"
- 有时候也是点加空格然后再加点进行绕过