深育杯

⏳:2021-11-13

Lithops

无壳 32位 ida32打开

 

从输入到 check 有很多函数

莽一点 从check函数下断点 步入进去看看试试

输入任意长的flag之后进入 check 函数

 

再直接从 return 处下断点 f9 运行

 

双击进入 dword_813C60 查看 发现两处引用

且有一处引用是在我们的 check 函数

点击追踪过去

 

之后我们程序运行到此处时

 

发现 push ecx 中的 ecx 里面存放的值是我们的输入

 

而继续运行下去

push edx 中的 edx 值为

 

取出查看

0xE4, 0xB8, 0x8D, 0xE5, 0x81, 0x9A, 0xE4, 0xBC, 0x9F, 0xE5, 0xA4, 0xA7, 0xE6, 0x97, 0xB6, 0xE4, 0xBB, 0xA3, 0xE7, 0x9A, 0x84, 0xE6, 0x97, 0x81, 0xE8, 0xA7, 0x82, 0xE8, 0x80, 0x85

自己没有发现这是 UTF-8 编码方式

(赛后wp里面写明 此程序在加密过程中调用了 UTF-8 编码)

放上一点知识:

unicode-table.com/cn/

最后找个网站解码即可

 


flag{不做伟大时代的旁观者}


press

查壳 无壳 ida64打开

 

最后main函数输出out文件 内容

60 E1 2F 05 79 80 5E E1 C5 57 8B CC 5C 9A 67 26 1E 19 AF 93 3F 09 E2 97 99 7B 86 C1 25 87 D6 0C DD CF 2A F5 65 0E 73 59 1D 5F A4 F4 65 68 D1 3D D2 98 5D FE 5B EF 5B CC

查看关键函数1

 

++++++++++[->++++++++++++++++<],[->-<]>>[-]+++++<*++.<

查看关键函数2

 

说明了每个字符的操作 类似小型虚拟机 和真brainfuck加密不同

所以只能一步一步读取

贴一个师傅转成的代码

这里对指令的解读是难点 有点恶心人

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
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1;
ptr[0] += 1; //ptr[0] = 10

while
(ptr[0]) {
ptr[0] -= 1;
ptr[1] += 16; //ptr[1] += 160
}

ptr[0] = get();

while
(ptr[0]) {
ptr[0] -= 1;
ptr[1] -= 1; //ptr[1] = 160 - 输入的大小
}

while
(ptr[2]) {
ptr[2] -= 1;
}

ptr[2] += 1;
ptr[2] += 1;
ptr[2] += 1;
ptr[2] += 1;
ptr[2] += 1; //ptr[2] = 5 也就是ptr[1] *= 5
ptr[1] += 1;
ptr[1] += 1; //ptr[1] += 2

put(ptr[1]); //output = (x + 160-input) * 5 + 2

解密时需要注意溢出

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
out = [0x060,0x0E1,0x02F,0x005,0x079,0x080,0x05E,0x0E1,0x0C5,0x057,0x08B,0x0CC,0x05C,
0x09A,0x067,0x026,0x01E,0x019,0x0AF,0x093,0x03F,0x009,0x0E2,0x097,0x099,0x07B,
0x086,0x0C1,0x025,0x087,0x0D6,0x00C,0x0DD,0x0CF,0x02A,0x0F5,0x065,0x00E,0x073,
0x059,0x01D,0x05F,0x0A4,0x0F4,0x065,0x068,0x0D1,0x03D,0x0D2,0x098,0x05D,0x0FE,0x05B,0x0EF,0x05B,0x0CC]
flag = ''

for i in range(len(out)):
ens = out[i] - 2

while(ens != ens // 5 * 5):
ens += 0x100
ens = ens // 5

if(i == 0):
flag += chr(160 - ens)
else:
flag += chr((out[i-1] + 160 - ens) % 0x100)

print(flag)

ZmxhZ3tkZTBiZDY3ZS02ZDI1LTg3ZDctMTg3Ni1hZDEzMWE2MTY1Y2J9

base64解码即可


flag{de0bd67e-6d25-87d7-1876-ad131a6165cb}


xor_exercise

 

default去除之后会有残留

类似这种永真永假的语句

 

官方wp写的是

 

其实查看了官方给出的script.py之后 明白了就是用idapython nop掉无用代码

附上

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
def patch_nop(start, end):
for i in range(start, end):
PatchByte(i, 0x90)

def next_instr(addr):
return addr+ItemSize(addr)

st = 0x0000000000401170
end = 0x0000000000402de0

addr = st
while(addr < end):
next = next_instr(addr)
if "ds:y" in GetDisasm(addr):
while(True):
addr = next
next = next_instr(addr)
if "jnz" in GetDisasm(addr):
dest = GetOperandValue(addr, 0)
PatchByte(addr, 0xe9)
PatchByte(addr+5, 0x90)
offset = dest - (addr + 5)
PatchDword(addr + 1, offset)
print("patch bcf: 0x%x" % addr)
addr = next
break
else:
addr = next

ida里面 shitf+f2 运行代码发现报错

NameError: name ‘ItemSize’ is not defined

查找资料找到解决办法:

关于IDA7.5 IDApython api差异问题及解决办法 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

题目是crc64加密

从官方发的更新后的题文件能找到相关数字串来确定是crc64加密(虽然我自己看不出来就是了)

贴个其他师傅写的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cmp = [0x32E9A65483CC9671, 0xEC92A986A4AF329C, 0x96C8259BC2AC4673,
0x74BF5DCA4423530F, 0x59D78EF8FDCBFAB1, 0xA65257E5B13942B1]

for i in range(6):
for j in range(64):
if (int(cmp[i])&1)==1:
cmp[i] ^= 0xB1234B7679FC4B3D
cmp[i] = cmp[i]>>1
cmp[i] |= 0x8000000000000000
else:
cmp[i] = cmp[i]>>1

for i in range(6):
print(hex(cmp[i]), end=',')