渗透学习
文件上传漏洞
文章目录
前言
本系列用于记录本人渗透学习的过程,主要内容围绕Owasp TOP 10展开。
文件上传漏洞将介绍客户端和服务端的文件上传的检测和绕过方法,通过一些实验案例了解文件上传漏洞的危害和一些常见类型,理解文件上传的利用条件。
本文只做学习用途,严禁利用本文提到的技术进行非法攻击,否则后果自负,本人不承担任何责任。
一、文件上传漏洞
上传文件时,如果未对上传的文件进行严格的验证和过滤,就容易造成文件上传漏洞,上传脚本文件(包括asp、aspx、jsp、php等)
造成文件上传漏洞的成因(比较复杂)有:
1.Web应用开放了文件上传功能,并且对上传的文件没有进行足够的限制
2.程序开发部署的时候,没有考虑到系统特性和过滤不严格
3.通过其他漏洞绕过限制
恶意的上传行为可能导致网站甚至整个服务器被控制。恶意的脚本文件又被称为WebShell,WebShell具有强大的功能,如查看服务器目录、服务器中文件、执行系统命令等。
如:
图示实验环境
在操纵机上准备要上传的脚本文件,如新建info.php文件
在之前的网页上上传
查看脚本文件info.php文件可以成功上传并解析
同理,可以上传一句话木马。
二、客户端检测与绕过
文件上传的客户端检测主要通过前端的JS代码获取文件后缀名进行验证,后端PHP代码没有对文件做任何检测,因此只需要绕过客户端检测。
客户端检测的绕过方法有三种:
- 删除浏览器事件
- 通过Burp Suite抓包修改后缀名
- 伪造上传表单
1.删除浏览器事件
客户端即前端检测的原理通常是靠调用JS的selectFile()函数,先将文件名转换为小写,然后通过substr获取文件名最后一个点号后面的后缀(包括点号)进行判断。
实验举例:
上传info.php时文件上传失败
右键查看元素,定位到文件域位置,可以看到表单调用了selectFile()函数。
追溯到selectFile()函数,双击展开函数代码
从代码中可以分析出:表单调用JS代码的selectFile()函数,先获取上传文件的文件名,然后将文件名转换为小写,再通过substr函数截取文件后缀名(包括.)进行判断。所以只需要不调用该JS代码,删除浏览器事件,即οnsubmit=" "
然后就可以成功上传
成功通过删除浏览器事件绕过selectFile()函数
2.抓包修改后缀名
由于selectFile()函数只对.jpg后缀设置了白名单,我们可以先把后缀改为.jpg绕过,再到Burp Suite抓包把后缀改回.php
在此进行修改,然后forward
发现上传绕过成功
3.伪造上传列表
由于表单调用了JS代码的selectFile()函数做过滤限制,并且表单提交到upload.php页面,所以伪造一个没有做任何过滤限制的表单同样提交即可。
去掉过滤条件,修改action
双击打开1.html
提交php文件即可,通过伪造一个没有做任何限制的表单,数据依然提交到目标地址,绕过原来的JS代码的限制。
三、服务端检测与绕过
文件上传从客户端进行检测显然是防护不足的,所以需要从服务器端进行防护。
服务端的检测与绕过方法有很多,常见的有:
- 后缀名检测绕过
- MIME类型检测与绕过
- 文件内容检测与绕过
- 00截断绕过
- 条件竞争检测与绕过
1.后缀名检测绕过
当服务端检测为黑名单时:
1.大小写绕过
2.名单列表绕过(黑名单外的后缀名:有些中间件允许解析其他文件后缀名,如asa、cer之类的或在httpd.conf配置文件中,配置如下代码,则能解析php、php3、phtml文件。所以上传一个后缀名为php3、phtml的文件即可。)
3.windows特性(一些特殊的文件名命名方式在windows下是不被允许的,利用BurpSuite抓包修改后缀名,绕过验证后上传文件,windows会自动去掉后面添加的,但Unix和Linux系统没有这个特性。如:1.php.、1.php 、1.php::$DATA)
当服务端检测为白名单时:
1.配合文件包含漏洞或文件解析漏洞
2…htaccess文件攻击(.htaccess文件是Apache服务器中的分布式配置文件(IIS中不存在该文件),该配置文件会覆盖Apache服务器的全局配置,作用于当前目录及其子目录。如果一个Web应用允许上传.htachess文件,那就意味着攻击者可以修改Apache的配置。而该文件中包含了很多解析方面的操作,会被利用)
3.Apache文件解析机制(从右向左开始解析,后缀名不可识别则向前,如1.php.XXX)
2.MIME类型检测与绕过
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
常见的MIME类型如下:
判断$_FILES["file"]["type"]
是不是图片格式(image/gif、image
/jpeg、image/pjpeg),不是则不允许上传,在HTTP协议中,使用Content-Type字段表示文件的MIME类型。$_FILES["file"]["type"]
的值是从请求数据包中Contet-Type中获取的。
因此,当服务端检测利用MIME类型检测时,只需要用BurpSuite抓包修改Content-Type字段为image/jpeg即可。
实验步骤:
将数据包中Content-Type值application/octer-stream修改为image/jpeg,再forward。
脚本文件成功上传。
3.文件内容检测与绕过
文件内容的检测是利用getimagesize()函数获取图片的宽高等信息,如果上传的不是图片,那么则获取不到信息。
文件内容检测的绕过常见的有两种方式:
1.在脚本文件前面补充对应的文件头
常见的图片文件头:
为了方便记忆我们通常使用GIF89a
2.制作图片马
在图片后写入脚本代码
在cmd中使用命令 copy 1.jpg/b+1.php/a 2.jpg
- 参数/b指定以二进制格式复制、合并文件,用于图像类/声音类文件
- 参数/a指定以ASCII格式复制、合并文件,用于txt等文档类文件
实验步骤:
这里我们采用第一种方法
补充图片的文件头(比如GIF文件头)
上传成功
4.00截断检测与绕过
截断漏洞出现的核心就是chr(0),这个字符不为空 (Null),也不是空字符 (" "),更不是空格。当程序在输出含有 chr(0)变量时,chr(0)后面的数据会被停止,换句话说,就是误把它当成结束符,后面的数据直接忽略,这就导致了漏洞产生。
由于0x00是字符串的结束标识符,PHP会把0x00后面的所有字符删除。攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测。
截断条件:PHP版本小于5.3.4、magic_quotes_gpc为OFF状态
实验步骤:
1.基于GET方式的00截断绕过
先上传一个php脚本,发现文件上传失败,不允许的后缀。
更改文件后缀为.jpg,用burpsuite抓包,将数据包"jieduan"参数添加"info.php%00"
forward,脚本文件成功上传
访问./upload/info.php6420220423075148.jpg,脚本解析失败,找不到文件。
访问./upload/info.php,上传的脚本文件成功解析
在使用基于GET方式的00截断绕过服务端的检测上传脚本文件时可以利用Burp Suite工具抓包在数据包的URL中添加“%00”,由于0x00是字符串的结束标识符,PHP会把0x00后面的所有字符删除,所以访问0x00前面的才可以成功解析。
另外,上传文件被重命名也可以靠爆破或00截断判断。
2.基于POST方式的00截断绕过
先上传一个php脚本,发现文件上传失败,不允许的后缀,需要用POST的方式。
更改文件后缀为.jpg,用burpsuite抓包,获得数据包
在Burp Suite中点击右侧的"INSPECTOR",并点击"Body Parameters(3)“,选中"jieduan"参数,点击右侧的”>",显示细节
将"VALUE"中"./upload/“修改为”.%2fupload%2finfo.php%00",然后将下方"DECODED FROM"中的字符串复制到左侧的"./upload/"处
forward,上传成功
另外,老版本的Burp Suite在代理模块中有“Hex”功能,可以直接编辑消息的原始二进制数据,直接将脚本文件后缀名后的数据修改为"00"即可。
5.条件竞争检测与绕过
一些网站文件检测逻辑是先允许上传任意文件,然后检测文件内容是否包含可执行脚本,如果包含则删除。
绕过方法:利用成功上传到删除文件的时间差,上传一个./php文件,在未删除之前立即访问,则会自动生成一个新的php文件,新文件不会被删除。
<?php
fputs(fopen('../shell.php','w'),'<?php phpinfo();?>');
?>
总结
以上比较全面的罗列了文件上传漏洞的原理和一些客户端和服务端的常见检测和绕过方式,并举了一些简单的实验案例,完成了文件上传漏洞的初步学习,为未来接触更复杂的绕过打下基础。