【web安全】——文件上传的绕过方式
作者名:白昼安全
主页面链接: 主页传送门
创作初心: 舞台再大,你不上台,永远是观众,没人会关心你努不努力,摔的痛不痛,他们只会看你最后站在什么位置,然后羡慕或鄙夷
座右铭: 不要让时代的悲哀成为你的悲哀
专研方向: web安全,后渗透技术
每日emo: 醒来觉得甚是爱你
一、黑名单绕过
黑名单简单来说就是目标程序规定了哪些文件不能上传
1、大小写绕过
这个没什么好讲的,举个简单的例子,如下
本来需要上传一个名为a.php的木马文件,有时候将文件名改为以下的样子就能绕过一些黑名单限制
a.PHP
a.Php
a.PhP
还有几种组合啊,懒得写了,这种方式还是比较简单的
2、空格绕过
在讲解空格绕过之前要先给大家讲一个系统层面上的特性
在系统层面上,当我保存了一个名为a.txt的文件时,当我在文件名 前面或者后面加上一个空格,在保存时在系统层面上是没有空格的,但是在PHP传输的过程中,是可以识别这个空格的,所以也就诞生我们的空格绕过方式
例: 如果目标的黑名单过滤中只有“.php”,而没有“.php ”这样的后缀时,就可以上传时使用burp抓包,在上传的文件名前面或者后面添加空格,再放包就能成功上传,实现绕过
3、点号绕过
这个点号绕过也是系统层面的原理,很空格过滤没什么区别,当你重命名文件名时,如果在 文件后缀名加上一个点,此时保存后系统会在自动过滤末尾的点号
使用方法同空格过滤一样,例如上传一个a.php文件,burp抓包将文件名改为“a.php.”,此时放包,如果黑名单检测中没有对“php.”过滤,就能实现绕过
4、::$data绕过
条件:只适用于windows
这里能绕过的原理是因为windows的NTFS文件系统的一个特性,windows都适用
也就是当我们访问a.php::$data时,也就是相当于访问a.php本身
当我们访问ab:a.php::$data时,也就是访问ab文件夹下的a.php文件本身
这个绕过方式的使用和前面两个一样,都是burp抓包改文件名就行了,例如把a.php改为a.php::$data,只要他没有做对应的过滤就能绕过黑名单检测
注意:这种方法确实能绕过限制,但是当我们开新标签访问我们上传的文件时会报错,需要把此时url中的::$data删掉才能正常访问
5、单次过滤绕过
先来看看下面这一段过滤代码
$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); //首尾去空
假设我们上传的文件经过这样一次过滤后才能成功上传,初略一看这里的过滤其实还挺多的,但是这里有一个最大的问题——我们上传的文件只经过了一次这样的过滤,例如我们上传a.php,burp抓包后修改为“a.php. .”,此时点击放包,处理流程如下
遇到上面删除文件末尾的点的过滤时, 末尾的点被删除,此时文件名——“a.php. ”
接着往下过滤,遇到首位去空时, 末尾的空格被删除,此时文件名——“a.php.”
接着往下过滤,你会发现它已经过滤完了,它会将此时的结果拿去$deny_ext进行 黑名单检测
但是黑名单中“a.php.”能被检测到吗?不能,所以自然就绕过了过滤
这里的思路就是假如我们已经知道了目标的一个过滤规则,那我们就可以尝试 使用两次对应的过滤来绕过,假如它所有的过滤都只进行一次,那就可以宣布拿下了
6、后缀双写绕过
双写后缀的方式只适合 目标服务器的过滤规则是检测到黑名单后缀时,将文件名中对应后缀删除的情况
例如服务器检测的黑名单如下
$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");
此时我们上传一个a.php文件,服务器会那黑名单中的内容来匹配,匹配到php后,就会把原来的文件名“ a.php”后面的php后缀删掉,此时的文件名——“ a.”,此时这个文件倒是能成功上传,但是已经不会被解析为php了,,这就是整个过滤流程
而我们对应的绕过方式就是——双写后缀绕过
条件还是这个服务器只进行了一次过滤,例如我们上传a.php,burp抓包,将文件名改为“a.pphphp”
进入文件上传流程,识别文件后缀,为“pphphp”。
从左到右识别,当识别当第二位到第四位的php时,即“p phphp”,判定后缀名存在黑名单,将识别到的php删除,后缀中剩下的字符组合后,此时后缀“pphphp”就成了“php”,此时剩下的文件名——“a.php”,程序以为处理完了,没有危害,所以文件成功上传,不进行拦截,即成功绕过
a.php文件,自然我们访问时也能以正常php去解析
二、白名单绕过
白名单简单来说就是目标程序规定了能上传的后缀名
1、mine类型检测绕过
MIME多用途网络邮件扩展类型,可被称为Media type或Content type,它设定某种类型的文件当被浏览器打开的时候需要用什么样的应用程序,多用于HTTP通信和设定文档类型例如HTML。之所以叫多用途网络邮件扩展类型,因为它最早被用于电子邮件系统,后用于浏览器。
常见的类型有:
那么在我们抓包的时候,content-type里面的值,就是文件的mime类型,如果后台是根据这个来判断文件类型的,那么就存在mime类型的检测绕过。
即上传时抓包,将mine类型改为它没允许上传的类型即可绕过验证
实操这里就不讲了,太简单了有点
2、00截断绕过
条件:
php版本< 5.3
php.ini这个配置文件中 magic_quotes_gpc必须为 off
上传路径可控
必须满足这两个条件才能使用00截断
原理:
0x00是字符串的结束标识符,攻击者可以利用手动添加标识符的方式来将后面的内容弄进行截断,这样标识符后面的内容就能帮我们绕过检测
实例:
例如一个程序在代码中规定只允许上传png,jpg,gif后缀的文件,而我们需要上传一个名为aa.php的一句话木马文件,可以使用如下方法
1、选中aa.php文件并上传,在上传时使用burp抓包,如下
2、修改文件保存路径和文件名
最初的保存路径是 ../upload/,文件名是 aa.php,所以经过拼接后 aa.php上传后的相对路径位置是 ../upload/aa.php
此时我们将文件报错路径修改为“../upload/test.php%00”
文件名修改为“aa.jpg”,如下
此时我们上传的文件最后的路径就会拼接成为——“../upload/test.php%00aa.jpg”,因为过滤规则只对文件名生效,也就是filename参数对应的“aa.jpg”,目标允许jpg文件上传,所以绕过过滤自然是没有问题的
很多人会问,那我们上传的aa.php中的一句话木马内容在哪去了?自然也就是在test.php里面去了。因为%00后面的语句不会被识别,所以能成功上传,内容也成功解析为php
此时访问test.php就能成功访问我们上传的php文件内容
三、特殊的情况
1、纯前端限制绕过
条件:过滤仅在前端进行
前端就是经过javascript来进行验证,不和服务器进行交互,单纯以js代码来进行过滤,此时可以通过以下方法绕过
1、禁用js
2、f12删除代码中的限制性js语句
以upload——labs第一关为例,如下
查看源代码,发现当我们点击上传按钮时触发onsubmit事件,会开始执行js代码,js代码就是实现过滤的代码
我们直接把onsubmit的内容删掉,那么点击上传后就不会去执行过滤的js代码,但是新的浏览器并不会识别,只适合一些老版本的浏览器
当然,禁用js也是同样的道理
2、相似拓展名绕过
条件:中间件使用的是apache
当php的后缀被限制不允许上传时,而网站的中间件使用的又是apache时,就可以考虑下面的方式
phtml,php3,php4,php5这些特殊后缀,在 apache配置文件中可以被当php解析
条件:httpd.conf配置文件中的AddType application/x-httpd-php配置需要开启,并且将特殊后缀写入配置中才行,如下
例:AddType application/x-httpd-php .php .phtml .php3
此时php3文件和phtml文件就能被apache解析为php文件,如果对方只是不允许php文件上传,那此时就可以使用这些特殊后缀
3、htaccess配置文件绕过
条件:中间件使用的是apache
htaccess文件(或者“分布式配置文件”),.htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。
.htaccess主要的作用有:URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等。
所以上传.htaccess文件,可以 重写文件解析规则绕过
意思就是例如他最初的 配置文件httpd.conf中有个对文件上传的过滤规则,此时你给目标目录下上传一个 .htaccess文件,里面有你重新写的解析规则,此时生效的最后的过滤(解析)规则就是你上传的 .htaccess文件中的,而不是原来的 http.conf中的规则
我们创建一个.htaccess文件格式如下,例
AddType application/x-httpd-php .jpg
例如最开始该apache的httpd.conf配置文件中解析配置如下
AddType application/x-httpd-php .php
即只有php文件会被当做php代码执行,但若此时php文件被拦截,我们可以尝试把php一句话木马放进jpg文件源码中,再将上面准备好的.htaccess文件上传到目标服务器,此时的解析规则就变成了jpg文件的源码会被解析为php代码,这样我们就只需要上传jpg文件,而不是被过滤的php文件,达到变相绕过的目的