2022 美团MTCTF初赛 small
分析
首先查壳,知道是64为无壳

然后放入相对应的IDA,但是这里要注意一下要以Binary的方式打开,我之前用7.7版本尝试直接打开文件,发现解析不出来,这里建议用二进制方式打开

然后就会看到一堆数据

这里我有直接全选然后按C转换为汇编代码过,但是发现会出错,并且找不到我想要的,然后去观察

这个0C3代表的是ret也就是一个结束,然后就从6A开始选中去按C

发现这个unk_64函数有点点不对,然后就选中68,69这两行然后强行转换为汇编代码就成了一个对的函数
然后进行分析一下这个函数在干嘛

这里的shl的移位和4,5的出现,能联想到这是一个tea的魔改,然后这里循环是23次,我写脚本发现不对,然后就声明了一下函数才知道是循环了35次(可能前面按C变成汇编代码的时候弄错了才导致循环次数不对,但也不怎么影响)

接着就是去找密文
这里找密文其实挺艰难的(对我来说),首先在魔改tea函数的后面还有几个函数

这个sub_C0函数有一个跳转与loc_EA函数有关,这两个函数好像没什么多大用,然后F1行这里有一个endp代表结束了。这里F3行开始后面的汇编代码都很不常见,还有很多花,我就把它们全选按U转换成了数据

然后有一个good,那么就猜测good后面的应该是所需要的密文了,然后就是写脚本了
脚本
#include <stdio.h> #include <stdint.h>
void decrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) { uint32_t v0 = v[0], v1 = v[1], i; uint32_t delta = 0x67452301,sum = delta*num_rounds; uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; for (i = 0; i<num_rounds; i++) { v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); sum -= delta; } v[0] = v0; v[1] = v1; } void dump_data(uint32_t * v,int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < 4; j++) { printf("%c", (v[i] >> (j * 8)) & 0xFF); } } printf("\n"); return; } int main() { uint32_t v[] = {0xde087143,0xc4f91bd2,0xdaf6dadc,0x6d9ed54c,0x75eb4ee7,0x5d1ddc04,0x511b0fd9,0x51dc88fb}; uint32_t k[4] = {0x01,0x23,0x45,0x67}; unsigned int r = 35; int n = sizeof(v) / sizeof(uint32_t); for(int i=0;i<n/2;i++) { decrypt(r,&v[i*2],k); } printf("解密后明文字符:"); dump_data(v,n); return 0; }
|
总结
比赛的时候是全部按C没有去想那么多,如果有去想字节码估计还是能做出来的。还有就是密文的找到方式我也不知道还有没有其他更好的方法,希望有大佬指点!!!