比赛没写出来,学会了新东西
__________________________________________
进来就发现了flag
DASCTF{I'am Fake But Why Look Like real?}
fake flag,但是but look real????
可以看见它的下面还有数据段
查看他下面数据段的引用
反编译不成功,拆测可能还存在SMC
而且这个数据段也十分可疑
回调
这种fake flag 小心还存在 hook 和tls,
一直找了star 函数
这个tls回调好隐蔽,我找不到
但是我跟着师傅们学到了一个新方法
附加进程
这样的话,比如这道题,在输入之前,我们都是正常运行的代码,系统检查不到动调
我们先在电脑上运行这个程序
dug里面选择attch
我下的断点是在这里,因为这里比较了0x100
很可疑
F7跟进就到了一个新的地方!
桃花源记是吧
而且这一段正巧是我们的DASCTF!
重编译一下
正常了!
一直从开头选到这里,好麻烦啊,我的天,有没有什么简单的方法
__int64 __cdecl sub_41D250(char *Str)
{
__int64 v1; // rax
__int64 v3; // [esp-8h] [ebp-24Ch]
int j; // [esp+D0h] [ebp-174h]
size_t i; // [esp+F4h] [ebp-150h]
char *v6; // [esp+100h] [ebp-144h]
int v7; // [esp+124h] [ebp-120h] BYREF
int v8; // [esp+128h] [ebp-11Ch]
int v9; // [esp+12Ch] [ebp-118h]
int v10; // [esp+130h] [ebp-114h]
char v11[260]; // [esp+13Ch] [ebp-108h] BYREF
int savedregs; // [esp+244h] [ebp+0h] BYREF
sub_4114D8(&unk_4250F3);
v11[0] = -7;
v11[1] = 77;
v11[2] = 43;
v11[3] = -68;
v11[4] = 19;
v11[5] = -35;
v11[6] = 19;
v11[7] = 98;
v11[8] = -55;
v11[9] = -4;
v11[10] = -1;
v11[11] = -119;
v11[12] = 125;
v11[13] = 79;
v11[14] = -55;
v11[15] = 15;
v11[16] = 99;
v11[17] = 29;
v11[18] = 109;
v11[19] = 82;
v11[20] = 80;
v11[21] = -3;
v11[22] = 65;
v11[23] = -29;
v11[24] = 51;
v11[25] = 118;
v11[26] = 40;
v11[27] = -105;
v11[28] = 56;
v11[29] = 54;
v11[30] = -7;
v11[31] = 107;
v11[32] = -112;
v11[33] = 57;
v11[34] = 20;
v11[35] = -125;
v11[36] = 44;
v11[37] = -30;
v11[38] = 44;
v11[39] = 31;
memset(&v11[40], 0, 216);
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
if ( j_strlen(Str) == 40 )
{
v6 = Str + 4;
v7 = *Str;
v8 = *(Str + 1);
sub_411541(&v7, &unk_422100);
*Str = v7;
*(Str + 1) = v8;
for ( i = 2; i < j_strlen(Str) >> 2; i += 2 )
{
sub_411541(&v7, &unk_422100);
*Str = v7;
*v6 = v8;
*&Str[4 * i] ^= *Str;
*&Str[4 * i + 4] ^= *v6;
}
for ( j = 0; j < 40; ++j )
{
HIDWORD(v1) = j;
if ( Str[j] != v11[j] )
{
LODWORD(v1) = 1;
goto LABEL_12;
}
}
LODWORD(v1) = 0;
}
else
{
LODWORD(v1) = 1;
}
LABEL_12:
v3 = v1;
sub_41130C(&savedregs, &unk_41D5CC);
return v3;
}
int __cdecl sub_41D6F0(unsigned int *a1, _DWORD *a2)
{
int result; // eax
unsigned int i; // [esp+DCh] [ebp-2Ch]
int v4; // [esp+E8h] [ebp-20h]
unsigned int v5; // [esp+F4h] [ebp-14h]
unsigned int v6; // [esp+100h] [ebp-8h]
sub_4114D8(&unk_4250F3);
v6 = *a1;
v5 = a1[1];
v4 = 0;
for ( i = 0; i < 0x10; ++i )
{
v6 += (a2[1] + (v5 >> 5)) ^ (v4 + v5) ^ (*a2 + 16 * v5);
v5 += (a2[3] + (v6 >> 5)) ^ (v4 + v6) ^ (a2[2] + 16 * v6);
v4 -= 1640531527;
}
*a1 = v6;
result = 4;
a1[1] = v5;
return result;
}
很明显,我们看见了tea加密
首先先把这个tea加密给完成了
经典的tea加密,没有很改
void __cdecl dec(unsigned int* a1, unsigned int* a2,int rounds, unsigned long int delta)
{
unsigned int i;
int sum;
unsigned int v4;
unsigned int v5;
v5 = *a1;
v4 = a1[1];
sum = 0;
for (i = 0; i < rounds; ++i)
{
sum -= delta;
}
for (i = 0; i < rounds; ++i)
{
sum += delta;
v4 -= (a2[3] + (v5 >> 5)) ^ (sum + v5) ^ (a2[2] + 16 * v5);
v5 -= (a2[1] + (v4 >> 5)) ^ (sum + v4) ^ (*a2 + 16 * v4);
}
*a1 = v5;
a1[1] = v4;
}
然后我们跳回去
V11是我们的密文了
记得程序要运行到这里啊
不然数据都是错的
0xBC2B4DF9, 0x6213DD13, 0x89FFFCC9, 0x0FC94F7D, 0x526D1D63, 0xE341FD50, 0x97287633, 0x6BF93638, 0x83143990, 0x1F2CE22C
先tea,在异或,异或的是
我们输入的密文的第一个和第二个
然后tea解密
最后tea了一次!
理一下
程序先开始tea一下(只tea了开头)
然后循环再tea开头,再异或
最后对比
密文结果就是前面看见的那个数据段!
int main(void) {
int rounds=16;
unsigned long long int delta= 0x61C88647;
unsigned int last[10] = {
0xBC2B4DF9, 0x6213DD13, 0x89FFFCC9, 0x0FC94F7D, 0x526D1D63, 0xE341FD50, 0x97287633, 0x6BF93638,
0x83143990, 0x1F2CE22C
};
unsigned int key[4] = {
0x12345678, 0x09101112, 0x13141516, 0x15161718
};
for (int i = 8; i > 0; i -= 2)
{
last[i] ^= last[0];
last[i + 1] ^= last[1];
dec(last, key,rounds,delta);
}
dec(last, key,rounds,delta);
cout << (char*)last;
}
需要好好学习的一道题!