n00bzCTF-2024 Writeup

n00bzCTF-2024 Writeup

👉👉👉获取高性价比云服务器👍👍👍

Crypto

Vinegar

Can you decode this message? Note: Wrap the decrypted text in n00bz{}.

1
2
Encrypted flag: nmivrxbiaatjvvbcjsf
Key: secretkey

解题:

n00bz{vigenerecipherisfun}

RSA

The cryptography category is incomplete without RSA. So here is a simple RSA challenge. Have fun!

1
2
3
e = 3
n = 135112325288715136727832177735512070625083219670480717841817583343851445454356579794543601926517886432778754079508684454122465776544049537510760149616899986522216930847357907483054348419798542025184280105958211364798924985051999921354369017984140216806642244876998054533895072842602131552047667500910960834243
c = 13037717184940851534440408074902031173938827302834506159512256813794613267487160058287930781080450199371859916605839773796744179698270340378901298046506802163106509143441799583051647999737073025726173300915916758770511497524353491642840238968166849681827669150543335788616727518429916536945395813

解题:

rsa 低指数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from gmpy2 import iroot
import libnum

e = 3
n = 135112325288715136727832177735512070625083219670480717841817583343851445454356579794543601926517886432778754079508684454122465776544049537510760149616899986522216930847357907483054348419798542025184280105958211364798924985051999921354369017984140216806642244876998054533895072842602131552047667500910960834243
c = 13037717184940851534440408074902031173938827302834506159512256813794613267487160058287930781080450199371859916605839773796744179698270340378901298046506802163106509143441799583051647999737073025726173300915916758770511497524353491642840238968166849681827669150543335788616727518429916536945395813

k = 0
while 1:
res = iroot(c + k * n, e) # c+k*n 开3次方根 能开3次方即可
if (res[1] == True):
print(libnum.n2s(int(res[0]))) # 转为字符串
break
k = k + 1
# b'n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}'

n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}

Vinegar 2

Never limit yourself to only alphabets!

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
alphanumerical = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'
matrix = []
for i in alphanumerical:
matrix.append([i])

idx=0
for i in alphanumerical:
matrix[idx][0] = (alphanumerical[idx:len(alphanumerical)]+alphanumerical[0:idx])
idx += 1

flag=open('../src/flag.txt').read().strip()
key='5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
assert len(key)==len(flag)
flag_arr = []
key_arr = []
enc_arr=[]
for y in flag:
for i in range(len(alphanumerical)):
if matrix[i][0][0]==y:
flag_arr.append(i)

for y in key:
for i in range(len(alphanumerical)):
if matrix[i][0][0]==y:
key_arr.append(i)

for i in range(len(flag)):
enc_arr.append(matrix[flag_arr[i]][0][key_arr[i]])
encrypted=''.join(enc_arr)
f = open('enc.txt','w')
f.write(encrypted)

enc.txt

1
*fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({

解题:

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
alphanumerical = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'
matrix = []
for i in alphanumerical:
matrix.append([i])

idx = 0
for i in alphanumerical:
matrix[idx][0] = (alphanumerical[idx:len(alphanumerical)] + alphanumerical[0:idx])
idx += 1

# 读取加密文本
encrypted = "*fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({"
key = '5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
assert len(key) == len(encrypted)

key_arr = []
for y in key:
for i in range(len(alphanumerical)):
if matrix[i][0][0] == y:
key_arr.append(i)

# 解密过程
dec_arr = []
for i in range(len(encrypted)):
key_index = key_arr[i]
encrypted_char = encrypted[i]
for j in range(len(alphanumerical)):
if matrix[key_index][0][j] == encrypted_char:
dec_arr.append(alphanumerical[j])
break

decrypted = ''.join(dec_arr)
print(decrypted)

n00bz{4lph4num3r1c4l_1s_n0t_4_pr0bl3m}

Random

I hid my password behind an impressive sorting machine. The machine is very luck based, or is it?!?!?!?

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
#include<chrono>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string>
#include<fstream>
#include<thread>
#include<map>
using namespace std;

bool amazingcustomsortingalgorithm(string s) {
int n = s.size();
for (int i = 0; i < 69; i++) {
cout << s << endl;
bool good = true;
for (int i = 0; i < n - 1; i++)
good &= s[i] <= s[i + 1];

if (good)
return true;

random_shuffle(s.begin(), s.end());

this_thread::sleep_for(chrono::milliseconds(500));
}

return false;
}

int main() {
string s;
getline(cin, s);

map<char, int> counts;
for (char c : s) {
if (counts[c]) {
cout << "no repeating letters allowed passed this machine" << endl;
return 1;
}
counts[c]++;
}

if (s.size() < 10) {
cout << "this machine will only process worthy strings" << endl;
return 1;
}

if (s.size() == 69) {
cout << "a very worthy string" << endl;
cout << "i'll give you a clue'" << endl;
cout << "just because something says it's random mean it actually is" << endl;
return 69;
}

random_shuffle(s.begin(), s.end());

if (amazingcustomsortingalgorithm(s)) {
ifstream fin("flag.txt");
string flag;
fin >> flag;
cout << flag << endl;
}
else {
cout << "UNWORTHY USER DETECTED" << endl;
}
}

解题:

random_shuffle 的随机每次的结果是一样的 只需要找到变换顺序 按顺序算一个下一结果符合要求的值即可

1
2
3
4
5
6
7
8
9
10
11
12
a = '0123456789'
b = '4378052169'

c = [''] * len(a)

for i, char in enumerate(b):
index = a.index(char)
c[index] = a[i]

c = ''.join(c)
print(c)
# 4761058239

n00bz{5up3r_dup3r_ultr4_54f3_p455w0rd_02efffa2b997}

Misc

Addition

My little brother is learning math, can you show him how to do some addition problems?

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

questions = int(input("how many questions do you want to answer? "))

for i in range(questions):
a = random.randint(0, 10)
b = random.randint(0, 10)

yourans = int(input("what is " + str(a) + ' + ' + str(b) + ' = '))

print("calculating")

totaltime = pow(2, i)

print('.')
time.sleep(totaltime / 3)
print('.')
time.sleep(totaltime / 3)
print('.')
time.sleep(totaltime / 3)

if yourans != a + b:
print("You made my little brother cry 馃槶")
exit(69)

f = open('/flag.txt', 'r')
flag = f.read()
print(flag[:questions])

解题:

输入-1 将不会进入循环 并且能获取到 flag[:-1] 全部内容

n00bz{m4th_15nt_4ll_4b0ut_3qu4t10n5}

Agree

I hope you like our Terms of Service and Privacy Policy of our website!

解题:

在注册页面有两个连接

n00bz{Terms_0f_Serv1c3s_4nd_pr1v4cy_p0l1cy_6f3a4d}

Subtraction

My little brother is learning math, can you show him how to do some subtraction problems?

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

n = 696969

a = []
for i in range(n):
a.append(random.randint(0, n))
a[i] -= a[i] % 2

print(' '.join(list(map(str, a))))

for turns in range(20):
c = int(input())
for i in range(n):
a[i] = abs(c - a[i])

if len(set(a)) == 1:
print(open('/flag.txt', 'r').read())
break

解题:

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
import socket
import time

sock = socket.socket()
sock.connect(("challs.n00bzunit3d.xyz", 10507))


def recv_until_newline(sock):
data = ''
while True:
part = sock.recv(1024).decode('utf-8') # 接收数据并解码
data += part
if '\n' in data:
break
return data


data = recv_until_newline(sock)
l = data.split(' ')
a = [int(i) for i in l]

n = 696969
send_list = []
for turns in range(20):
# 找到数组 a 中的最大值和最小值
max_a = max(a)
min_a = min(a)

# 计算 c 为最大值和最小值的中点
c = (max_a + min_a) // 2
print(turns, c) # 输出这个 c 值
send_list.append(c)

for i in range(n):
a[i] = abs(c - a[i])

if len(set(a)) == 1:
print("open flag")
break

for i in send_list:
sock.send(str(i).encode('utf-8') + b'\n')
time.sleep(0.5)

flag = sock.recv(1024).decode('utf-8')
print(flag)
sock.close()

n00bz{1_sh0uld_t34ch_my_br0th3r_logs_1be84f03cdb3}

WaaS

Writing as a Service!

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
import subprocess
from base64 import b64decode as d
while True:
print("[1] Write to a file\n[2] Get the flag\n[3] Exit")
try:
inp = int(input("Choice: ").strip())
except:
print("Invalid input!")
exit(0)
if inp == 1:
file = input("Enter file name: ").strip()
assert file.count('.') <= 2 # Why do you need more?
assert "/proc" not in file # Why do you need to write there?
assert "/bin" not in file # Why do you need to write there?
assert "\n" not in file # Why do you need these?
assert "chall" not in file # Don't be overwriting my files!
try:
f = open(file,'w')
except:
print("Error! Maybe the file does not exist?")

f.write(input("Data: ").strip())
f.close()
print("Data written sucessfully!")

if inp == 2:
flag = subprocess.run(["cat","fake_flag.txt"],capture_output=True) # You actually thought I would give the flag?
print(flag.stdout.strip())

解题:

代码中导入了 base64 并未使用 可以利用文件写入 base64.py 并在 base64.py 中完成代码执行,程序会优先调用当前目录下的base64.py,由于只能写入一行 利用 ; 号绕过,和 使用 b64decode = lambda: None 实现b64decode 函数 不让代码报错

1
import subprocess;print(subprocess.run(["cat","flag.txt"],capture_output=True).stdout.strip()); b64decode = lambda: None

n00bz{0v3rwr1t1ng_py7h0n3_m0dul3s?!!!_3cf4a694557f}

Web

Passwordless

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
#!/usr/bin/env python3
from flask import Flask, request, redirect, render_template, render_template_string
import subprocess
import urllib
import uuid
global leet

app = Flask(__name__)
flag = open('/flag.txt').read()
leet=uuid.UUID('13371337-1337-1337-1337-133713371337')

@app.route('/',methods=['GET','POST'])
def main():
global username
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
username = request.values['username']
if username == 'admin123':
return 'Stop trying to act like you are the admin!'
uid = uuid.uuid5(leet,username) # super secure!
return redirect(f'/{uid}')

@app.route('/<uid>')
def user_page(uid):
if uid != str(uuid.uuid5(leet,'admin123')):
return f'Welcome! No flag for you :('
else:
return flag

if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337)

解题:

计算出uuid直接请求地址即可

1
2
3
4
5
6
7
8
9
10
import uuid

import requests

leet = uuid.UUID('13371337-1337-1337-1337-133713371337')
uid = str(uuid.uuid5(leet, 'admin123'))

r = requests.get('http://24.199.110.35:40150/' + uid)
print(r.text)
# n00bz{1337-13371337-1337-133713371337-1337}

n00bz{1337-13371337-1337-133713371337-1337}

Rev

Vacation

My friend told me they were going on vacation, but they sent me this weird PowerShell script instead of a postcard!
run.ps1

1
2
3
4
5
6
7
$bytes = [System.Text.Encoding]::ASCII.GetBytes((cat .\flag.txt))
[System.Collections.Generic.List[byte]]$newBytes = @()
$bytes.ForEach({
$newBytes.Add($_ -bxor 3)
})
$newString = [System.Text.Encoding]::ASCII.GetString($newBytes)
echo $newString | Out-File -Encoding ascii .\output.txt

output.txt

1
m33ayxeqln\sbqjp\twk\{lq~

解题:

异或3

1
2
3
4
5
a = r'm33ayxeqln\sbqjp\twk\{lq~'

for i in a:
print(chr(ord(i) ^ 3), end='')
# n00bz{from_paris_wth_xor}

n00bz{from_paris_wth_xor}

Brain

Help! A hacker said that this “language” has a flag but I can’t find it!

1
>+++++++++++[<++++++++++>-]<[-]>++++++++[<++++++>-]<[-]>++++++++[<++++++>-]<[-]>++++++++++++++[<+++++++>-]<[-]>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<++>-]<[-]>+++++++++++++++++++++++++++++++++++++++++[<+++>-]<[-]>+++++++[<+++++++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>+++++++++++[<+++++++++>-]<[-]>+++++++++++++[<++++>-]<[-]>+++++++++++[<++++++++++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>+++++++++++[<+++++++++>-]<[-]>++++++++[<++++++>-]<[-]>++++++++++[<++++++++++>-]<[-]>+++++++++++++++++[<+++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>+++++++[<+++++++>-]<[-]>+++++++++++[<++++++++++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>++++++++++++++[<+++++++>-]<[-]>+++++++++++++++++++[<++++++>-]<[-]>+++++++++++++[<++++>-]<[-]>+++++++[<+++++++>-]<[-]>+++++++++++[<++++++++++>-]<[-]>+++++++++++++++++[<++++++>-]<[-]>+++++++[<++++++>-]<[-]>+++++++++++[<+++++++++>-]<[-]>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<[-]>+++++++++++[<+++>-]<[-]>+++++++++++++++++++++++++[<+++++>-]<[-]

解题:

使用 brainfuck-visualizer 运行发现规律<[-] 会清空值 将<[-] 替换为 输出字符 <.

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
def brainfuck_interpreter(code, input_data=''):
tape = [0] * 30000
pointer = 0
code_pointer = 0
input_pointer = 0
output = []
loop_stack = []

while code_pointer < len(code):
command = code[code_pointer]

if command == '>':
pointer += 1
if pointer >= len(tape):
tape.append(0)

elif command == '<':
pointer -= 1
if pointer < 0:
raise IndexError("Data pointer moved to a negative index")

elif command == '+':
tape[pointer] = (tape[pointer] + 1) % 256

elif command == '-':
tape[pointer] = (tape[pointer] - 1) % 256

elif command == '.':
output.append(chr(tape[pointer]))

elif command == ',':
if input_pointer < len(input_data):
tape[pointer] = ord(input_data[input_pointer])
input_pointer += 1
else:
tape[pointer] = 0 # If no input is available, set cell to 0

elif command == '[':
if tape[pointer] == 0:
open_brackets = 1
while open_brackets != 0:
code_pointer += 1
if code[code_pointer] == '[':
open_brackets += 1
elif code[code_pointer] == ']':
open_brackets -= 1
else:
loop_stack.append(code_pointer)

elif command == ']':
if tape[pointer] != 0:
code_pointer = loop_stack[-1]
else:
loop_stack.pop()

code_pointer += 1

return ''.join(output)


# 示例用法
bf_code = [
'>+++++++++++[<++++++++++>-]<.',
'>++++++++[<++++++>-]<.',
'>++++++++[<++++++>-]<.',
'>++++++++++++++[<+++++++>-]<.',
'>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<++>-]<.',
'>+++++++++++++++++++++++++++++++++++++++++[<+++>-]<.',
'>+++++++[<+++++++>-]<.',
'>+++++++++++++++++++[<+++++>-]<.',
'>+++++++++++[<+++++++++>-]<.',
'>+++++++++++++[<++++>-]<.',
'>+++++++++++[<++++++++++>-]<.',
'>+++++++++++++++++++[<+++++>-]<.',
'>+++++++++++[<+++++++++>-]<.',
'>++++++++[<++++++>-]<.',
'>++++++++++[<++++++++++>-]<.',
'>+++++++++++++++++[<+++>-]<.',
'>+++++++++++++++++++[<+++++>-]<.',
'>+++++++[<+++++++>-]<.',
'>+++++++++++[<++++++++++>-]<.',
'>+++++++++++++++++++[<+++++>-]<.',
'>++++++++++++++[<+++++++>-]<.',
'>+++++++++++++++++++[<++++++>-]<.',
'>+++++++++++++[<++++>-]<.',
'>+++++++[<+++++++>-]<.',
'>+++++++++++[<++++++++++>-]<.',
'>+++++++++++++++++[<++++++>-]<.',
'>+++++++[<++++++>-]<.',
'>+++++++++++[<+++++++++>-]<.',
'>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<.',
'>+++++++++++[<+++>-]<.',
'>+++++++++++++++++++++++++[<+++++>-]<.',
]
for i in bf_code:
output = brainfuck_interpreter(i)
print(output, end='')
# n00bz{1_c4n_c0d3_1n_br41nf*ck!}

n00bz{1_c4n_c0d3_1n_br41nf*ck!}

FlagChecker

Why did the macros hide its knowledge? Because it didn’t want anyone to “excel”! Note: char_21 is the SAME as char_22 Note 2: The correct flag has ALL LOWERCASE, NUMBERS, n00bz{} AND UNDERSCORES (There’s two underscores in the entire flag)

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
Sub FlagChecker()

Dim chars(1 To 24) As String
guess = InputBox("Enter the flag:")
If Len(guess) <> 24 Then
MsgBox "Nope"
End If
If (Asc(char_1) Xor Asc(char_8)) = 22 Then
If (Asc(char_10) + Asc(char_24)) = 176 Then
If (Asc(char_9) - Asc(char_22)) = -9 Then
If (Asc(char_22) Xor Asc(char_6)) = 23 Then
If ((Asc(char_12) / 5) ^ (Asc(char_3) / 12)) = 130321 Then
If (char_22 = char_11) Then
If (Asc(char_15) * Asc(char_8)) = 14040 Then
If (Asc(char_12) Xor (Asc(char_17) - 5)) = 5 Then
If (Asc(char_18) = Asc(char_23)) Then
If (Asc(char_13) Xor Asc(char_14) Xor Asc(char_2)) = 121 Then
If (Asc(char_14) Xor Asc(char_24)) = 77 Then
If 1365 = (Asc(char_22) Xor 1337) Then
If (Asc(char_10) = Asc(char_7)) Then
If (Asc(char_23) + Asc(char_8)) = 235 Then
If Asc(char_16) = (Asc(char_17) + 19) Then
If (Asc(char_19)) = 107 Then
If (Asc(char_20) + 501) = (Asc(char_1) * 5) Then
If (Asc(char_21) = Asc(char_22)) Then
MsgBox "you got the flag!"
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End Sub

解题:

Z3求解

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
from z3 import *

# 创建一个优化器
s = Solver()

# 创建字符变量,使用 BitVec 类型来支持按位操作
char_vars = [BitVec(f'char_{i}', 8) for i in range(1, 25)]

# 添加字符范围约束
for char in char_vars:
s.add(Or(
And(char >= 48, char <= 57), # 数字 0-9
And(char >= 97, char <= 122), # 小写字母 a-z
char == 95, # 字符 _
char == 123, # 字符 {
char == 125 # 字符 }
))

s.add(char_vars[0] == ord('n'))
s.add(char_vars[1] == ord('0'))
s.add(char_vars[2] == ord('0'))
s.add(char_vars[3] == ord('b'))
s.add(char_vars[4] == ord('z'))
s.add(char_vars[5] == ord('{'))
s.add(char_vars[23] == ord('}'))
# 添加给定的条件
constraints = [
char_vars[0] ^ char_vars[7] == 22,
char_vars[9] + char_vars[23] == 176,
char_vars[8] - char_vars[21] == -9,
char_vars[21] ^ char_vars[5] == 23,
# (char_vars[11] / 5) ^ (char_vars[2] / 12) == 130321, # 除法运算存在问题
char_vars[21] == char_vars[10],
char_vars[14] * char_vars[7] == 14040,
char_vars[11] ^ (char_vars[16] - 5) == 5,
char_vars[17] == char_vars[22],
char_vars[12] ^ char_vars[13] ^ char_vars[1] == 121,
char_vars[13] ^ char_vars[23] == 77,
1365 == char_vars[21] ^ 1337,
char_vars[9] == char_vars[6],
char_vars[22] + char_vars[7] == 235,
char_vars[15] == char_vars[16] + 19,
char_vars[18] == 107,
char_vars[19] + 501 == char_vars[0] * 5,
char_vars[20] == char_vars[21]
]

# 将约束添加到求解器
for constraint in constraints:
s.add(constraint)

# 用于存储所有解的集合
all_solutions = set()

# 查找所有解
while s.check() == sat:
model = s.model()
solution = ''.join([chr(model[char].as_long()) for char in char_vars])
all_solutions.add(solution)

# 创建一个新的约束,阻止当前解
block = []
for char in char_vars:
block.append(char != model[char])
s.add(Or(block))

# 打印所有找到的解
print(f"Total solutions found: {len(all_solutions)}")
for sol in all_solutions:
if '_' in sol:
print(sol)

#Total solutions found: 10
#n00bz{3xc3l_y05r_sk1lls}
#n00bz{3xc3l_y0ur_sk1lls}

n00bz{3xc3l_y0ur_sk1lls}