> 文章列表 > GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck

GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck

GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck

Check_Your_Luck

下载文件是cpp
GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck
是个解方程的题,用python的z3

from z3 import *
v,w,x,y,z=BitVecs('v w x y z',16)l=Solver()
l.add(v * 23 + w * -32 + x * 98 + y * 55 + z * 90 == 333322)
l.add(v * 123 + w * -322 + x * 68 + y * 67 + z * 32 == 707724)
l.add(v * 266 + w * -34 + x * 43 + y * 8 + z * 32 == 1272529)
l.add(v * 343 + w * -352 + x * 58 + y * 65 + z * 5 == 1672457)
l.add(v * 231 + w * -321 + x * 938 + y * 555 + z * 970 == 3372367)
if l.check() == sat:print(l.model())
else:print ('Error')
#[y = 1754, z = 777, x = 677, w = 123, v = 4544]

GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck

Tea

打开可执行文件有输出,直接打开ida
shift+F12点进去
GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck
GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck
他提示你,这是假的flag,看看哪个函数引用了它,往上追,就来到了关键的地方

__int64 sub_140016230()
{char *v0; // rdi__int64 i; // rcxchar v3[32]; // [rsp+0h] [rbp-20h] BYREFchar v4; // [rsp+20h] [rbp+0h] BYREFint v5; // [rsp+24h] [rbp+4h]int v6; // [rsp+44h] [rbp+24h]int v7[12]; // [rsp+68h] [rbp+48h] BYREF_DWORD v8[16]; // [rsp+98h] [rbp+78h] BYREFint v9[31]; // [rsp+D8h] [rbp+B8h] BYREFint j; // [rsp+154h] [rbp+134h]int k; // [rsp+174h] [rbp+154h]int m; // [rsp+194h] [rbp+174h]v0 = &v4;for ( i = 102i64; i; --i ){*(_DWORD *)v0 = -858993460;v0 += 4;}sub_14001137F(&unk_140023009);v5 = 32;v6 = 0;v7[0] = 1234;v7[1] = 5678;v7[2] = 9012;v7[3] = 3456;memset(v8, 0, 0x28ui64);v9[15] = 0;v9[23] = 0;sub_1400113E8();for ( j = 0; j < 10; ++j )sub_1400111FE("%x", &v8[j]);sub_140011339(v7);sub_140011145(v8, v9);sub_1400112B7(v8, v7);v6 = sub_140011352(v8);if ( v6 ){printf("you are right\\n");for ( k = 0; k < 10; ++k ){for ( m = 3; m >= 0; --m )printf("%c", (unsigned __int8)((unsigned int)v9[k] >> (8 * m)));}}else{printf("fault!\\nYou can go online and learn the tea algorithm!");}sub_140011311(v3, &unk_14001AE90);return 0i64;
}

最后一句话提醒了我们这是tea加密
最后v9输出flag。
v6 = sub_140011352(v8);
进去发现是一个返回值为bool类型的函数
GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck
说明了形参a1等于v8
由此我们知道了tea加密后的v8的值
sub_1400112B7(v8, v7);
进入这个函数,就是魔改版的茶加密,在解密前,我们还要知道v7
的值。
sub_140011339(v7);
进入这个函数,直接对v7进行赋值。
GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck
然后我们再解密,我们首先把加密改成c语言形式

for (int i = 0; i <= 8; ++i ){v5 = 0;v6 = 256256256 * i;v3 = i + 1;do{++v5;v8[i] += v6 ^ (v8[v3]+ ((v8[v3] >> 5) ^ (16 * v8[v3]))) ^ (v6 + v7[v6&3]);v8[v3] += (v6 + v7[(v6>>11)&3]) ^ (v8[i]+ ((v8[i] >> 5) ^ (16 * v8[i])));v6 += 256256256;}while ( v5 <= 0x20 );}

之后再逆向写,为了检验正确性,自己可以赋值一组数,然后互相解密,看看结果对不对

#include <bits/stdc++.h>using namespace std;
int sub_140011339(int *a1)
{int v6;int v7;int v8;int v9;v6 = 2233;v7 = 4455;v8 = 6677;v9 = 8899;*a1 = 2233;*(a1+1) = v7;*(a1+2) = v8;*(a1+3) = v9;return 0;
}
int main()
{int v7[12];unsigned int v8[15];int v5,v6,v3;v7[0] = 1234;v7[1] = 5678;v7[2] = 9012;v7[3] = 3456;sub_140011339(v7);//cout<<v7[3]<<endl;v8[0] = 444599258;v8[1] = 4154859931;v8[2] = 1226314200;v8[3] = 4060164904;v8[4] = 359413339;v8[5] = 1013885656;v8[6] = -2066432216;v8[7] = -249921817;v8[8] = 856928850;v8[9] = 3718242937;for (int  i = 8; i >= 0; --i ){v5 = 0;v6 = 0xF462900 * i;v3 = i + 1;v6=v6+(33*0xF462900);do{v6-=0xF462900;v8[v3]-=(v6+v7[(v6>>11)&3])^(v8[i]+((v8[i]>>5)^(16 * v8[i])));v8[i]-=v6^(v8[v3]+((v8[v3]>>5)^(16*v8[v3])))^(v6+v7[v6&3]);++v5;}while ( v5 <= 0x20 );}/*for(int j=0;j<10;j++)cout<<v8[j]<<endl;*/for (int k = 0; k < 10; ++k ){for (int m = 3; m >= 0; --m )printf("%c",(v8[k] >> (8 * m)));}return 0;
}

要注意不能把v8定义成int类型,要定义成unsigned int类型