收获

  • 使用 OllyDBG 动态调试直接获取程序的中间数据

  • 分析伪代码函数逻辑


(2023年5月1日-2023年5月25日)【ISCC 2023】Pull the Wool Over People’s Eyes


思路

定位到主函数:

ISCC2023-Pull the Wool Over People's Eyes1.png

代码比较长,先定位到输入的位置:
sub_402190(std::cin, v35) 让用户输入 v35
sub_401650(Src, v22, v25) 用于生成一个 Src,后面会用到

生成 Src 的逻辑如下:

ISCC2023-Pull the Wool Over People's Eyes2.png

虽然给出了生成 Src 的代码,但是这里可以通过 OllyDBG 动态调试直接得到 Src 的内容,在 sub_401650() 函数的返回值处,下一个断点即可

先找到 return Src; 这句的地址,在这一条指令处使用快捷键 TAB

ISCC2023-Pull the Wool Over People's Eyes3.png

在 OllyDBG 中打开,定位到该位置,在 IDA 中该地址为 0x004017DB,在 OllyDBG 中为 0x000E17DB

ISCC2023-Pull the Wool Over People's Eyes4.png

F2 下断点
直接运行程序,输入的时候随便输入即可
在堆栈窗口中即可看到生成的 Src 的值为:ISCC{ACYeeeloorrsuv}

ISCC2023-Pull the Wool Over People's Eyes5.png

跟踪 Srcv35 的处理过程,观察到如下代码:

ISCC2023-Pull the Wool Over People's Eyes6.png

首先将输入 v35 赋值给 v4Src 赋值给 v5
其中,v3v35Src 的索引,v29v6 的索引
v7 = v4 + v3 指向 v35
v8 = v5 + v3 指向 Src
v6 指向 v35
*(v6 + v29) = *v8 ^ *v7v35Src 进行异或,即 v35[] = Src[] ^ v35[]

后面定义了一串 0 和 1 的字符串 v10,并用一个 while() 循环比较 v9[]v10[] 的值是否相等
若每一位都相等,则 v13 = 0,输出 Right

ISCC2023-Pull the Wool Over People's Eyes7.png

由初值 v11 = 156v14 = v11 < 4,当 v11 < 4 时结束循环
结合 Src = ISCC{ACYeeeloorrsuv} 长度为 20
v10 长度为 160,每 8 位二进制作为一组与 Src 进行异或
即可得到 flag


脚本

key = "ISCC{ACYeeeloorrsuv}"  
v10 = "0000000000000000000000000000000000000000011001000111001000101110001001110001010100000001000111110101110100101100000111010100101100100100010000010010000000000000"  
num = []  
for i in range(0, len(v10), 8):  
    t = ""  
    for j in range(8):  
        t += v10[i + j]  
    num.append(int(t, 2))  
print(list(key))  
print(num)  
for i in range(len(num)):  
    print(chr(ord(key[i]) ^ num[i]), end="")

结果

ISCC