中间件漏洞
IIS
- IIS6.0文件解析 xx.asp;.jpg
- IIS6.0目录解析 xx.asp/1.jpg
- IIS 7.0畸形解析 xxx.jpg/x.asp
Apache
- %0a(CVE-2017-15715)
- 未知后缀 test.php.xxx
Nginx
- 访问连接加/xxx.php test.jpg/xxx.php
- 畸形解析漏洞 test.jpg%00xxx.php
- CVE-2013-4547 test.jpg(非编码空格)\0x.php
Tomcat
- xxx.jsp/
- xxx.jsp%20
- xxx.jsp::$DATA
Upload-Labs练习
pass-01
传一个php文件上去,点上传,弹窗说该文件不允许上传,根据处理的速度推断应该是前端判断文件是否合法,故查看源码,果然有一段javascript:
我们直接在页面元素中将onsubmit事件删除,就可以上传了。
也可以修改文件名称为1.jpg,然后用burp suite抓包修改文件名为1.php,绕过前端检查。
pass-02
上传1.jpg然后burpsuite修改后缀即可。
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = $UPLOAD_ADDR.'文件夹不存在,请手工创建!';
}
}
可以看到,服务端通过检查MIME来确定文件类型
pass-03
上传一个.php文件,提示不允许上传asp,aspx,php,jsp后缀文件,那么我们就从后缀下手
Apache服务器有一个特性,会从右往左开始解析文件后缀,如果最右边的扩展名不可识别,就继续往左判断,直到遇到可以识别的后缀为止,所以这里我们上传 1.php.xxxxx 即可绕过
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if(!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
既然基于黑名单判断,那么我们需要知道Apache可以解析php,phtml后缀的文件,故上传 1.phtml直接绕过
pass-04
- 此处基于依旧可以通过上传 1.php.xxxx 绕过检查
- 上传.htaccess进行覆盖也可以:
上传一个.htaccess文件含有以下内容:
SetHandler application/x-httpd-php
或是
SetHandler application/x-httpd-php
然后随便上传任意后缀的文件,apache均会当作php解析.
源码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '此文件不允许上传!';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
pass-05
- 利用apache解析特性上传1.php.xxxx绕过
- 查看源码发现没有对文件名进行大小写统一,故1.PHP既可绕过验证
pass-06
- 利用apache解析特性上传1.php.xxxx绕过
- 用Burpsuite抓包修改文件名,后缀末尾加空格即可绕过
pass-07
- 直接上传1.php.xxxx
- 在文件后缀名加 . (Windows系统会自动去除文件名末尾的.和空格)
pass-08
看源码发现这里没有对文件名进行去 ::DATA 即可绕过。
pass-09
查看源码的过滤规则,将文件名设置为 '1.php. .' 即可绕过规则检查
pass-10
程序使用str_ireplace函数替换掉了文件名中的敏感字,但该函数只会匹配一次,
故我们双写后缀名来绕过: 1.pphphp
pass-11
查看源码发现使用白名单过滤,但通过url中通过get方式提交了 save_path 参数,并将其拼接到文件名中,
故我们修改 /?sava_path=../upload/1.php%00 使用%00将 $_GET('save_path') 后面的文件名截断。
然后上传1.jpg绕过
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
}
else{
$msg = '上传失败!';
}
}
else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
pass-12
与pass-11无异,只是将提交save_path参数的方法改成了POST,用burpsuite抓包修改即可。
pass-13
查看源码发现通过读取文件前两个字节判断文件类型,所以需要我们制作图片马:
copy normal.jpg/b+shell.php/a webshell.jpg
参数/b指定以二进制格式复制、合并文件; 用于图像类/声音类文件
参数/a指定以ASCII格式复制、合并文件。用于txt等文档类文件
pass-14
程序通过使用 getimagesize() 函数获取图片信息,故仍制作图片马绕过检查
pass-15
程序通过使用 exif_imagetype() 函数获取文件类型,故仍制作图片马绕过检查
pass-16
查看源码看到后端程序对图片进行了imagecreatefromgif()操作,即判断文件是否为合法gif文件,
这里我们上传图片马,然后用burpsuite抓包,在 Content-Type 下两行,即文件内容开头处添加
GIF89a ,即可绕过验证
绕过imagecreatefromgif()函数的方法
https://secgeek.net/bookfresh-vulnerability/
pass-17
竞争条件
pass-18
竞争条件
pass-19
在文件名处使用0x00截断符绕过