在练习文件上传漏洞之前,我们首先要知道文件上传被利用的两个前提条件:
http://www.upload:93/upload/abc.jpg
2.网页上右键选择查看页面源代码,源代码中显示文件的相对路径
3.如果是用burpsuite上传的文件,reponse报文中也会显示文件的相对路径。
进入第一关要求我们上传一个webshell,所以我们直接选择一个php文件进行上传,上传之后,跳出了一个弹窗,提示当前文件类型不是允许上传的文件类型。
查看网页源代码,发现文件类型和弹框是由前端JS代码校验的。说明弹框时文件格式没有经过后端校验。
所以本关至少有两种方法:浏览器关闭JS,或者上传合法格式的文件,burp抓包并修改文件后缀为.php。
firefox可以安装一个叫Script Switch的插件,安装成功之后,就是下图右上角小红框里那个图标,使其处在JS disabled状态,上传1.php。出现下图这样没加载成功的图片表示webshell已经上传成功。
到服务器上看看,上传成功的webshell在 upload-labs目录\upload 文件夹下
将服务器上的1.php删除,再来测试方法2
把刚才使用的1.php修改为muma.png,上传抓包
将请求报文中的Content-Disposition头的filename从muma.png修改为muma.php,然后一路forward,图片成功上传
服务器也成功上传
第二关我们进行上传一个php文件后,没有弹窗显示,而且也没说上传类型,说明本关是一个后端黑名单校验。
本关也有两种绕过方法:第一种是上传php文件,改Content-Type,第二种是上次合法后缀文件,改文件改后缀。
使用burp抓取上传的php文件,将Content-Type的值修改为image/png
查看服务器成功上传
将1.php修改为muma.png,上传抓包
直接修改filename的值为muma.php,然后一路forward
查看服务器成功上传
代码分析:
从第五行可见,本关后端代码对上传文件的Content-Type,也就是MIME进行了白名单校验。事实证明,单纯对MIME校验对于文件上传攻击并没有什么用。
按照惯例上传一个1.php文件,发现页面显示不允许上传…后缀文件,并且burp有抓到包,初步判断,这关可能是后端文件后缀黑名单过滤。
这里就要说到常见文件上传漏洞查找方法,如果是黑盒测试就需要不断手工测试,或者通过常用字典进行爆破,若是白盒测试,就通过代码审计的方式查看是不是存在过滤不严谨从而导致文件上传漏洞。
由于这里是实验闯关所以我选择直接使用白盒代码审计的方法进行闯关。
查看源代码发现他对文件扩展名进行了去末尾的点,转换为小写,去掉了::$DATA,去掉空格的操作,然后与第五行的后缀黑名单进行比较,后缀名在黑名单中则报错。
这里他没有过滤php3php4php5等字符,这些也会被解析为php代码,但我这里不推荐使用这种方法,因为这个需要Apache等提供这些解析方法才能解析,如果对方未开启,则这种方法就无效
如图所示,我的apache只提供了php3和phtml解析为php代码。
所以我这里推荐使用文件末尾双写::$DATA绕过过滤或添加空格绕过
因为:(1)trim和deldot函数可以删掉连续的多个空格和点,但str_ireplace函数只能替换掉一个::$DATA,因此本关可以文件末尾双写::$DATA绕过过滤
查看服务端文件成功上传
并能成功解析
进入第四关上传1.php后,提示为这个文件不能上传。
由于没有任何提示,所以跟上一关一样,进行代码审计
通过查看代码发现,在上一关过滤的基础上还过滤很多文件名后缀,但他没有过滤.htaccess文件,所以我们可以上传.htaccess文件
.htaccess的作用用来做伪静态将任意文件当做php文件进行解析。
关于.htaccess方法绕过文件上传黑名单过滤的具体方法,下面这个文章里面有详细描述: 【文件上传】.htaccess上传
简而言之,使用这种方法是需要满足一些环境条件的:
此时根据分析代码逻辑,发现他是在上传文件后先是删除文件末尾的点,然后首尾去空,去除字符串::$DATA,但是这些操作只执行一次。所以我们可以抓取数据包来修改绕过。我们在数据包中把后缀名改为.php. .,首先他发现有一个点,这时会把他去掉,又发现有一个空格,也会把它去掉,我们这时还有一个点,也就是.php. 由于他只是验证一次,所以不会在去掉我们的点。
查看服务端文件上传成功
查看图片地址,成功解析php代码
上传1.php失败,提示此文件类型不允许上传
还是用上一关的方法,进行代码审计
发现本关还是使用trim函数进行的过滤,所以我们可以继续使用双写进行绕过,但本关使用第三关的代码1.php::$DA::$DATATA,发送后会提示报错,但从图中的代码可知,这表明其实已经绕过了黑名单过滤了。但为什么上传出错呢?
仔细看代码会发现是因为文件没有move成功,对比本关和Pass-03的代码可以发现,本关目标文件名是HTTP请求中的filename,而Pass-03目标文件名是随机数拼接处理后的文件后缀。在windows系统上尝试创建文件名为1.php:: D A : : DA:: DA::DATATA和1.php::$DATA的文件可以发现,前者创建成功,后者创建失败。至此真相大白~
所以本关我们可以直接双写php进行绕过。
如图所示,查看服务端发现成功上传
但是他的后缀是pphphp,也不能正常解析php代码
所以我们这里只能换一个方法,通过查看他的过滤,发现他也没有过滤.ini文件,所以我们用.user.ini文件绕过文件上传黑名单过滤。
那我来简单说一下,php中有一个默认配置文件php.ini,其中包括了很多php的配置,而自 PHP 5.3.0 起,PHP 支持基于每个目录的 INI 文件配置。
此类文件 仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果你的 PHP 以模块化运行在 Apache 里,则用 .htaccess 文件有同样效果。
可以查看这篇文章
文件上传–.hatccess–.user.ini
和使用.htaccess一样,使用.user.ini也要满足一些环境条件:
对比可见,使用.user.ini的条件比.htaccess宽松不少。但是我的环境上也没有尝试成功,因为我的环境没有使用CGI和FastCGI。
此时根据分析代码逻辑,发现他是在上传文件后先是删除文件末尾的点,然后首尾去空,去除字符串::$DATA,但是这些操作只执行一次。所以我们可以抓取数据包来修改绕过。我们在数据包中把后缀名改为.php. .,首先他发现有一个点,这时会把他去掉,又发现有一个空格,也会把它去掉,我们这时还有一个点,也就是.php. 由于他只是验证一次,所以不会在去掉我们的点。
查看服务端文件上传成功
查看图片地址,成功解析php代码