杜彬,Time,文件上传漏洞
原理:
原理与过程
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。客户端 选择发送的文件→服务器接收→网站程序判断→临时文件→移动到指定的路径
能够webshell的文件类型 PHP、JSP、ASP、ASP.NET
黑名单
1,前端限制
```plain function checkFile() { var file = document.getElementsByName('upload_file')[0].value; if (file == null || file == "") { alert("请选择要上传的文件!"); return false; } //定义允许上传的文件类型 var allow_ext = ".jpg|.png|.gif"; //提取上传文件的类型 var ext_name = file.substring(file.lastIndexOf("."));//通过lastIndexOf方法找到文件名中最后一个点(.)的位置,然后使用substring方法从该位置截取到字符串末尾,得到文件的扩展名。 //判断上传文件类型是否允许上传 if (allow_ext.indexOf(ext_name + "|") == -1) //检查allow_ext字符串中是否包含当前文件的扩展名加一个竖线|。如果indexOf方法返回-1,说明文件扩展名不在允许的扩展名列表中。 { var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name; alert(errMsg); return false; } } ```绕过方法:禁用js和抓包修改。
2,绕过contnet-type检测上传
有些上传模块,会对contnet-type进行检测,如果是图片类型,允许上传文件到服务器,否则返回上传失败。因为服务端是通过content-type判断类型,content-type在客户端可被修改。则此文件上传也有可能被绕过的风险。检测文件类型是否是image/jpeg或者是image/png,如果是就允许上传。
- text/html : HTML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
3,大小写绕过
有的上传模块 后缀名采用黑名单判断,但是没有对后缀名的大小写进行严格判断,导致可以更改后缀大小写可以被绕过。如PHP、 Php、 phP、pHp4,特殊可解析后缀绕过
Apache的httpd.comf配置文件中有AddType application/x-httpd-php .php .phtml .php3 后缀名为 phtml 、php3 均被解析成php 有的apache版本默认就会开启。
5,windows 系统特征绕过攻击
点绕过在windows 中文件后缀名. 系统会自动忽略.所以shell.php. 和shell.php的效果一样。所以可以在文件名后面加上.绕过。
空格绕过
检测submit后 上传目录存在时,进入黑名单判断。如果文件后缀名在黑名单里。不允许上传,但是文件后缀名,没有过滤空格,可以添加空格绕过。
::$DATA
在Windows系统中,如果文件名后加上 :: D A T A ,系统会将 : : DATA,系统会将:: DATA,系统会将::DATA 之后的数据当成文件流处理,不会检测后缀名,且保持::DATA 之前的文件名。这意味着,例如 1.php:: D A T A , W i n d o w s 会自动去掉末尾的 : : DATA,Windows会自动去掉末尾的:: DATA,Windows会自动去掉末尾的::DATA,变成1.php
6,双写绕过
在上传模块,有的代码会把黑名单的后缀名替换成空,例如a.php 会把php替换成空,但是可以使用双写绕过例如,pphphp,即可绕过上传。str_ireplace对上传的后缀名是黑名单内的字符串转换成空。
7,. htaccess 重写解析绕过上传
.htaccess文件,提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。管理员可以通过Apache的AllowOverride指令来设置。 这个漏洞的原理就是服务器没有过滤htaccess文件的上传,而htaccess文件上传后,当前目录就会按照这个配置文件里面的内容执行。要htaccess的规则生效 则需要在apache开启rewrite重写模块,因为apache多数都开启这个模块,所以规则一般都生效。
AddType application/x-httpd-php .jpg
任何以.jpg结尾的文件都会被Apache视为PHP脚本
再上传恶意的jpg到.htaccess相同目录里,访问图片即可获取执行脚本。
8,.user.ini
应用场景- 服务器脚本语言为PHP,并且使用CGI/FastCGI模式,php版本>5.3.0
- 上传目录下要有可执行的php文件
.user.ini,它会影响php.ini中的配置,从而将指定的文件内容按php来解析,影响的范围该文件所在的目录以及子目录。需要等待php.ini中的user_ini.ache_ttl设置的时间或重启Apache才能生效,且只在php5.3.0之后的版本才生效。.user.ini比.htaccess用的更广,不管是nginx/Apache/IIS,只要是以fastCGI运行的php都可以用这个办法。如果使用Apache,则用.htaccess文件有同样的效果。
注意 .htaccess只能用于Apache。
auto_prepend_file = <filename> //包含在文件头
auto_append_file = <filename> //包含在文件尾
9,文件头检测
有的文件上传,上传时候会检测头文件,不同的文件,头文件也不尽相同。GIF89a图片头文件欺骗
GIF89a图形文件是一个根据图形交换格式(GIF)89a版进行格式化之后的图形
JPEG (jpg),文件头:FFD8FF PNG (png),文件头:89504E47 GIF (gif),文件头:47494638
白名单
00截断的核心:当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃。
例如1.php%00.1.jpg 变成 1.php(GET参数直接是%00即可,但POST需要把%00 解码一下)
- php版本要小于5.3.4; 5.3.4及以上已经修复该问题
- magic_quotes_gpc需要为OFF状态,否则会把%00转换成其他的字符
文件上传绕过之00截断
【%00和0x00】区别:
它们最终的结果都是一样的,都代表着chr(0),即空字符,只不过使用的位置不同,0x00代表16进制的空字符00,需要在HEX中改为00,进行截断,而%00是URL解码之前的字符,它被解码成16进制ASCII码之后实际上也是0x00,所以它们最终都对应的是空字符.
0x00截断
0x00是十六进制表示方法,表示ASCII码为0的字符,在一些函数处理时,会把这个字符当作结束符。
0x00可以用在对文件名的绕过上,具体原理:系统在对文件名进行读取时,如果遇到0x00,就会认为读取已经结束。但要注意是文件的十六进制内容里的00,而不是文件名中的00。也就是说系统是按二进制或十六进制读取文件,遇到ASCII码为0的位置就停止,而这个ASCII码为0的位置在十六进制中是00。
总之就是利用ASCII码为0这个特殊字符,让系统认为字符串已经结束。
文件包含
其实原理就是由于在代码开发的过程中,有时候会遇到相同的代码,不想重复输入,就将代码单独写在一个文件里面,当遇到的时候就直接调用该文件进行运行,而这种方式可能会导致客户端可以调用其他的恶意文件,通过恶意文件造成文件包含漏洞。但是前提也是当文件包含的代码文件被当作一个变量来使用,并且能够被用户传入参数,如果没有对该变量做相应的安全防护,就可能会引发出文件包含漏洞。
上传一个包含一句话木马的正常图片
通过包含就可以执行里面的一句话木马
条件竞争与二次渲染
条件竞争
简单来说就是上传文件后立即保存到服务器。
上传成功后进行文件格式的校验。
如果文件格式符合要求,则重命名该文件。
如果文件格式不符合要求,则删除该文件。
由于服务器在处理多个并发请求时,可能会出现以下几种情况:
访问时间点在文件上传之前:此时,文件尚未上传到服务器,任何对该文件的访问请求将返回“文件不存在”。访问时间点在文件上传成功后,但服务器尚未完成校验及处理:在此时间窗口内,文件已经存在于服务器上,但尚未经过格式校验。任何对该文件的访问请求将会找到文件,但由于文件格式尚未验证,可能存在安全隐患。访问时间点在服务器删除文件之后:如果文件格式不符合要求,服务器会删除该文件。此时,任何对该文件的访问请求将返回“文件不存在”。
<?php file_put_contents('1.php', '<?php @eval($_POST[1]); ?>'); ?>#生成1.php,写入后边的一句话木马
import requests
url = "http://62.234.14.144:8082/upload/1.php"
while True:html = requests.get(url)if html.status_code == 200:print("OK")break
条件竞争需要访问文件,文件进行执行才能生成文件。
二次渲染
在我们上传文件后,网站会对图片进行二次处理,服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。绕过:
1、配合文件包含漏洞:将一句话木马插入到网站二次处理后的图片中,也就是把一句话插入图片在二次渲染后会保留的那部分数据里,确保不会在二次处理时删除掉。这样二次渲染后的图片中就存在了一句话,在配合文件包含漏洞获取webshell。2、可以配合条件竞争:这里二次渲染的逻辑存在漏洞,先将文件上传,之后再判断,符合就保存,不符合删除,可利用条件竞争来进行爆破上传
gif二次渲染
gif图片在二次渲染后,与原图片差别不会太大。所以二次渲染攻击最好用git图片马。
上传正常的gif图片下载回显的图片
用 010Editor 编辑器进行对比两个GIF图片内容,找到 相同 的地方,上传前和上传后,两张图片的部分 Hex 仍然保持不变的位置,并插入PHP一句话,上传带有 PHP一句话木马 的GIF图片
进行包含
png二次渲染
先了解一下文件格式标准的 PNG 文件由以下关键块组成:
IHDR(Image Header):图像头部块,定义图像的基本属性(如宽度、高度、颜色深度等)。
IDAT(Image Data):图像数据块,包含实际的图像像素信息。
IEND(Image End):图像结束块,表示图像文件的结束。
其他可选的块,如 tEXt(用于存储文本注释),pHYs(存储图像物理维度),以及 PLTE(调色板)等。
在正常情况下,PNG 文件必须符合一定的标准和格式要求,否则大多数 PNG 解析器会拒绝加载或渲染该文件。也就是说,我们想要手工插入恶意代码且不损坏图像文件,几乎不可能
漏洞产生原因:
不同解析器的兼容性差异:不同的软件、浏览器或操作系统中的 PNG 解析库对图像的解析方式有所不同。例如,某些解析器可能对格式不规范的 PNG 文件宽容处理,而其他解析器则会严格遵循规范。当同一个 PNG 文件被不同软件解析时,可能会出现不同的渲染结果。
利用方式:
**篡改块内容或顺序:**攻击者可能会故意改变 PNG 文件中的块内容或块顺序,使得不同的解析器呈现不同的结果,
或者通过图像数据块将恶意代码插入其中
<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,0x66, 0x44, 0x50, 0x33);$img = imagecreatetruecolor(32, 32);for ($y = 0; $y < sizeof($p); $y += 3) {$r = $p[$y];$g = $p[$y+1];$b = $p[$y+2];$color = imagecolorallocate($img, $r, $g, $b);imagesetpixel($img, round($y / 3), 0, $color);
}imagepng($img,'./1.png');
?>
从别人那里看到的用来生成包含一句话木马的png图片
主要是十六进制一串 RGB 颜色值
下面的不过是创建图像资源,分配颜色。
生成的木马:<?$_GET[0]($_POST[1]);?>
在进行使用的时候,要get传一个参数,post传一个参数
看后端是被包含的,不然无法执行命令
中间件
一、IIS解析漏洞IIS作为一款使用比较广泛的Web应用,在特定的版本中存在一些文件名解析的漏洞。 1、exp.asp;.jpg 在5.X——6.X版本的IIS中,还存在如上的解析漏洞,即如果我们上传一个名为XXX.asp;.jpg的文件,那么尽管该文件的真实后缀名为jpg,但是IIS服务器会将该文件当成asp文件来进行处理。 2、xxx.jpg/xxx.php 在7——7.5版本的IIS中,如果我们上传一个名为xxx.jpg的文件,但是在访问该文件时,在该文件URL的后面添加xxx.php,那么该文件就会被当作PHP文件来执行。
二、Apache解析漏洞
同样的,Apache服务器由于其自身程序设计以及常见配置的问题,也容易产生各种各样的文件解析漏洞。 1、文件后缀从右向左判断 对于低版本Apache服务器而言,其对于文件后缀名的判断,是从右向左进行的,例如,如果我们上传一个名为exp.php.aaa的文件,那么该文件的后缀名为aaa,由于aaa不是一个合法的后缀名(合法的文件名是指mime.types文件中记录的文件名),因此Apache服务器会向该文件的前面寻找是否存在有合法的文件名,接下来找到的文件后缀名为php,php是一个合法的后缀名,因此该文件会被当作php文件来解析。 2、Apache换行解析漏洞(CVE-2017-15715) 在2.4.0-2.4.29版本的Apache中,存在着换行解析的漏洞,漏洞编号CVE-2017-15715。 简单来看,该漏洞的成因是Apache在进行上传文件文件名的提取时,如果文件名的最后存在\n、\r或者是0x0a,那么该\n、\r和0x0a会被当作文件名的一部分被提取出来,这样就可以对文件的后缀名造成污染,从而对文件后缀名的检测造成影响,但是当该文件被保存到本地时,如果目标系统不是Windows操作系统,那么该文件在存储时就会删除该换行符,从而使得我们上传的文件恢复为我们想要的后缀名。
例如,如果我们上传一个名为1.php0x0a的文件,那么在Apache提取到的文件后缀名为php0x0a,这样可以绕过一些黑名单的检测,而当该文件被保存到本地时,则会被删除掉0x0a,这样该文件就会恢复为原来的1.php。
三,Nginx漏洞
Nginx是一款高性能的Web服务器,该Web服务器下也有很多漏洞。 1、Nginx %00漏洞(CVE-2013-4547)
Nginx %00漏洞,编号CVE-2013-4547影响比较广泛,Nginx 0.8.41-1.4.3,以及1.5.x版本都到了受该漏洞的影响。 该漏洞的成因是%20%00在Nginx中的解析问题,在这里%20即空格,而%00即16进制的0x00,或\0。如果我们上传一个名为1.jpg%20的文件,那么由于该文件后缀名没有PHP,因此可以上传。但是当我们访问该文件时,访问1.jpg%20%00.php的文件,那么由于后面的php的后缀名,就会把我们上传的1.jpg的文件当作PHP来进行处理。 在这里插入图片描述
防御
1,扩展名检测,直接上白名单2,文件MIME验证,只允许上传jpg,png类型的图片
3,文件重命名
4,图片二次渲染
5,检查文件上传路径,只允许上传到本目录