大家好!
我是小黄,很高兴又跟大家见面啦 !
拒绝水文,从我做起 !!!!
未经允许,禁止转载 ,违者必究!!!!
本实验仅适用于学习和测试 ,严禁违法操作 ! ! !
今天更新的是:
- 文件上传后端黑名单白名单绕过
- 微信公众号回复:【
靶机
】,即可获取本文全部涉及到的工具。
创建时间:2021年6月23日
软件: MindMaster Pro、kali、DriftingBlues:7靶机
文件上传后端黑名单白名单绕过
一、文件上传常见验证:
客户端验证:客户端校验
- 一般都是在网页上写一段 JavaScript 脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,
- 内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。
- https://www.yuque.com/u21092836/im1n32/gmptgs
服务端验证:
- 直接验证方法:直接查看文件名后缀。
- 间接验证方法:通过文件头和类型来进行识别。
后缀名:黑名单、白名单
- **黑名单:**明确不允许上传的文件格式后缀
- 常见脚本格式:ASP、PHP、JSP、ASPX、cgi、war …
- 可能绕过方式(与网站搭建平台和设置格式有关):php5 、phtml …
对于黑名单的检测方式,我们有如下几种办法绕过:
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', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if (!in_array($file_ext, $deny_ext)) {
$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 = '此文件不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
- .htaccess 代码 ,保存到文件,文件类型 .htaccess
- 参考链接
<FilesMatch "shana">
SetHandler application/x-httpd-php
</FilesMatch>
// FilesMatch 文件匹配 ,如果匹配到文件中存在 "shana" 就会将文件以解析 application/x-httpd-php 类型进行解析。
- 首先将这个文件( .htaccess),进行上传,上传之后,再次解析文件的话就会以这个(刚才上传的配置文件为主)
- 然后将文件名中含有 “shana” 字段的图片进行上传,就会将文件以 php 代码进行解析了。(也可以在最后添加 phpinfo 进行回显)
- 就可以进行访问了。
补充:.user.ini 文件
- 自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。
- 此类文件仅被 CGI/FastCGI SAPI 处理。
- 此功能使得 PECL 的 htscanner 扩展作废。
- 如果使用 Apache,则用 .htaccess 文件有同样效果。
- 除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。
- 如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
- 在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
- 两个新的 INI 指令,user_ini.filename 和 user_ini.cache_ttl 控制着用户 INI 文件的使用。
- user_ini.filename 设定了 PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。默认值是 .user.ini。
- user_ini.cache_ttl 控制着重新读取用户 INI 文件的间隔时间。默认是 300 秒(5 分钟)。
- 但是想要引发 .user.ini 解析漏洞需要三个前提条件:
- 服务器脚本语言为PHP
- 服务器使用CGI/FastCGI模式
- 上传目录下要有可执行的php文件
- 先来创建一个 .user.ini 文件并写入一下内容:auto_prepend_file=x.png
- 上传 .user.ini 后,再上传一个 x.png 文件,此时 x.png 文件只要有符合 php 语言的代码就会执行。
第五关:大小写绕过(太简单了):
<?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",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess");
$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)) {
$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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
第六关:空格绕过
- 检查源代码,发现首尾去空,通过抓取上传数据包,在上传的文件后面加空格就可以实现绕过了。
- 原理:借助了系统的特性。
- Windows 会强制将后面的空格平掉。但是在数据包上空格是不会去掉的。这样就可以跳过黑名单绕过。
- 上传到系统之后,系统又会强制给平掉,来实现绕过。
- 所以在网站没有收尾去空的话 而且又是windows系统 就可以采用’1.php '这种方式来绕过 或者多加一些空格 1.php.这样也是一样的原理。
- 上传1.php(或者图片马),抓包改为1.php:1.jpg 也是一样的原理。
<?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",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
第七关:点绕过
<?php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess",".ini");
$file_name = $_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
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 = '此文件不允许上传';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
第八关:::$DATA绕过
第九题:点+空格+点绕过
- 与上面题相比呢这个道题去掉了: f i l e e x t = s t r i r e p l a c e ( ′ : : file_ext = str_ireplace(':: fileext=strireplace(′::DATA’, ‘’, f i l e e x t ) ; / / 去 除 字 符 串 : : file_ext);//去除字符串:: fileext);//去除字符串::DATA 这行代码。
- ::
D
A
T
A
是
什
么
意
思
呢
?
必
须
是
w
i
n
d
o
w
s
,
必
须
是
p
h
p
,
必
须
是
那
个
源
文
件
,
p
h
p
在
w
i
n
d
o
w
的
时
候
如
果
文
件
名
+
"
:
:
DATA 是什么意思呢?必须是windows, 必须是php, 必须是那个源文件,php在window的时候如果文件名+"::
DATA是什么意思呢?必须是windows,必须是php,必须是那个源文件,php在window的时候如果文件名+"::DATA"会把::
D
A
T
A
之
后
的
数
据
当
成
文
件
流
处
理
,
不
会
检
测
后
缀
名
.
且
持
"
:
:
DATA之后的数据当成文件流处理,不会检测后缀名.且持"::
DATA之后的数据当成文件流处理,不会检测后缀名.且持"::DATA"之前的文件名
他的目的就是不检查后缀名
<?php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess",".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 = 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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
第十关:双写绕过
<?php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess",".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', '', $file_ext);//去除字符串::$DATA
// 这里也是去除了一次
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
$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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
- 假设: 将代码中的字符串里面PHP替换为空, a.php —> a.
- 如果是一次过滤:a.pphphp ----> a.php
- 如果是循环过滤(也就是递归过滤,更加安全)a.pphphp ----> a.
- 那么我们就可以上传数据包中修改数据来通过:xxxxx.php. . 来进行绕过。
第11关:00截断
<?php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
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","ini");
$file_name = trim($_FILES['upload_file']['name']);
// 匹配格式,将$deny_ext与$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 . '文件夹不存在,请手工创建!';
}
}
?>
- 匹配格式,将 d e n y e x t 与 deny_ext与 denyext与file_name上传的文件格式进行匹配,如果有就将文件替换为空,文件上传之后就没有后缀了,还是一次代码,通过抓包来进行绕过
- 那么我们就可以上传数据包中修改数据来通过:xxxxx.pphphp 来进行绕过。
第12关:白名单绕过,%00截断
- 只允许上传指定文件类型。
<?php
$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);
// 将文件传输到这个函数 $file_ext 与 $ext_arr 进行判断寻找,如果匹配则进行正常的文件上传。
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类型文件!";
}
}
?>
- %00截断 与 0x00截断的区别?
- 地址上面文件命名的区别。
- %00上是建立在地址信息上的
- 0x00 文件
- 操作方法基本一致。
- %00截断 与 0x00截断的实战中的区别?
- 平时一定要多观察一下数据包,数据包中包含了很多参数,很多参数可以进行修改。
<?php
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
? save_path = ../upload/1.php%00
==> ? save_path = ../upload/1.php%00/(%00相当于是截断)/1313131.jpg 后面这些东西相当于没有了 1313131.jpg
==> $img_path = $_GET['../upload/1.php%00 ']
==> 最终结果:../upload/1.php
==> php版本:5.3版本以下
?>
第13关:图片马
<?php
$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 = $_POST['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类型文件!";
}
}
?>
各位路过的朋友,如果觉得可以学到些什么的话,点个赞 再走吧,欢迎各位路过的大佬评论,指正错误,也欢迎有问题的小伙伴评论留言,私信。
每个小伙伴的关注都是本人更新博客的动力!!!
请微信搜索【 在下小黄 】文章更新将在第一时间阅读 !
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!