BUUCTF--[V&N2020 公开赛]strangeCpp
Posted mayfly-nymph
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BUUCTF--[V&N2020 公开赛]strangeCpp相关的知识,希望对你有一定的参考价值。
测试文件:https://www.lanzous.com/iauqjsd
代码分析
先找到程序运行显示处的代码
1 // 个数,数组,环境变量 2 __int64 __fastcall sub_140013AA0(__int64 a1, __int64 a2, __int64 *a3) 3 { 4 char *v3; // rdi 5 signed __int64 i; // rcx 6 __int64 v5; // rax 7 __int64 v6; // rax 8 __int64 v7; // rax 9 __int64 v8; // rax 10 char v10; // [rsp+0h] [rbp-20h] 11 struct _SYSTEM_INFO SystemInfo; // [rsp+28h] [rbp+8h] 12 __int64 *j; // [rsp+78h] [rbp+58h] 13 __int64 v13; // [rsp+98h] [rbp+78h] 14 __int64 *v14; // [rsp+1A0h] [rbp+180h] 15 16 v14 = a3; 17 v3 = &v10; 18 for ( i = 94i64; i; --i ) 19 { 20 *(_DWORD *)v3 = 3435973836; 21 v3 += 4; 22 } 23 sub_1400110AA((__int64)&unk_140027033); 24 GetSystemInfo(&SystemInfo); 25 putchar(byte_140021004); // w 26 putchar(byte_140021005); // e 27 putchar(byte_140021006); // l 28 putchar(byte_140021007); // c 29 putchar(byte_140021019); // o 30 putchar(byte_14002101A); // m 31 putchar(byte_140021005); // e 32 putchar(10); 33 puts("Let me have a look at your computer..."); 34 for ( j = v14; *j; ++j ) // 循环输出环境变量 35 { 36 v13 = *j; 37 sub_140011226("%s ", v13); 38 } 39 std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127); 40 dword_140021190 = SystemInfo.dwNumberOfProcessors;// CPU数量 41 sub_140011226("now system cpu num is %d ", SystemInfo.dwNumberOfProcessors); 42 if ( dword_140021190 < 8 ) 43 { 44 puts("Are you in VM?"); 45 _exit(0); 46 } 47 if ( GetUserNameA(Str1, &pcbBuffer) ) // 获取用户名 48 { 49 v5 = sub_140011172(std::cout, (__int64)"this is useful"); 50 std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, sub_140011127); 51 } 52 v6 = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127); 53 v7 = sub_140011172(v6, (__int64)"ok,I am checking..."); 54 std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_140011127); 55 if ( !j_strcmp(Str1, "cxx") ) 56 { 57 v8 = sub_140011172(std::cout, (__int64)"flag{where_is_my_true_flag?}"); 58 std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, sub_140011127); 59 _exit(0); 60 } 61 system("pause"); 62 sub_1400113E3((__int64)&v10, (__int64)&unk_14001DE50); 63 return 0i64; 64 }
在我查看第21~25行代码,输出字符串处时
中间插了一个byte_140021008变量,找到引用处
1 __int64 sub_140013580() 2 { 3 __int64 *v0; // rdi 4 signed __int64 i; // rcx 5 __int64 result; // rax 6 __int64 v3; // [rsp+0h] [rbp-20h] 7 int v4; // [rsp+24h] [rbp+4h] 8 int j; // [rsp+44h] [rbp+24h] 9 __int64 v6; // [rsp+128h] [rbp+108h] 10 11 v0 = &v3; 12 for ( i = 82i64; i; --i ) 13 { 14 *(_DWORD *)v0 = -858993460; 15 v0 = (__int64 *)((char *)v0 + 4); 16 } 17 v6 = -2i64; 18 sub_1400110AA((__int64)&unk_140027033); 19 result = sub_140011384((unsigned int)dword_140021190); 20 v4 = result; 21 if ( (_DWORD)result == 607052314 && dword_140021190 <= 14549743 ) 22 { 23 for ( j = 0; j < 17; ++j ) 24 { 25 putchar((unsigned __int8)(dword_140021190 ^ byte_140021008[j])); 26 result = (unsigned int)(j + 1); 27 } 28 } 29 return result; 30 }
我们首先需要看到第19行代码,进入sub_140011384函数(dword_140021190实际就是我们第一处代码的CPU数量,变量的值可以通过下面if条件,暴力解出值)。
1 signed __int64 __fastcall sub_140013890(int a1) 2 { 3 __int64 *v1; // rdi 4 signed __int64 i; // rcx 5 signed __int64 result; // rax 6 __int64 v4; // [rsp+0h] [rbp-20h] 7 int v5; // [rsp+24h] [rbp+4h] 8 int v6; // [rsp+44h] [rbp+24h] 9 unsigned int v7; // [rsp+64h] [rbp+44h] 10 int v8; // [rsp+160h] [rbp+140h] 11 12 v8 = a1; 13 v1 = &v4; 14 for ( i = 82i64; i; --i ) 15 { 16 *(_DWORD *)v1 = -858993460; 17 v1 = (__int64 *)((char *)v1 + 4); 18 } 19 sub_1400110AA((__int64)&unk_140027033); 20 v5 = v8 >> 12; 21 v6 = v8 << 8; 22 v7 = (v8 << 8) ^ (v8 >> 12); 23 v7 *= 291; 24 if ( v7 ) 25 result = v7; 26 else 27 result = 987i64; 28 return result; 29 }
通过这段代码的第22,23行和上段代码的第25行,我们可以解出flag
脚本
# -*- coding:utf-8 -*- import hashlib result = 0 for v8 in range(14549743): v7 = (((v8 << 8) ^ (v8 >> 12))*291)&0xFFFFFFFF # 原文是unsigned int--0~0xFFFFFFFF,输出的值需要截断 if (v7 == 607052314): result = v8 break enc = [0x26, 0x2C, 0x21, 0x27, 0x3B, 0x0D, 4, 0x75, 0x68, 0x34, 0x28, 0x25, 0x0E, 0x35, 0x2D, 0x69, 0x3D] flag = "" for i in enc: flag += chr((result ^ i)&0xFF) # unsigned __int8--0~0xFF print (flag) md = hashlib.md5() md.update(str(result).encode(‘utf-8‘)) print ("flag{"+md.hexdigest()+"}")
get flag!
flag{e10adc3949ba59abbe56e057f20f883e}
以上是关于BUUCTF--[V&N2020 公开赛]strangeCpp的主要内容,如果未能解决你的问题,请参考以下文章