Drinksometea
题目给了exe和一个tea.png.out(加密完生成的文件),哇这个第一题做了我一天啊。。。已知是tea就卡在不会文件读写是真的难受住了呜呜呜呜
逻辑是很清晰的,CreateFile,ReadFile 这些句柄可自行百度,理解是在干什么即可(但要是要像我一样想仿着这个写个C++脚本逆回去。。。。就各种报错。。。一言难尽了。。wtcl)

关键就在loc_4010A0的位置,但是不能F5,因为加了花指令
哇今天最大的收获就是k1ee师傅给一步步教的去花(感谢!!

Undefine+C(emmm早有耳闻。。。)我以为这就结束了。。

师傅说要把jz jnz 和 db 0E8h 给nop掉,用的 010editor (长见识了~
jz jnz 机器码 74 75,还有下面用到的nop 是90,常识了

搜索 ,然后 Ctrl + R (五个都要改成 90 吖。。。

然后就可以看到正常的函数了,确实是tea,之前有见过类似的题

传入了假的flag作密钥,我本来以为密钥就是flag四个字母

动调了一下发现我还是太天真了(是四个一组,还要考虑大小端序,如果没有动调,废物就当场gg了

哦对,这道题动调会秒退的。。是这个函数作怪,在这儿下断

有个get,out!哈,这。。一步步绕呗,走右边那条路就绕过了

ps:解密函数里delta是个负数,不太好办得看看十六进制

拿到了这些,tea解密脚本还是好写的。。。但是!写入二进制文件我是真的真的不会啊(哭泣。。。。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| fin=open('tea.png.out','rb') tea=fin.read() fin.close()
def sub(b1,b2): v5=0xC6EF3720 a0=0X67616C66 a1=0x6B61667B a2=0x6C665F65 a3=0x7D216761 v3=b1 v6=b2 for i in range(32): v6 -= (a3 + (v3 >> 5)) ^ (v5 + v3) ^ (a2 + 16 * v3) v3 -= (a1 + (v6 >> 5)) ^ (v5 + v6) ^ (a0 + 16 * v6) v5 -= 0x9e3779b9 b1=v3 b2=v6 flag='' l=len(tea) v8=l>>3 for i in range(v8): sub(tea[i],tea[i+1]) i+=2
|
以下是oc师傅给的脚本:
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 40 41 42 43 44 45 46 47
| #include <stdio.h> #include <stdint.h> #define _CRT_SECURE_NO_WARNINGS
void encrypt(int* v, int* k) { int v0 = v[0], v1 = v[1], sum = 0, i; int delta = 0x9e3779b9; int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; for (i = 0; i < 32; i++) { sum += delta; v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); } v[0] = v0; v[1] = v1; }
void decrypt(int* v, int* k) { int v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; int delta = 0x9e3779b9; int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; for (i = 0; i < 32; 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; }
int main() { int v[2], k[4] = { 1734437990, 1801545339, 1818648421, 2099341153 }; FILE* fin = fopen("tea.png.out", "rb"); FILE* fout = fopen("tea.png", "wb"); while (fread(v, sizeof(v), 1, fin)) { decrypt(v, k); fwrite(v, sizeof(v), 1, fout); } fclose(fin); fclose(fout); return 0; }
|
解完就是个图片。。呜呜好丑。。真就卡我一天啊,哭死

Enjoy_it
看了一下别的师傅的wp,觉得。。。这才是签到题吧(唉。。既然不复杂就复现一下了)
ida打开发现不对劲,是个.NET程序,上dnSpy
b.b和b.c是对输入的校验,flag好像是取这个输入的bytes进行运算生成的
关键是它会输出flag!!那岂不是很友好。。(但要想办法跳过那个Sleep

所以先看看输入的text2是什么,base64既视感(表换了。。。

解出输入,验证正确~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import base64 import string
str='yQXHyBvN3g/81gv51QXG1QTBxRr/yvXK1hC='
flag='' string1="abcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ=" string2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
flag=str.translate(str.maketrans(string1,string2)) flag=base64.b64decode(flag)
print(flag)
|

到了关键了,怎么跳过Sleep,这要是ida就好了。。不会用dnSpy啊。。我是废物。。。然后,去问了那个写wp的师傅~~
师傅说动调的时候用右键设置下一条语句,诶还有这么神奇的功能嘛

好耶!!! 学到了学到了,复现完成啦
希望下周的 MRCTF 可以让我做出来题。。。