理解文件上传漏洞原理
掌握几种文件上传绕过方法
文件上传:文件上传是现代互联网常见的功能,允许用户上传图片、视频、及其他类型文件,向用户提供的功能越多,web受攻击的风险就越大。
上传文件时,如果未对上传的文件进行严格的验证和过滤,就容易造成文件上传漏洞,上传脚本文件(asp、aspx、php、jsp等)
注:asp,aspx对应iis解析 php对应apache解析 jsp对应java(tomcat)
恶意上传行为可能导致网站甚至整个服务器被控制。恶意的脚本文件又被称为Webshell。Webshell具有强大的功能。如查看服务器目录、服务器中文件、执行系统命令等。
调用JS的toLowerCase()函数,先将文件名转换为小写,然后通过substr获取文件名后面最后一个点号后面的后缀(包括点号)进行判断。
substr()返回字符串
//enctype=“multipart/form-data” 专门处理文件上传的文件流
//return selectFile() 提供点击提交按钮,完成文件上传
注:这里网站的过滤仅为前端过滤,这里前端代码只允许后缀名伪".jpg"的文件上传。我们先去尝试浏览器前端过滤。
如图:通过F12打开开发者模块,将onsubmit的值删除,这里οnsubmit=""调用的函数即为我们编写的判断(过滤)方法。将此处值删除后再次点击上传我们想要上传的任意文件,观察实验结果并访问上传后的文件
注:这里我们发现通过修改前端页面的值,成功上传并解析了文件
注:这里我们可以先将我们想要上传的php文件后缀直接改为jpg。也可使用合成图片码的方式,抓包后将后缀再改回我们需要上传的文件后缀,放包后观察结果。
注:这里将33.jpg文件后缀修改回.php后放包,文件即可成功上传。
这里我们成功上传并解析了我们想要上传的文件,同理,我们可以绕过上传任何我们想要上传的任何文件。
copy 1.jpg/b +1.php/a 2.jpg
这里是将1.jpg与1.php文件合并,生成新图片2.jpg
通过函数pathinfo()获取文件后缀,将后缀转为小写后判断是不是php
注:pathinfo() 返回文件路径的信息
有些中间件允许解析其他文件后缀的,如在httpd.conf配置文件中,配置如下代码,则能解析php、php3、phtml文件。所以上传一个后缀名为php3、phphtml的文件即可绕过黑名单。
注:这里添加消息的含义是要能够解析php3,phtml 这里是将添加的这两种后缀按照php文件解析
结合Apache文件解析机制,从右向左开始解析文件后缀,若后缀名不可识别,则继续判断直到遇到可解析的后缀为止,若全部不认识,则会暴露文件内容。
在程序开发部署的时候,没有考虑到系统的特性会导致限制被绕过,利用windows特性。可以在后缀名中加"."或"::$DATA"绕过
注:这里我们给文件名直接加. windows本身特性会自动删除,限制如此修改文件后缀,这里就需要使用burpsuit来进行修改
注:这里我们尝试上传了.jpg .txt .php这里我们发现只有php的文件无法上传,通过代码我们也可以知道,此处是将php的文件加入了黑名单,不允许后缀为php的文件上传。
这里我们上传一个后缀名为php3的文件,如下图,我们发现上传成功,但是访问该文件时,php文件未解析。
注:我们此模块的内容主要讲文件解析及上传,这里文件上传已经成功,接下来要做的就是文件解析
(1)打开phpstudy面板,点击【设置】–>【配置文件】–>【httpd.conf】–>点击apache的版本 打开文件
(2)在文件处使用Ctrl+F 进行查找,先去查找AddType
如图:找到如下内容,在下面加入以下3条命令
AddType application/x-http-php .php
AddType application/x-http-php .php3
AddType application/x-http-php .phtml
注:这里添加消息的含义是要能够解析php3,phtml 这里是将添加的这两种后缀按照php文件解析
这里我们再次访问上传的.php3可以发现php文件可以正常解析。
修改文件名为.php.XX 这里XX可以是数字,也可以是字母,根据apache解析漏洞来进行上传绕过
使用burpsuit抓包来对文件后缀进行修改 可以在后缀名中加"."或"::$DATA"绕过
判断$_FILES["file"]["type"]是不是图片格式(image/gif、image/jpeg、image/pjpeg),不是则不允许上传。
$_FILES["file"]["type"]的值是从请求数据包中Content-type中获取的
注:我们这里的类型检测,也是有相应的配置文件与之对应的,检测文件类型的配置文件为mime.types 文件位置为:
D:\phpstudy_pro\Extensions\Apache2.4.39\conf\mime.types
注:这里我们可以看到各种文件类型与对应关系
通过抓取数据请求包,上传php文件时,Content-Type值为application/octer-stream,上传jpg的文件时Content-Type值为image/jpeg。可修改文件类型进行绕过。
如果代码使用getimagesize()函数获取图片的宽高等信息,如果上传的不是图片,那么则获取不到信息。
在图片文件脚本文件开头补充图片对应的头部值,或在图片后写入脚本代码(这里就是第一节课讲过的图片+代码合成新图片的知识模块)
(1)方法1 这里我们将文件头部值写入文件即可
注:下图显示的47 49 46……这些是16进制数,可以通过01编辑器进行编辑,我们通过nt++编辑时可直接在代码前面编写GIF89a,我们可以通过编码转换进行验证。
(2)方法2 合成图片这种方法前面已经讲过,这里不再讲。下面再将一种方式
直接将图片使用记事本模式打开,在乱码后面直接加入我们需要加入的PHP代码。
注:这里我们修改完后文件后缀名依旧是.JPG 我们虽然修改了文件内容,但是上传成功后.JPG文件依旧无法解析。这里我们要将添加完代码的图片后缀名改为.php后再次上传,上传后即可实现解析。但这里操作没有方法1方便,操作时也可将合成图片上传后,在burpsuit中将后缀名改为php后放包,即可实现上传绕过,也可实现解析。
这里我们发现,无论是上传jpg/png…凡是图片类型的文件均可上传,php/txt…其他类型文件均不能上传。通过代码我们可以发现,这里是通过白名单的方式,只允许图片类型的文件上传,只有在白名单之内的文件才可以上传,这里我们发现,单纯通过浏览器,网页前端,我们无法做任何绕过与修改。我们依旧需要使用burpsuit抓包的方式去进行绕过。
(1)将文件类型修改为Content-Type:image/jpeg放包后观察是否文件上传成功
注:这里我们发现文件不仅上传成功,并且成功解析
如图:图片乱码后面就是我们写入的代码,根据图片步骤,抓包后修改后缀,放包,观察结果
可以看到这里文件成功解析,图片在文件中为乱码形式,后面加入的php代码phpinfo();成功解析
由于00代表结束符,PHP会把00后面的所有字符删除
截断条件:PHP版本小于5.3.4、magic_quotes_gpc为OFF状态
注:magic_quotes_gpc参数设置在phpstudy面板中【设置】–>【配置文件】–>【php.ini】–>【php5.2.17nts】打开文件,然后查找(Ctrl+F)magic_quotes_gpc参数设置为OFF
这里必须要下载一个版本低于5.3.4的php,然后将网站的php版本修改为低版本。
注:魔术引号:magic_quotes_gpc=On时,会把引号进行转义。 php版本升级后将magic_quotes_gpc函数丢弃,使用了新的转义函数。
GET方法中加入%00截断
POST方法中传入00并解码
注:我们上传的文件进行了重命名,所以才会有我们的上传00截断
这里通过上传我们发现,只有白名单内的文件后缀才能够上传,白名单外的文件(如php)均不可上传。我们通过浏览器前端也无法再做什么其他可绕过的方式,我们通过抓包去尝试绕过。
如图:上图标记的地方是GET方式的GET请求表单,在jieduan=./upload/后加上2.php后放包进行观察
注:我们这里上传了一个图片码
放包后我们可以看到文件上传成功,但是我们上传的文件名这里重叠了一个2.php(802020…)我们正常访问这个文件依旧可以解析,解析后是一个图片。我们接下来尝试去00截断
如图:在GET请求后加入2.php%00 后放包,观察我们的页面
这里我们发现回显的文件404错误,找不到文件
这里我们发现,我们成功上传并解析了刚才上传的图片码,这里就是00截断的一种绕过方式(GET方式)
这里我们依旧发现只有白名单内的文件允许上传,其他文件均不允许上传
注:这里我们发现POST请求与GET请求的不同之处。首先是URL处不带请求,但是文本内容重点出现了./upload 这里便是我们的POST请求,POST请求需要
如图,找到上步修改文件名的位置,修改00处的编码为00(30–>00)前面我们给php后面加的00是为了更快更准确的找到文件后缀名所在的位置。16进制修改为00后再去观察Raw视图
如图:修改完成后我们输入的00会转换为两个框型图案
如图,我们看到文件上传成功,同上面操作过程,检验文件是否能够正常解析
这里我们看到文件成功上传并成功解析,00截断成功
一些网站文件检测逻辑是先允许上传任意文件,然后检查文件内容是否包含可执行脚本,如果包含则删除。这里使用sleep()函数来模拟判断是否含有脚本所需要的时间。
利用成功上传到删除的时间差,上传一个.php文件,在未删除之前立即访问,则会自动生成一个新php文件,新文件不会被删除。
这里我们发现任意文件均可上传,这里上传时我们需要等待10s才可上传成功,这里我们模拟文件上传,上传后再经过检查将文件删除的过程。
这里可以在10s等待,文件还未上传成功时,点击访问,即可生成新文件shell.php
注:这里是模拟竞争上传环境,我们一边上传,系统会自动删除我们上传的文件,这里就需要快速访问上传文件,只要访问到刚才上传的文件,即可实现我们想要写入的文件生成。
如图,这里的shell.php是我们访问上一步上传文件后生成的新文件,这里文件内容可以自行控制,可以写入我们想要的任何文件。