文件上传后端黑名单白名单绕过
Posted 在下小黄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传后端黑名单白名单绕过相关的知识,希望对你有一定的参考价值。
大家好!
我是小黄,很高兴又跟大家见面啦 !
拒绝水文,从我做起 !!!!
未经允许,禁止转载 ,违者必究!!!!
本实验仅适用于学习和测试 ,严禁违法操作 ! ! !
今天更新的是:
- 文件上传后端黑名单白名单绕过
- 微信公众号回复:【
靶机
】,即可获取本文全部涉及到的工具。
创建时间:2021年6月23日
软件: MindMaster Pro、kali、DriftingBlues:7靶机
文件上传后端黑名单白名单绕过
一、文件上传常见验证:
客户端验证:客户端校验
- 一般都是在网页上写一段 javascript 脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,
- 内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。
- https://www.yuque.com/u21092836/im1n32/gmptgs
服务端验证:
- 直接验证方法:直接查看文件名后缀。
- 间接验证方法:通过文件头和类型来进行识别。
后缀名:黑名单、白名单
对于黑名单的检测方式,我们有如下几种办法绕过:
1. 后缀名大小写混用(只能在Linux系统环境下进行解析)
假如.php后缀,我们可以写成.PHp之类的形式,用于一些过滤不严谨的系统。
2. 特殊后缀绕过(利用难度较高)
将Burpsuite截获的数据包中xxxx.php名字改为xxxx.php4(php1,php2,php3,php4,php5),
前提条件是http.conf中设置 AddType application/x-httpd-php .php1(php的版本小于等于5.3.29以下)
3. 配合操作系统文件命名规则绕过:
在windows系统下,如果文件名以“.”或者空格作为结尾,系统会自动删除“.”与空格,利用此特性也可以绕过黑名单验证。
apache中可以利用点结尾和空格绕过,asp和aspx中可以用空格绕过。
4. 双写后缀
在一些系统中,仅仅匹配非法后缀删除,这个时候我们构造.pphphp,当它将第一个php匹配删除之后,剩下的字符又重新组合成了.php。
能被WEB容器解析的文件其他扩展名列表:
jsp, jspx ,jspf
asp asa cer cdx,htr,xml,html
aspx,ashx,asmx,asax,ascx
- **白名单:**明确可以上传的文件格式:
- JPG、PNG、zip、rar、gif …
- 相对于黑名单要安全一些。
白名单绕过方法:
一、%00 截断上传绕过:
通过抓包截断将XXXX.asp.jpg后面的一个.换成%00在上传的时候即XXXX.asp%00.jpg,
当文件系统读到%00时,会认为文件已经结束,从而将XXXX.asp.jpg的内容写入到XXXX.asp中,从而达到攻击的目的。
%00不是针对所有基于白名单的后缀名检查都能绕过,代码的实现过程中必须存在截断上传漏洞,上传格式如下:
XXXX.asp %00.jpg
路径/updata/XXXX.asp(0x00).jpg
二、 突破文件路径绕过:(待验证 !!!)
在文件上传时,程序通常允许用户将文件放到指定的目录中,如果指定的目录存在,就将文件写入目录中,不存在的话则先建立目录,然后写入。
比如:在前端的HTML代码中,有一个隐藏标签<input type="hidden" name="Extension" value="up"/> 在服务器端有如下代码 if(!is_dir($Extension)) //如果文件夹不存在,就建立文件夹
mkdir($Extension);
攻击者可以利用工具将表单中value的值由“up”改为“pentest.asp”,并上传一句话图片木马文件。
程序在接收到文件后,对目录判断,如果服务器不存在pentest.asp目录,将会建立此目录,然后再将图片一句话密码文件写入pentest.asp目录,如果Web容器为IIS 6.0,那么网页木马会被解析。
二、.htaccess 文件重写绕过:
配合黑名单列表绕过,上传一个自定义的.htaccess和一句话图片木马,就可以轻松绕过各种检测,该文件仅在Apache平台上存在,.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。
.htaccess 文件的写法:
<FilesMatch "backlion.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
保存为.htaccess文件。该文件的意思是,只要遇到文件名中包含有” backlion.jpg”字符串的任意文件,统一被当作php执行。如果这个” backlion.jpg”的内容是一句话木马,即可利用中国菜刀进行连接
前提条件是:大于等于php版本5.3.39以下
三、配合web容器的解析漏洞:
IIS中的目录解析漏洞和分号解析漏洞: 将一句话木马的文件名backlion.php,改成backlion.php.abc(奇怪的不被解析的后缀名都 行)。
首先,服务器验证文件扩展名的时候,验证的是.abc,只要该扩展名符合服务器端黑白名单规则,即可上传。
nginx空字节漏洞 xxx.jpg%00.php 这样的文件名会被解析为php代码运行
apache的解析漏洞,上传如a.php.rar a.php.gif 类型的文件名,可以避免对于php文件的过滤机制,但是由于apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar等扩展名是apache不能识别的,因此就会直接将类型识别为php,从而达到了注入php代码的目的
目录位置修改绕过的几种形式:
第一种:
upload/1.asp%00.jpg #asp中的修改目录位置%00的拦截
bk.jpg #post提交一句话图片马或者其他白名单为一句话木马
------->upload/1.asp%00.jpg/bk.jpg #最终生成的文件访问路径
第二种:
upload/bk.asp; # windows2003 iis6.0中目录路径后添加一个bk.asp;的目录
bk.jpg #post上传的文件类型将bk.jpg一句话图片马
----->upload/bk.asp;14127900008.asp ##最终的URL访问路径
这里以动网6.0为例,先上传一个正常的图片,会生成如:files/201210010321944973.jpg文件。
第一种突破方法:先上传一句话图片马如1.jpg,然后拦截将其 FilePath 值改为“files/backlion.asp□
最终生成:“files/backlion.asp□/201210010321944973.jpg,实际就是files/backlion.asp
第二种突破:先上传一句话图片马如1.jpg,然后拦截将其 FilePath 值改为“backlion.asp;最终生成:“backlion.asp;201210010321944973.jpg
文件类型:MIME信息
-
使客户端软件,区分不同种类的数据,例如web浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件。web服务器使用MIME来说明发送数据的种类, web客户端使用MIME来说明希望接收到的数据种类,它是服务器用来判断浏览器传递文件格式的重要标记项。
-
上传文件的时候呢,会自带一个文件上传格式信息。
-
可以通过抓包来进行修改上传。
-
此类后端检查时,检查的是Content-Type,也叫Mime-Type,这个时候,我们上传一个PHP文件,通过BurpSuite抓包,将.php后缀的Content-Type: application/octet-stream更改为.jpg的Content-Type: image/jpeg。
-
然后发包,就可以绕过后端基于Content-Type的检测。
-
将“Content-Type”的参数类型更改为“image/ *”即可,例如“image/png”, “image/jpeg”, “image/gif”
-
需要配合文件包含漏洞绕过。
常见文件类型:
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf Microsoft
Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
text/plain(纯文本)
text/html(HTML文档)
text/javascript(js代码)
application/xhtml+xml(XHTML文档)
image/gif(GIF图像)
image/jpeg(JPEG图像)
image/png(PNG图像)
video/mpeg(MPEG动画)
application/octet-stream(二进制数据)
application/pdf(PDF文档)
application/(编程语言) 该种语言的代码
application/msword(Microsoft Word文件)
message/rfc822(RFC 822形式)
multipart/alternative(HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示)
application/x-www-form-urlencoded(POST方法提交的表单)
multipart/form-data(POST提交时伴随文件上传的表单)
绕过方式:
一、运行上传文件包含脚本木马和一句话木马内容:(这里讲解一下一句话木马)
前提:校验规则只校验当文件后缀名为asp/php/jsp的文件内容是否为木马。
1. 先上传一个内容为木马的txt后缀文件,因为后缀名的关系没有检验内容;
2. 然后再上传一个.php的文件,内容为<?php Include(“上传的txt文件路径”);?>
此时,这个php文件就会去引用txt文件的内容,从而绕过校验,下面列举包含的语法:
PHP
<?php Include("上传的txt文件路径");?>
ASP
<!--#include file="上传的txt文件路径" -->
JSP
<jsp:inclde page="上传的txt文件路径"/>
or
<%@include file="上传的txt文件路径"%>
二、存在本地文件包含漏洞,并可上传一句话内容马:(网上搜集的待验证!!!)
1. 上传一个符合条件格式的文档,文档内容为一句话木马,
eg:test.txt
2. 利用文件包含漏洞包含上传的木马文件,
eg:page?id=D:/www/test.txt
三、修改URL的参数绕过:(需要进行验证!!!)
谷歌关键字:inurl:newslist.asp?NodeCode=
将/uploadfile.asp?uppath=PicPath&upname=&uptext=form1.PicPath中的参数uptext的值改为form1.PicPath.asp即可绕过。
可以看出对参数 PicPath 进行了修改,这种漏洞主要是存在文件名或者路径过滤不严,在实战中多多观察 url 中的参数,可以尝试进行修改数据。
四、双重文件上传绕过:(需要进行验证!!!)
通过保存以下代码为1.html修改上传:
<form action="http://edu2b.sinaapp.com/Upfile_AdPic.asp" method="post"
name="form1" enctype="multipart/form‐data">
<input name="FileName1" type="FILE" class="tx1" size="40">
<input name="FileName2" type="FILE" class="tx1" size="40">
<input type="submit" name="Submit" value="上传">
</form>
//在第一个框内选择一个 jpg 图片,文件名为“yueyan.jpg”,在第
二个框内选择一个 cer 文件,文件名为“yueyan.cer”,点“上传”把这两个文件提交给程序即可。
文件头:内容头信息
-
图片格式往往不是根据文件后缀名去做判断的。文件头是文件开头的一段二进制,不同的图片类型,文件头是不同的。文件头又称文件幻数。
-
不同类型的文件,文件头信息不相同。
-
可以通过抓包来进行修改上传。
-
这个时候他会检测文件的16进制数据头是否是合法文件的数据头,这个时候我们找一个普通的图片文件,再写一个一句话木马文件:
-
隐写术可以看这篇文章图片隐写术总结
-
然后通过前面隐写术的方法,进入两个文件的路径,在cmd中输入:copy/b 1.jpg+1.php 2.jpg就可以制作图片马,但是需要配合解析漏洞 或者在线工具 在线图片添加/解密隐藏信息(隐写术)工具
-
常见文件幻数
-
PNG: 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A
-
JPEG: 文件头标识 (2 bytes): 0xff, 0xd8 (SOI) (JPEG 文件标识)
-
GIF: 文件头标识 (6 bytes) 47 49 46 38 39(37) 61
格式 | 文件头 |
---|---|
TIFF (tif) | 49492A00 |
Windows Bitmap (bmp) | 424D |
CAD (dwg) | 41433130 |
Adobe Photoshop (psd) | 38425053 |
Rich Text Format (rtf) | 7B5C727466 |
MS Word/Excel (xls.or.doc) | D0CF11E0 |
MS Access (mdb) | 5374616E64617264204A |
ZIP Archive (zip), | 504B0304 |
RAR Archive (rar), | 52617221 |
Wave (wav), | 57415645 |
AVI (avi), | 41564920 |
Real Media (rm), | 2E524D46 |
MPEG (mpg), | 000001BA |
MPEG (mpg), | 000001B3 |
Quicktime (mov), | 6D6F6F76 |
Adobe Acrobat (pdf), | 255044462D312E |
Windows Media (asf), | 3026B2758E66CF11 |
MIDI (mid), | 4D546864 |
二、简要上传表单代码分析解释:
upload 靶场第二题源码分析
<form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
<p>请选择要上传的图片:<p>
<input class="input_file" type="file" name="upload_file"/>
<input class="button" type="submit" name="submit" value="上传"/>
</form>
- 这是一个HTML代码。
- enctype 是提交类型。
- method 是请求方法。
- onesubmit 是鼠标触发时间,当你点击之后会返回后面的那个函数。
- name 第一个是name 是参数名字、第二个是鼠标触发名字。
<? php?
$name = $_FILES['upload_file']['name'];
echo $name;
>
// HTML
<form enctype="multipart/form-data" method="post" action="">
<p>请选择要上传的图片:<p>
<input class="input_file" type="file" name="upload_file"/>
<input class="button" type="submit" name="submit" value="上传"/>
</form>
- $_FILES : 这是PHP里面的一个全局变量,专门是接收文件上传的操作数据。
- $_FILES 详解。
- HTML 中表单中接收到的数据就会以 name 值发送到 $_FILES[‘upload_file’] 变量中。[‘name’] 代表接收到的文件名。
- echo $name :输出这个文件名。
- action="" :表示提交会给当前这个文件。
<? php?
//输出文件名称
echo $_FILES['upload_file']['name'];
//输出文件类型
echo $_FILES['upload_file']['type'];
//输出文件大小(字节)
echo $_FILES['upload_file']['size'];
>
三、演示案例:
第一关:客户端验证
- 禁用JS脚本
第二关MIME白名单绕过 :
- 只验证文件类型,我们只要修改上传文件格式的值也就是MIME值(Content - Type 的值),就可以轻松实现文件绕过。
<?php
include '../config.php';
include '../head.php';
include '../menu.php';
$is_upload = false;
$msg = null;
// 当点击鼠标上传的时候,进行验证
if (isset($_POST['submit']))
// UPLOAD_PATH 声明在配置文件上的文件上传路径,来判断路径是否存在。
if (file_exists(UPLOAD_PATH))
// 进行上传文件类型判断, || 或的意思
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];
// move_uploaded_file 移动文件函数,将前者移动到后者哪里
if (move_uploaded_file($temp_file, $img_path))
$is_upload = true;
else
$msg = '上传出错!';
else
$msg = '文件类型不正确,请重新上传!';
else
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
?>
<?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
define("WWW_ROOT",$_SERVER['DOCUMENT_ROOT']);
define("APP_ROOT",str_replace('\\\\','/',dirname(__FILE__)));
define("APP_URL_ROOT",str_replace(WWW_ROOT,"",APP_ROOT));
//文件包含漏洞页面
define("INC_VUL_PATH",APP_URL_ROOT . "/include.php");
//设置上传目录
define("UPLOAD_PATH", "../upload");
?>
第三关黑名单特殊解析后缀 :
- 黑名单验证,只要避免啊上传这种后缀就可以正常的进行文件上传。
<?php
include '../config.php';
include '../common.php';
include '../head.php';
include '../menu.php';
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
if (file_exists(UPLOAD_PATH))
// 声明了变量 deny_ext(拒绝_后缀名)
$deny_ext = array('.asp','.aspx','.php','.jsp');
// trim 过滤为空的函数,替换空格。自动去除空格
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点,xiasohuang.jpg.php 防止上传验证为jpg格式实际上是php代码。
// strrchr 分隔字符,就是删除掉.前面的文件名称,这样就得到了文件的真实后缀了。
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA,将目标中的::$DATA替换为空。
$file_ext = trim($file_ext); //收尾去空
// 判断接收到的文件中,有没有黑名单里面的后缀,就继续进行文件上传,如果存在就不允许上传这个格式。
if(!in_array($file_ext, $deny_ext))
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path))
$is_upload = true;
else
$msg = '上传出错!';
else
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
else
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
?>
第四关.htaccess绕过:
- 上面已经写了这是解析漏洞 只有apache才有。
- .htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。
- 提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
- 这个漏洞的原理就是服务器没有过滤htaccess文件的上传,而htaccess文件上传后,当前目录就会按照这个配置文件里面的内容执行。
<FilesMatch "自定义">
Sethandler application/x-httpd-php
</Eilesmatch >
- 然后上传“自定义.可以上传的后缀” 都会按照“自定义.php”来执行
- 前提:只试用于Apache 平台的伪静态转换,是Apache文件一个配置文件。
<?php
include '../config.php';
include '../common.php';
include '../head.php';
include '../menu.php';
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
if (file_exists(UPLOAD_PATH))
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".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",".ini");
$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', 一道面试题引发的思考第一篇-文件上传白名单绕过