318's Blog

来人间一趟,总要见见太阳

0%

DASCTF_RE部分复现

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

//注意注意,本题为算数移位,不能用uint!!!
//加密函数
void encrypt(int* v, int* k) {
int v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
int delta = 0x9e3779b9; /* a key schedule constant */
int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
} /* end cycle */
v[0] = v0; v[1] = v1;
}
//解密函数
void decrypt(int* v, int* k) {
int v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; /* set up */
int delta = 0x9e3779b9; /* a key schedule constant */
int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
} /* end cycle */
v[0] = v0; v[1] = v1;
}

int main()
{
int v[2], k[4] = { 1734437990, 1801545339, 1818648421, 2099341153 };
FILE* fin = fopen("tea.png.out", "rb");//注意不是"r"!!!
FILE* fout = fopen("tea.png", "wb");
while (fread(v, sizeof(v), 1, fin))
{
//printf("%d %d\n",v[0],v[1]);
decrypt(v, k);
//encrypt(v,k);
//printf("%d %d\n",v[0],v[1]);
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)
#combustible_oolong_tea_plz

在这里插入图片描述
到了关键了,怎么跳过Sleep,这要是ida就好了。。不会用dnSpy啊。。我是废物。。。然后,去问了那个写wp的师傅~~

师傅说动调的时候用右键设置下一条语句,诶还有这么神奇的功能嘛
在这里插入图片描述
好耶!!! 学到了学到了,复现完成啦

希望下周的 MRCTF 可以让我做出来题。。。