第四题 血色试炼

TlsCallBack分析

TlsCallback_0初始化了两个Key,以及一个Base64表,并且有一个标准Sbox和一个标准InvSbox赋值。

alt text

alt text

alt text

alt text

这边从ntdll.dll中寻找所有Zw开头API,然后储存到自定义链式结构中。

alt text

这边加载了个加密字符串,自解密出来是ZwQueryInformationProcess,然后通过第二处红框去上面的结构里面找到对应API的syscall服务号。

alt text

赋值给全局服务号变量,然后调用syscall,判断返回值是否>=0,若>=0则触发异常,说明这边可能是一个反调试。

alt text

alt text

直接在这个call后面设置条件断点将返回值改成负数即可绕过。

alt text

Main函数分析

main函数开头处有设置一个VEH,

alt text

VEH里面分成两部分代码执行。

alt text

动调发现输出完”UserName:”后会触发异常,然后进入第一个箭头call处,这里面是进行了一个输入流的启动,下面syscall后就是等待用户输入。

alt text

用户名输入完后会返回到这边,然后底下进行三次循环处理,循环内第一个call会触发第二种异常,进入VEH函数的第二部分代码。

alt text

红框处就是我们输入的用户名,下面对用户名进行加密,加密结果是一个Base64,和序列号的格式一样,循环三次会对UserName加密三次。

alt text

alt text

加密完直接输出FAILED,这边解题完后也不知道为什么。

alt text

通过观察decstr和encstr两个Call,猜测大概是相互转换的加解密函数。

断点在TlsCallBack的随便一个API名解密处,将第一个参数改成刚刚上面加密一次的数据,单步运行解密函数,发现返回的解密文本就是刚刚输入的字符串,说明猜想成立。

alt text

alt text

alt text

尝试将readme.txt里面的序列号patch进去进行解密。

alt text

发现可以解密出32个字节,但是后32字节暂时看不到。vaEW2QqcchrlmpysQuRAzZoCdbPvDxhx

alt text

当输入readme.txt的示例用户名时,在VEH函数这边断点,三次加密后查看第三次加密完的用户名,发现和上面我们解密序列号的前三十二字节一样。

alt text

alt text

结论

序列号 = 四次加密(用户名)

获取KCTF序列号

将Main函数这边对用户名加密三次循环改成4次。

alt text

第四次加密时候断下,查看箭头处字符串,即是用户名对应的序列号。

alt text

alt text

alt text

tSzQkyqcvZLgkwDltPF9RpInibA5fTpH/bJni2yvLzTKao2uL5eLZ5QIxPj8bsYWe48ZohC5/Jw3cNNAaX8/rA==