2021 莲城杯 Reverse WP
作者cxing,转载请注明出处。
baby_rust
不知道用了什么算法,生成了一张256个字节的表,动态生成了一系列的索引(似乎是用随机数种子)取表中的值。我们取32个值即可,然后与加密数据异或即可得到flag,但奇怪的是题目自身无法验证通过。
enc = [
0xDE, 0xA5, 0x70, 0x9D, 0x74, 0xD0, 0x20, 0xA9, 0x60, 0xE8,
0xA5, 0xF7, 0x3F, 0xE9, 0x1E, 0x2A, 0xB0, 0x45, 0xB5, 0x39,
0xC1, 0x80, 0x26, 0xDF, 0xB7, 0xA7, 0x94, 0xE0, 0x9B, 0x03,
0xD2, 0x3A
]
table = [0xE9,0x9C,0x40,0xF9,0x47,0xE2,0x19,0xCC,0x06,0xDB,0x97,0xC6,0x0E,0xDD,0x2A,0x4F,0xD3,0x71,0x81,0x5F,0xF2,0xB7,0x42,0xEE,0x8F,0x9E,0xA5,0xD9,0xF9,0x37,0xE3,0x02]
for i in range(len(enc)):
enc[i] ^= table[i]
print(''.join(map(chr,enc))) #790d329ef321144ec44f37d18919b418
babybf
brainfuck用脚本解析出C语言代码,运行即可。
int main(_In_ int argc, _In_reads_(argc) _Pre_z_ char** argv, _In_z_ char** envp)
{
uint8_t ptr[40] = { 0 };
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
while (ptr[1]) {
ptr[0] += 10;
ptr[1] -= 1;
}
while (ptr[0]) {
ptr[0] -= 1;
ptr[10] += 1;
ptr[20] += 1;
}
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
while (ptr[1]) {
ptr[0] += 8;
ptr[1] -= 1;
}
while (ptr[0]) {
ptr[0] -= 1;
ptr[2] += 1;
ptr[3] += 1;
ptr[5] += 1;
ptr[7] += 1;
ptr[30] += 1;
}
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
while (ptr[1]) {
ptr[0] += 9;
ptr[1] -= 1;
}
while (ptr[0]) {
ptr[0] -= 1;
ptr[4] += 1;
ptr[6] += 1;
ptr[16] += 1;
ptr[22] += 1;
ptr[23] += 1;
ptr[24] += 1;
}
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
while (ptr[1]) {
ptr[0] += 10;
ptr[1] -= 1;
}
while (ptr[0]) {
ptr[0] -= 1;
ptr[9] += 1;
ptr[11] += 1;
ptr[12] += 1;
ptr[13] += 1;
ptr[14] += 1;
ptr[17] += 1;
ptr[18] += 1;
ptr[19] += 1;
ptr[21] += 1;
ptr[25] += 1;
ptr[28] += 1;
ptr[29] += 1;
}
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
ptr[1] += 1;
while (ptr[1]) {
ptr[0] += 11;
ptr[1] -= 1;
}
while (ptr[0]) {
ptr[0] -= 1;
ptr[8] += 1;
ptr[15] += 1;
ptr[26] += 1;
ptr[27] += 1;
ptr[31] += 1;
ptr[32] += 1;
ptr[33] += 1;
}
ptr[2] += 1;
ptr[2] += 1;
ptr[2] += 1;
ptr[2] += 1;
ptr[3] += 1;
ptr[4] += 1;
ptr[4] += 1;
ptr[5] += 1;
ptr[5] += 1;
ptr[5] += 1;
ptr[6] += 1;
ptr[6] += 1;
ptr[6] += 1;
ptr[7] += 1;
ptr[7] += 1;
ptr[7] += 1;
ptr[7] += 1;
ptr[7] += 1;
ptr[7] += 1;
ptr[8] += 1;
ptr[8] += 1;
ptr[9] -= 1;
ptr[9] -= 1;
ptr[10] += 1;
ptr[11] -= 1;
ptr[11] -= 1;
ptr[11] -= 1;
ptr[12] += 1;
ptr[12] += 1;
ptr[12] += 1;
ptr[12] += 1;
ptr[12] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[13] += 1;
ptr[14] += 1;
ptr[14] += 1;
ptr[15] -= 1;
ptr[15] -= 1;
ptr[15] -= 1;
ptr[15] -= 1;
ptr[16] += 1;
ptr[16] += 1;
ptr[16] += 1;
ptr[16] += 1;
ptr[16] += 1;
ptr[16] += 1;
ptr[16] += 1;
ptr[17] += 1;
ptr[17] += 1;
ptr[17] += 1;
ptr[17] += 1;
ptr[17] += 1;
ptr[17] += 1;
ptr[17] += 1;
ptr[18] -= 1;
ptr[18] -= 1;
ptr[18] -= 1;
ptr[18] -= 1;
ptr[18] -= 1;
ptr[19] += 1;
ptr[19] += 1;
ptr[19] += 1;
ptr[19] += 1;
ptr[19] += 1;
ptr[20] += 1;
ptr[20] += 1;
ptr[20] += 1;
ptr[21] -= 1;
ptr[21] -= 1;
ptr[21] -= 1;
ptr[21] -= 1;
ptr[21] -= 1;
ptr[22] += 1;
ptr[22] += 1;
ptr[22] += 1;
ptr[22] += 1;
ptr[22] += 1;
ptr[23] += 1;
ptr[23] += 1;
ptr[23] += 1;
ptr[23] += 1;
ptr[23] += 1;
ptr[24] += 1;
ptr[24] += 1;
ptr[24] += 1;
ptr[24] += 1;
ptr[24] += 1;
ptr[25] += 1;
ptr[26] -= 1;
ptr[26] -= 1;
ptr[26] -= 1;
ptr[26] -= 1;
ptr[26] -= 1;
ptr[26] -= 1;
ptr[26] -= 1;
ptr[28] -= 1;
ptr[28] -= 1;
ptr[28] -= 1;
ptr[28] -= 1;
ptr[28] -= 1;
ptr[29] += 1;
ptr[31] -= 1;
ptr[31] -= 1;
ptr[31] -= 1;
ptr[31] -= 1;
ptr[31] -= 1;
ptr[31] -= 1;
ptr[33] += 1;
ptr[33] += 1;
ptr[33] += 1;
ptr[33] += 1;
printf("%s", &ptr[2]); //DASCTF{b3ainfuXk_i5_VVVery_e@sy}
return 0;
}
LongTime
go程序逆向,先patch Sleep函数。程序主要利用一个等式,v1 = i + 4 * v1 + 1取索引作为斐波那契数列的项数取余16作为16进制符号的索引,相当于有两层映射关系,第一层是一个等式,第二层斐波那契数列的值,最终从16进制字符串中取字符,一个32个。
处理数列相关的实际问题,通常是列出一些项来观察规律,因此可知斐波那契数列取余16的数列是在每隔24项重复。
因此等式产生的32个值就可以在24内取余,作为斐波那契数列的项数,第三层映射非常简单就不说了,因此问题就解决了。
def get_flag():
table = "0123456789abcdef"
fib = [0,1,1,2,3,5,8,13,5,2,7,9,0,9,9,2,11,13,8,5,13,2,15,1]
idxs = []
v0 = 0
v1 = 1
while v0 < 32:
idxs.append(v1 % 24)
v16 = v0
v15 = v1
v0 = v16 + 1
v1 = v16 + 4 * v15 + 1
for e in idxs:
print(table[fib[e]],end='')
get_flag() # 15f559713195b57dd1f9b91d3df55971
to be or not to be, is a question.