February 22, 2022

TQLCTF2022-Tales of the Arrow

直呼RE人坐牢日

0x00 日常查壳

纯Python程序

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

print("Enter the text within tqlctf{ ... }:")
# tqlctf{123456789}
id = input();

id_bytes = bytes(id, "ascii")
bits = ''.join(["{0:08b}".format(x) for x in id_bytes]) # 转成二进制存到bits

print(bits)

n = len(bits)

N = 5000

# print(n)
# print(N)
print(2**29)


def get_lit(i):
return (i + 1) * (2 * int(bits[i]) - 1)
# (i + 1) * -1 or 1

for t in range(N):
i = random.randint(0, n - 1) # i = [0, 135]
p = random.randint(0, 2) # p = [0, 2]
true_lit = get_lit(i)
for j in range(3):
if j == p:
print(true_lit, end = " ")
else:
tmp = random.randint(0, n - 1) # tmp = [0, 135]
rand_true = get_lit(tmp)
if random.randint(0, 3) == 0:
print(rand_true, end = " ")
else:
print(-rand_true, end = " ")

# 如果结果相同 能证明第 i 位是0或1

0x01 我们银河见

已知:括号内17位,于是每个字符的最高位为0,于是知道(17 / 136)

已知:一次循环两个为真或假 一个为必真(位为0为负,位为1为正)

检索每个循环

只有得知一 次循环两个为假 -> 确定一个数据必为真

以此可以恢复部分数据,再反复根据已知位确定余下数据

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
output = open("output.txt", "rb").read().split(b'\n')
flags = output[2:-1]

bits = [0 for i in range(136)]
vis = [False for i in range(136)]
f = []

for i in range(136):
if i % 8 == 0:
bits[i] = 0
vis[i] = True

for i in range(5000):
f.append([])
for j in range(3):
x = abs(int(flags[i * 3 + j])) - 1
if int(flags[i * 3 + j]) > 0 and x % 8 == 0: # 如果必为负数位大于0 就进入下次循环
continue
f[i].append(int(flags[i * 3 + j])) # 去掉确定为假的值 其他全部装入
if len(f[i]) == 1: # 如果只剩一个说明其他两个都为假 那么剩下那个必为真
vis[abs(f[i][0]) - 1] = True
bits[abs(f[i][0]) - 1] = 1 if f[i][0] > 0 else 0

Judge = True
while ( Judge ):
Judge = False
for i in range(5000):
for j in f[i]:
x = abs(j) - 1
if vis[x]: # 用已确定的值来去除不确定的值
if j > 0 and bits[abs(j) - 1] == 0:
f[i].remove(j)
if j < 0 and bits[abs(j) - 1] == 1:
f[i].remove(j)
if len(f[i]) == 1: # 如果只有剩下一共值 两个可能 1. 这个值已经确定不用再添加 2. 该值是新值 加入确定数组 并重新开始循环
x = abs(f[i][0]) - 1
if not vis[x]:
vis[x] = True
bits[x] = 1 if f[i][0] > 0 else 0
Judge = True
break

flag = ''
x = 0
for i in range(17):
x = 0
for j in range(8):
x = x * 2 + bits[i * 8 + j]
flag += chr(x)

print("TQLCTF{" + flag + "}")

银河见!(理科生的浪漫我爱了)

image-20220222154144475

DASCTF X SU
🍬
HFCTF2022
🍪

About this Post

This post is written by P.Z, licensed under CC BY-NC 4.0.