upload20)通关教程
1、Pass-01-js检查
查看代码后端没有对上传文件进行过滤,且上传php木马代替图片:没有后端交互,只有前端;
修改前端代码;先点击浏览选中php木马文件,将文件上传位置代码内容中的onsubmit中的内容删除(删除return checkFile()),然后点击上传文件就显示木马文件上传成功;
2、Pass-02- content-type(MIME文件类型)
从代码中发现只对上传文件的Content-Type类型判断,通过burp抓包,修改Content-Type类型为图片类型进行绕过,就可以上传成功;
3、Pass-03-.php3和.php5后缀绕过
从代码中可看出只允许上传asp、aspx、php和jsp后缀文件,但有些版本支持php3和php5;可通过这个漏洞上传木马;就可直接将木马文件后缀改为php3或php5, 完成木马文件上传:
4、pass-04-PHP 和 Windows特性绕过
分析代码发现,这里对上传的后缀名的判断增加了,php3.php5....已经不允许上传,利用PHP 和 Windows环境的叠加特性,以下符号在正则匹配时的相等性:
利用PHP 和 Windows环境的叠加特性,以下符号在正则匹配时的相等性: 双引号" = 点号.
大于符号> = 问号?
小于符号< = 星号*
注意,在windows直接修改文件名称,肯定是不让你加冒号的,所以我们先以图片的格式上传,然后抓
包,修改文件名称,加上冒号,上传一个名为 tj.php:.jpg 的文件
上传上去之后的效果,由于文件名称不允许出现冒号,所有windows就将冒号和后面的字符都去掉了,就剩下123.php了,但是有个点就是,文件为0kb;
然后将文件名改为 tj.< 或 tj.<<< 或 tj.>>> 或 tj.>>< 后再次上传,重写 tj.php 文件内容,Webshell代码就会写入原来的 tj.php 空文件中。
5、pass-05-大小写混合绕过
但是 $file_ext = strtolower($file_ext); //转换为小写 这一句没有了,我们就可以使用,文件名后缀大小写混合绕过,把x.php改为x.phP来上传:
6、pass-06&07-空格和点配合绕过
从代码中看出将上传的文件名都改为小写了,利用Windows系统的文件名特性。用burpsuite抓包修改,将上传的文件名shell.php文件名最后增加空格和点,写成shell.php .,上传后保存在Windows系统上的文件名最后的一个.会被去掉,实际上保存的文件名就是shell.php;
7、pass08-基于文件流特性::DATA绕过
从代码中看,少了 $file_ext = str_ireplace(‘::$DATA‘, ‘‘, $file_ext);//去除字符串::$DATA这一句,我们可以采用Windows文件流特性绕过,文件名改为shell.php::$DATA, 上传成功后保存的文件名其实是shell.php:
8、pass09-点空格点绕过
原理同Pass-06,上传文件名后加上点+空格+点,改为 shell.php. . (php后面加点空格点)就可以绕过,上传文件;
9、pass10-双写绕过
从代码中发现,由于 $file_name = str_ireplace($deny_ext,"", $file_name); 只对文件后缀名进行一次过滤,可通过双写文件名绕过,文件名改成shell.pphphp:
10、pass11&19-%00截断绕过
这个属于白名单绕过,这是php语言自身的问题,php低版本存在的漏洞(这一关上传前需将phpstudy中php版本修改到5.3.4版本以下才能实现,同时把magic_quotes_gpc关闭)。
分析代码,这是以时间戳的方式对上传文件进行命名,使用上传路径名%00截断绕过,不过这需要对文件有足够的权限,比如说创建文件夹,上传的文件名写成shell.jpg, save_path改成../upload/shell.php%00 (shell.php%00.jpg经过url转码后会变为shell.php 00.jpg),最后保存下来的文件就是shell.php:
11、pass12-0x00绕过
原理同Pass-11,上传路径0x00绕过。利用Burpsite的Hex功能将save_path改成../upload/shell.php【二进制00】形式(这里的二进制00先在php后面加个空格,再再hex中将空格的二进制数20改为00,同时将filename后面的shell.php的后缀php改为jpg,就可以完成上传绕过):
12、pass13&14&15-图片文件头绕过
绕过文件头检查,添加GIF图片的文件头GIF89a,绕过GIF图片检查。
13、pass16-二次渲染绕过
原理:是将用户上传过来的文件数据重新读取保存到另外一个文件中,那么在读取写入的过程中,将特殊的数据剔除掉了。将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然相同的数据块部分,将Webshell代码插在该部分,然后上传。具体实现需要自己编写Python程序或者从github上找些可绕过的图片马,人工尝试基本是不可能构造出能绕过渲染函数的图片webshell的。
使用可绕过二次渲染图片马上传绕过:
14、pass17-时间竞争绕过
利用条件竞争删除文件时间差绕过。使用命令pip install hackhttp安装hackhttp模块,运行下面的Python代码即可。如果还是删除太快,可以适当调整线程并发数。
#!/usr/bin/env python
#coding:utf-8
#Build By LandGrey
import hackhttp
from multiprocessing.dummy import Pool as ThreadPool
def upload(lists):
hh = hackhttp.hackhttp()
raw = """POST /upload-labs/Pass-17/index.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/upload-labs/Pass-17/index.php
Cookie: pass=17
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------6696274297634
Content-Length: 341
-----------------------------6696274297634
Content-Disposition: form-data; name="upload_file"; filename="17.php"
Content-Type: application/octet-stream
<?php assert($_POST["LandGrey"])?>
-----------------------------6696274297634
Content-Disposition: form-data; name="submit"
上传
-----------------------------6696274297634--
"""
code, head, html, redirect, log = hh.http("http://127.0.0.1/upload-labs/Pass-17/index.php", raw=raw)
print(str(code) + "r")
pool = ThreadPool(10)
pool.map(upload, range(10000))
pool.close()
pool.join()
一方面不断上传文件,一方面不断访问上传的文件,那么我们就可以在它删除木马文件之前的时间差来访问执行木马。这里使用两个发包器,一个包是上传我们test.php的包,一个是访问我们上传test.php后的地址,不停的访问这个文件。每一个测试器的参数都设置的高一些,3000个包,100个线程。 然后我们发现tj.php被访问了,并且执行了,生成了qing.php文件(这种方面短时间内不一定能成功,看运气):
15、pass18-条件竞争绕过
利用上传重命名竞争+Apache解析漏洞,成功绕过。
上传名字为18.php.7Z的文件(因为该题的源代码中支持这个类型文件的上传,有白名单),快速重复提交该数据包,会提示文件已经被上传,但没有被重命名。apache解析文件名称的时候,是从右往左解析的,当它看到不认识的扩展名时,他就找前面的扩展名作为文件扩展名,这样它就当成了18.php了。 直接上传,我们通过抓包工具看一下
你注意观察upload文件夹,注意这是网站根目录的那个upload文件夹,不是根目录中的那个upload文件夹昂,发现这个文件上传上去之后,被重命名了。所以,我们现在其实玩的也是时间竞争。我们如果将包发到burp的测试器中,发送3000个包,100个线程发送,那么有些文件是没有来得及被重命名的,但是我们直接访问这个文件的时候你发现其实文件还是不能被解析的:
因为我们使用的phpstudy中的apache是没有这个漏洞的了,所以看不出效果。但是通过其他方式搭建的apache,它是有一个漏洞的,因为apache能解upload1.php.7z的,自动解析成了php文件。
快速提交上面的数据包,可以让文件名字不被重命名上传成功。 然后利用Apache的解析漏洞,即可获得shell;
16、pass20-代码审计
解题思路:这个思路大家自己看看就行了,我们直接看演示效果,也就是解题步骤。
文件命名规则:$file_name = reset($file) . "." . $file[count($file) - 1];
reset():将内部指针指向数组中的第一个元素,并输出。
end():将内部指针指向数组中的最后一个元素,并输出。
$file = empty($_POST["save_name"]) ? $_FILES["upload_file"]["name"] :
$_POST["save_name"];如果save_name不为空则file为save_name,否则file为filename
if (!is_array($file))判断如果file不是数组则以’.’分组
文件名命名规则$file_name = reset($file) . "." . $file[count($file) - 1];
我们POST传入一个save_name列表:["info20.php", "", "jpg"],此时
empty($_POST["save_name"]) 为假则file为save_name,所以由$ext = end($file);为jpg可以通
过后缀名判断(判断结束后最后一个元素jpg弹出),并且最终文件名组装为upload20.php.
解题步骤:上传包数据为,那个1.jpg其实是1.php改的名字,为了上传的时候通过前端js校验而已,里面有木马, 重点要通过后端校验:
修改数据包: