2022DASCTF X SU 三月春季挑战赛 easyre
2022/4/30 6:12:52
本文主要是介绍2022DASCTF X SU 三月春季挑战赛 easyre,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
2022DASCTF X SU 三月春季挑战赛 easyre
前奏
查壳
查壳,asp壳
,esp定律脱之,修复可以看我的上一篇文章
main函数
main函数的反汇编代码
int __cdecl main(int argc, const char **argv, const char **envp) { unsigned __int8 Dest[50]; // [esp+1Ch] [ebp-74h] BYREF char Str[50]; // [esp+4Eh] [ebp-42h] BYREF __time32_t Time; // [esp+80h] [ebp-10h] BYREF int v7; // [esp+84h] [ebp-Ch] int v8; // [esp+88h] [ebp-8h] struct tm *v9; // [esp+8Ch] [ebp-4h] sub_40DCF0(); time(&Time); v9 = gmtime(&Time); sub_47C7D0((int)&dword_487F00, Str); if ( strlen(Str) != 42 ) { sub_47BAB0((int)&dword_488140, aWrong); exit(0); } if ( Str[0] != 'D' || Str[1] != 'A' || Str[2] != 'S' || Str[3] != 'C' || Str[4] != 'T' || Str[5] != 'F' ) { sub_47BAB0((int)&dword_488140, aWrong); exit(0); } mbscpy(Dest, (const unsigned __int8 *)Str); v8 = v9->tm_year + 1900; v7 = 0; sub_4019BE(Str); sub_401771((char *)Dest); system(Command); return 0; }
Str
是我们的输入
sub_47BAB0
是printf
sub_47C7D0
是scanf
修复后的代码
int __cdecl main(int argc, const char **argv, const char **envp) { unsigned __int8 Dest[50]; // [esp+1Ch] [ebp-74h] BYREF char Str[50]; // [esp+4Eh] [ebp-42h] BYREF __time32_t Time; // [esp+80h] [ebp-10h] BYREF int v7; // [esp+84h] [ebp-Ch] int v8; // [esp+88h] [ebp-8h] struct tm *v9; // [esp+8Ch] [ebp-4h] sub_40DCF0(); time(&Time); v9 = gmtime(&Time); scanf(&dword_487F00, Str); if ( strlen(Str) != 42 ) { printf_0(&dword_488140, aWrong); exit(0); } if ( Str[0] != 'D' || Str[1] != 'A' || Str[2] != 'S' || Str[3] != 'C' || Str[4] != 'T' || Str[5] != 'F' ) { printf_0(&dword_488140, aWrong); exit(0); } mbscpy(Dest, Str); v8 = v9->tm_year + 1900; v7 = 0; sub_4019BE(Str); sub_401771(Dest); system(Command); return 0; }
可以分析得出,我们输入的内容需要首先满足Str[0] != 'D' || Str[1] != 'A' || Str[2] != 'S' || Str[3] != 'C' || Str[4] != 'T' || Str[5] != 'F'
和= 42
这两个条件
所以可以我们可以构造如下的满足条件的输入
DASCTFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
然后根据代码,程序会进入下面两个函数
sub_4019BE(Str); sub_401771(Dest);
sub_4019BE(Str)
代码
size_t __cdecl sub_4019BE(char *Str) { size_t result; // eax char v2[84]; // [esp+1Ch] [ebp-7Ch] BYREF char *v3; // [esp+70h] [ebp-28h] size_t Size; // [esp+74h] [ebp-24h] int v5; // [esp+78h] [ebp-20h] int v6; // [esp+7Ch] [ebp-1Ch] int v7; // [esp+84h] [ebp-14h] size_t v8; // [esp+88h] [ebp-10h] int i; // [esp+8Ch] [ebp-Ch] strcpy(&v2[59], "26St9k3bNYWAadAhJJjDCRVx"); v5 = 0; v6 = 0; Size = 138 * strlen(Str) / 0x64 + 1; strcpy(v2, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); v3 = malloc(Size); v8 = 0; memset(v3, 0, Size); while ( v8 < strlen(Str) ) { v7 = Str[v8]; for ( i = Size - 1; ; --i ) { v7 += v3[i] << 8; v3[i] = v7 % 58; v7 /= 58; if ( !v7 ) break; } for ( i = 0; !v3[i]; ++i ) ; ++v8; } for ( i = 0; !v3[i]; ++i ) ; while ( 1 ) { result = Size - 1; if ( (Size - 1) < i ) break; Str[i] = v2[v3[i]]; ++i; } return result; }
根据strcpy(v2, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
这一段,可以发现是base58
对strcpy(&v2[59], "26St9k3bNYWAadAhJJjDCRVx");
中的v2进行解码,可以发现是个fake flag
那就不管他,看sub_401771(Dest);
sub_401771(Dest)
代码
int __cdecl sub_401771(char *Str) { int v2[50]; // [esp+1Ch] [ebp-DCh] BYREF int v3; // [esp+E4h] [ebp-14h] int j; // [esp+E8h] [ebp-10h] int i; // [esp+ECh] [ebp-Ch] v3 = strlen(Str); sub_401500(); sub_40152B(); sub_401593(); sub_401619(Str, v3); for ( i = 0; i < v3; ++i ) byte_492A60[i] = (LOBYTE(dword_492940[i]) ^ Str[i]) + 71; memset(v2, 0, sizeof(v2)); v2[0] = -61; v2[1] = -128; v2[2] = -43; v2[3] = -14; v2[4] = -101; v2[5] = 48; v2[6] = 11; v2[7] = -76; v2[8] = 85; v2[9] = -34; v2[10] = 34; v2[11] = -125; v2[12] = 47; v2[13] = -105; v2[14] = -72; v2[15] = 32; v2[16] = 29; v2[17] = 116; v2[18] = -47; v2[19] = 1; v2[20] = 115; v2[21] = 26; v2[22] = -78; v2[23] = -56; v2[24] = -59; v2[25] = 116; v2[26] = -64; v2[27] = 91; v2[28] = -9; v2[29] = 15; v2[30] = -45; v2[31] = 1; v2[32] = 85; v2[33] = -78; v2[34] = -92; v2[35] = -82; v2[36] = 123; v2[37] = -84; v2[38] = 92; v2[39] = 86; v2[40] = -68; v2[41] = 35; for ( j = 0; j <= 41; ++j ) { if ( v2[j] != byte_492A60[j] ) exit(0); } return printf_0(&dword_488140, aRight); }
根据最后的
if ( v2[j] != byte_492A60[j] ) exit(0);
这个代码,倒推需要我们input的flag
可以知道需要我们输入的flag的验证逻辑是
flag = (byte_492A60[j]-71)^LOBYTE(dword_492940[i])
根据byte_492A60[i] = (LOBYTE(dword_492940[i]) ^ Str[i]) + 71;
这段代码,可以知道我们需要LOBYTE(dword_492940[i])
的数值
这里我直接使用了动态分析(静态分析太麻烦)
动态调试
先输入我们上一把得到的过第一层校验的字符串DASCTFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
程序此时已经断在了我们需要的地方
此时我们就可以去拿dword_492940
的值了
以BYTE的格式(因为前文有提示说是BYTE)
unsigned char dword_492940[171] = { 0x38, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, 0xD2, 0xFF, 0xFF, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0xC9, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
因为LOBYTE(dword_492940[i])
的要求,所以我们需要低字节
#include<stdio.h> int main(){ unsigned char dword_492940[171] = { 0x38, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, 0xD2, 0xFF, 0xFF, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0xC9, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xA1 }; for(int i = 0;i < 171;i=i+4){ printf("%d,",dword_492940[i]); } }
输出
56,120,221,232,0,175,191,58,107,251,184,12,133,53,92,173,230,0,224,138,29,189,70,210,43,0,21,36,198,173,161,201,123,18,40,0,5,0,114,62,16,161,0
我们现在已知byte_492A60
和LOBYTE(dword_492940[])
再加上flag的逻辑是
flag = (byte_492A60[i]-71)^LOBYTE(dword_492940[i])
接下来就可以写逆向脚本了
#include<stdio.h> int main(){ int v1[43] = {56,120,221,232,0,175,191,58,107,251,184,12,133,53,92,173,230,0,224,138,29,189,70,210,43,0,21,36,198,173,161,201,123,18,40,0,5,0,114,62,16,161,43,0}; int v2[41]; v2[0] = -61; v2[1] = -128; v2[2] = -43; v2[3] = -14; v2[4] = -101; v2[5] = 48; v2[6] = 11; v2[7] = -76; v2[8] = 85; v2[9] = -34; v2[10] = 34; v2[11] = -125; v2[12] = 47; v2[13] = -105; v2[14] = -72; v2[15] = 32; v2[16] = 29; v2[17] = 116; v2[18] = -47; v2[19] = 1; v2[20] = 115; v2[21] = 26; v2[22] = -78; v2[23] = -56; v2[24] = -59; v2[25] = 116; v2[26] = -64; v2[27] = 91; v2[28] = -9; v2[29] = 15; v2[30] = -45; v2[31] = 1; v2[32] = 85; v2[33] = -78; v2[34] = -92; v2[35] = -82; v2[36] = 123; v2[37] = -84; v2[38] = 92; v2[39] = 86; v2[40] = -68; v2[41] = 35; char flag[42]; for (int i =0;i <43 ;i++) { flag[i] = (v2[i]-71)^v1[i]; printf("%c",flag[i]); } }
DASCTF{Welc0me-t0-j01n-SU-l0ve-suyug1eg1e}
这篇关于2022DASCTF X SU 三月春季挑战赛 easyre的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-29uni-app 中使用 Vant Weapp,怎么安装和配置npm ?-icode9专业技术文章分享
- 2024-12-27Nacos多环境配置学习入门
- 2024-12-27Nacos快速入门学习入门
- 2024-12-27Nacos快速入门学习入门
- 2024-12-27Nacos配置中心学习入门指南
- 2024-12-27Nacos配置中心学习入门
- 2024-12-27Nacos做项目隔离学习入门
- 2024-12-27Nacos做项目隔离学习入门
- 2024-12-27Nacos初识学习入门:轻松掌握服务发现与配置管理
- 2024-12-27Nacos初识学习入门:轻松掌握Nacos基础操作