目录
pass-04(Apache解析漏洞\.htaccess文件绕过)
注:
- 本项目提供的
writeup
只是起一个参考作用。 - 实在没有思路时,可以点击查看提示。
- 如果黑盒情况下,实在做不出,可以点击
查看源码
。
搭建:
https://github.com/c0ny1/upload-labs
pass-01(前端绕过)
可以直接上传木马看看情况(因为php文件肯定是上传不了的,主要看看报错情况):
看着挺眼熟,感觉就像只是在前端js文件中做限制,bp抓包看看:
发现抓不到,那就是在前端做验证了,审查元素发现存在一个checkfile函数,顾名思义就是一个检查函数:
删掉再上传即可:
找到文件的地址,右键也好,F12也罢均可,蚁剑连接,没有问题:
在下一关开始前最好点击一下右上角的清空上传文件,把前一关上传的小🐎清空一下,免得造成混淆。
pass-02(后缀绕过)
同样上传一个php看看:
提示类型不正确,应该是过滤了后缀名,抓包修改后缀再上传,这里上传前需要将自己的🐎的后缀改成这里允许的后缀,我这里改成jpg,然后再用bp抓包再次修改后缀名后绕过上传:
成功上传,并且也看见了文件地址,蚁剑连接,没有问题:
再提一下,右上角清空上传文件。
pass-03(黑名单绕过)
还是一样,直接上传🐎看看:
这里限制了一部分文件,属于黑名单绕过,还有一些文件后缀并没有限制,如.php3、.php4、.php5、.pht、.phtm、.phtml等,那直接修改我们的🐎后缀名为这些其中一个即可,但我这卡了一下,即使我上传的.php4文件成功了,但也无法执行,网上查了一下说要在httpd.conf配置文件中以下位置添加:
<IfModule>
...
#AddType text/html .shtml
#AddOutputFilter INCLUDES .shtml
AddType application/x-httpd-php .php .phtml .php3 .php4 .php5 .phps .pht .phtm
</IfModule>
当我添加了之后,发现还是不能解析,重启也没用,接着找到了一位大佬曾经也遇到跟我一样的问题,简而言之问题就是,小皮v8.1的版本没有TS版本的php,全是nts:
最简单的解决办法,就是换一个版本,小皮v2018有:
问题解决,继续做题,在httpd.conf文件中添加解析语句后,上传黑名单之外的文件(上传可以选择先修改后缀再上传或者先上传再使用bp修改):
蚁剑连接成功:
注:若要判断上传后的文件能不能执行,可以直接访问🐎地址,正常情况下就是一片空白,无任何反应,如果出现下载,那就是没有执行。
pass-04(Apache解析漏洞\.htaccess文件绕过)
apache解析漏洞:apache读取后缀从右向左,若遇见不认识的后缀名便向前继续读取,直到认识的后缀。
影响版本:apache 2.4.x。
在上传文件的后面再随意加一个后缀即可上传成功,再通过apache解析漏洞成功执行:
蚁剑成功连接:
这里可以先看看提示:
可以看见过滤了挺多东西的,但并没有过滤.htaccess文件,这个文件是一个分布式配置文件,全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。
先本地创建一个.htaccess文件,里面写以下三行代码:
<FilesMatch .jpg>
SetHandler application/x-httpd-php
</FilesMatch>
这三行代码的意思是通过一个.htaccess 文件调用 php 的解析器去解析一个文件名中只要包含".jpg"这个字符串的任意文件,都可以被以 php 的方式来解析。
那思路就很清晰了,先上传.htaccess文件,再上传之前改过后缀的🐎,也就是“.a.jpg”文件,然后“.a.jpg”文件就可以以php的方式来执行(这里的“.a.jpg”文件中的内容就是一句话🐎)。
蚁剑连接,没有问题:
pass-05(后缀大小写绕过)
这里就省一步上传php文件了,直接看看提示:
其实这里看提示就可以了解到这关考的是后缀大小写绕过,因为这里虽然限制了很多,但仔细一看,限制了.php之外又限制.pHp,所以这里的代码肯定没有做大小写限制,只是单纯的限制.php和.pHp,那很明显还有.Php,.phP,.PhP没被限制,随便丢一个上传即可:
蚁剑连接,没有问题:
pass-06(空格绕过)
看一下源码:
发现没有对空格进行过滤,不了解的可以查看一下上一关的源码,发现多了一句转小写的代码,少了一句首尾去空的代码:
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空
所以直接抓包,在上传文件的后面加一个空格即可上传成功:
蚁剑连接成功:
pass-07(点绕过)
这关挺牛啊,佩服。
不过再看一下源码,发现这关的源码相比上一关来说少了一个去除末尾的点:
$file_name = deldot($file_name);//删除文件名末尾的点
那就使用点绕过,在上传文件的末尾加一个点,让服务器将其解析为可执行文件:
蚁剑连接成功:
pass-08(::$DATA绕过)
这关同样也禁用了很多,看一下源码:
基本已经将前面所有的限制都在内了,但唯独有一个"::$DATA"没做限制, 在windows中如果文件名+"::$DATA",会把::$DATA之后的数据当成文件流处理,不会检测其后缀名,并且会保留"::$DATA"之前的文件名,这里就可以利用这一点进行绕过:
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
蚁剑连接成功(这里注意的是连接的时候文件名是"::$DATA"前面的部分,不包括"::$DATA"。)
pass-09(处理不当绕过)
这关比较细节,直接放源码:
这里一看,在限制这一块,前面的所有限制都包括了,那就说明前面的绕过方式都没用,注意看下面这个代码:
if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
这里跟前面有两处不同,首先是在文件保存的时候并没有使用随机名字,接着是在保存文件时的处理只对file_name做处理,没有对file_ext做处理,而file_name只消除了后面的点,从而导致了这里变成了单次检测,因此这里使用“. .”即可绕过,这里的两个点之间需要有空格,如果使用两个连续的点会被一起删掉,而这里删除点的时候遇到空格就停止了,需要中间需要有个空格才行。
蚁剑连接成功:
pass-10(双写绕过)
这关就有点奇怪,直接看源码:
估计从这关开始就没注释了,这里关键点就在于下面这句代码:
$file_name = str_ireplace($deny_ext,"", $file_name);
str_ireplace函数的意思就是匹配第三个参数中的内容,如果里面有第一个参数的内容,则替换成中间参数的内容,举个例子,比如下面这个代码:
str_ireplace("WORLD","Peter","Hello world!")
先放这个函数的结果:
Hello Peter!
一目了然了吧,就是把Hello world!里的world替换成Peter,其它不变,并且大小写不影响。
那回到这题,这题就相当于把我们上传的文件名中还有黑名单里的后缀直接删掉,但是这里只处理了一次,没有作循环处理,那就双写后缀即可。
但是这里我使用bp抓包该后缀名没成功,虽然bp显示没成功,但其实已经上传上去了,我这里就换一种上传方式,先在本地双写后缀再上传即可:
可以成功上传:
蚁剑连接也没问题:
pass-11(%00截断-GET)
放源码:
重点在于下面这个代码:
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
这里拼接了上传路径,并且save_path可控,那就可以使用%00来截断,比如上传路径是/upload,也就是save_path=../upload,此时上传的🐎为shell.jpg的话,那就可以再save_path后添加shell.php%00,这时save_path=../upload/shell.php%00,接着将.jpg后缀与save_path拼接的话就变成了save_path=../upload/shell.php%00/{.rand(10, 99).date("YmdHis").}.jpg,此时%00就将后面的都注释掉了,就只剩下一个shell.php文件了。
不过这个太老了,实现它需要两个条件:
1、PHP版本小于5.3.29;
2、magic_quotes_gpc = Off
这里的php版本直接调就行:
magic_quotes_gpc的关闭我个人更推荐直接在配置文件中修改:
修改成off就行:
接下来就可以开始上传了:
蚁剑连接成功:
pass-12(%00截断-POST)
放源码:
放眼一看,跟上一关居然差不多,还是那句代码的问题:
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
仔细一看,上一关用的GET请求,这一关变成POST,抓包也可以看得出来:
除了这个区别之后,在POST请求中,不会自动对url编码进行解码,这里就需要手动对%00进行解码,选中后右键选择Convert selection---URL---URL-decode:
接着你会发现它好像变成了空格一样:
那是因为%00是ascii值为0字符的url编码形式,但这并不代码直接在后面加空格就可以了哈。
上传成功后,蚁剑连接:
注:结束这一关后,记得将PHP版本调回去,以免后续关卡出现出现问题。