攻防世界 reverse题GFSJ0810-【crazy】
1.工具exeinfope、IDA Pro (64-bit)、thonny2.解题下载附件后我们先在exeinfope里查壳如下我们发现是64位无壳文件然后我们把它放到IDA Pro (64-bit)里分析我们点击F5先查看伪代码如下代码int __fastcall main(int argc, const char **argv, const char **envp) { __int64 v3; // rax __int64 v4; // rax __int64 v5; // rax __int64 v6; // rax __int64 v7; // rax __int64 v8; // rax __int64 v9; // rax __int64 v10; // rax __int64 v11; // rax __int64 v12; // rax __int64 v13; // rax __int64 v14; // rax __int64 v15; // rax __int64 v16; // rax char v18[32]; // [rsp10h] [rbp-130h] BYREF char v19[32]; // [rsp30h] [rbp-110h] BYREF char v20[32]; // [rsp50h] [rbp-F0h] BYREF char v21[32]; // [rsp70h] [rbp-D0h] BYREF char v22[32]; // [rsp90h] [rbp-B0h] BYREF char v23[120]; // [rspB0h] [rbp-90h] BYREF unsigned __int64 v24; // [rsp128h] [rbp-18h] v24 __readfsqword(0x28u); std::string::basic_string(v18, argv, envp); std::operatorchar(std::cin, v18); v3 std::operatorstd::char_traitschar(std::cout, -------------------------------------------); std::ostream::operator(v3, std::endlchar,std::char_traitschar); v4 std::operatorstd::char_traitschar(std::cout, Quote from peoples champ); std::ostream::operator(v4, std::endlchar,std::char_traitschar); v5 std::operatorstd::char_traitschar(std::cout, -------------------------------------------); std::ostream::operator(v5, std::endlchar,std::char_traitschar); v6 std::operatorstd::char_traitschar( std::cout, *My goal was never to be the loudest or the craziest. It was to be the most entertaining.); std::ostream::operator(v6, std::endlchar,std::char_traitschar); v7 std::operatorstd::char_traitschar(std::cout, *Wrestling was like stand-up comedy for me.); std::ostream::operator(v7, std::endlchar,std::char_traitschar); v8 std::operatorstd::char_traitschar( std::cout, *I like to use the hard times in the past to motivate me today.); std::ostream::operator(v8, std::endlchar,std::char_traitschar); v9 std::operatorstd::char_traitschar(std::cout, -------------------------------------------); std::ostream::operator(v9, std::endlchar,std::char_traitschar); HighTemplar::HighTemplar((DarkTemplar *)v23, (__int64)v18); v10 std::operatorstd::char_traitschar(std::cout, Checking....); std::ostream::operator(v10, std::endlchar,std::char_traitschar); std::string::basic_string(v19, v18); func1(v20, v19); func2(v21, v20); func3(v21, 0LL); std::string::~string(v21); std::string::~string(v20); std::string::~string(v19); HighTemplar::calculate((HighTemplar *)v23); if ( !(unsigned int)HighTemplar::getSerial((HighTemplar *)v23) ) { v11 std::operatorstd::char_traitschar(std::cout, /////////////////////////////////); std::ostream::operator(v11, std::endlchar,std::char_traitschar); v12 std::operatorstd::char_traitschar(std::cout, Do not be angry. Happy Hacking :)); std::ostream::operator(v12, std::endlchar,std::char_traitschar); v13 std::operatorstd::char_traitschar(std::cout, /////////////////////////////////); std::ostream::operator(v13, std::endlchar,std::char_traitschar); HighTemplar::getFlag[abi:cxx11]((__int64)v22, (__int64)v23); v14 std::operatorstd::char_traitschar(std::cout, flag{); v15 std::operatorchar(v14, v22); v16 std::operatorstd::char_traitschar(v15, }); std::ostream::operator(v16, std::endlchar,std::char_traitschar); std::string::~string(v22); } HighTemplar::~HighTemplar((HighTemplar *)v23); std::string::~string(v18); return 0; }然后我们分析①在倒数第十行出现了flag{在倒数第八行出现了}估计中间就是flag的内容②我们仔细看后发现多出出现了HighTemplar相关的函数我们主要来看倒数第8行之前即可如a. 46行HighTemplar::HighTemplar((DarkTemplar *)v23, (__int64)v18);b.56行HighTemplar::calculate((HighTemplar *)v23);c.57行if ( !(unsigned int)HighTemplar::getSerial((HighTemplar *)v23) )d.65行HighTemplar::getFlag[abi:cxx11]((__int64)v22, (__int64)v23);然后我们双击就可以看到这些函数如下1a. 46行HighTemplar::HighTemplar((DarkTemplar *)v23, (__int64)v18);unsigned __int64 __fastcall HighTemplar::HighTemplar(DarkTemplar *a1, __int64 a2) { char v3; // [rsp17h] [rbp-19h] BYREF unsigned __int64 v4; // [rsp18h] [rbp-18h] v4 __readfsqword(0x28u); DarkTemplar::DarkTemplar(a1); *(_QWORD *)a1 off_401EA0; *((_DWORD *)a1 3) 0; std::string::basic_string((char *)a1 16, a2); std::string::basic_string((char *)a1 48, a2); std::allocatorchar::allocator(v3); std::string::basic_string((char *)a1 80, 327a6c4304ad5938eaf0efb6cc3e53dc, v3); std::allocatorchar::~allocator(v3); return __readfsqword(0x28u) ^ v4; }我们分析发现主要是输入和存储数据的我们要尤其注意存储的数据327a6c4304ad5938eaf0efb6cc3e53dc可能后期进行加密处理2b.56行HighTemplar::calculate((HighTemplar *)v23);bool __fastcall HighTemplar::calculate(HighTemplar *this) { __int64 v1; // rax _BYTE *v2; // rbx bool result; // al _BYTE *v4; // rbx int i; // [rsp18h] [rbp-18h] int j; // [rsp1Ch] [rbp-14h] if ( std::string::length((char *)this 16) ! 32 ) { v1 std::operatorstd::char_traitschar(std::cout, Too short or too long); std::ostream::operator(v1, std::endlchar,std::char_traitschar); exit(-1); } for ( i 0; i (unsigned __int64)std::string::length((char *)this 16); i ) { v2 (_BYTE *)std::string::operator[]((char *)this 16, i); *v2 (*(_BYTE *)std::string::operator[]((char *)this 16, i) ^ 0x50) 23; } for ( j 0; ; j ) { result j (unsigned __int64)std::string::length((char *)this 16); if ( !result ) break; v4 (_BYTE *)std::string::operator[]((char *)this 16, j); *v4 (*(_BYTE *)std::string::operator[]((char *)this 16, j) ^ 0x13) 11; } return result; }我们分析发先主要是进行异或运算的在倒数第四、十二行大概率就是根据这个进行解密加密方法a.倒数十二行先异或0x50在加23b.倒数第四行先异或0x13在加11即解密就是先减11再异或0x13然后再减23再异或0x503c.57行if ( !(unsigned int)HighTemplar::getSerial((HighTemplar *)v23) )__int64 __fastcall HighTemplar::getSerial(HighTemplar *this) { char v1; // bl __int64 v2; // rax __int64 v3; // rax __int64 v4; // rax __int64 v5; // rax unsigned int i; // [rsp1Ch] [rbp-14h] for ( i 0; (int)i (unsigned __int64)std::string::length((char *)this 16); i ) { v1 *(_BYTE *)std::string::operator[]((char *)this 80, (int)i); if ( v1 ! *(_BYTE *)std::string::operator[]((char *)this 16, (int)i) ) { v4 std::operatorstd::char_traitschar(std::cout, You did not pass ); v5 std::ostream::operator(v4, i); std::ostream::operator(v5, std::endlchar,std::char_traitschar); *((_DWORD *)this 3) 1; return *((unsigned int *)this 3); } v2 std::operatorstd::char_traitschar(std::cout, Pass ); v3 std::ostream::operator(v2, i); std::ostream::operator(v3, std::endlchar,std::char_traitschar); } return *((unsigned int *)this 3); }我们分析发现这个是进行验证的验证flag是否正确这是我们基本确定了加密就是上面一步但我们还是看一下第四个函数4d.65行HighTemplar::getFlag[abi:cxx11]((__int64)v22, (__int64)v23);__int64 __fastcall HighTemplar::getFlag[abi:cxx11](__int64 a1, __int64 a2) { std::string::basic_string(a1, a2 48); return a1; }我们分析发现就是获取flag最后我们查看完四个函数后知道有用的就是前两个函数根据这个我们在thonny里编写解密脚本如下temp327a6c4304ad5938eaf0efb6cc3e53dc flag for i in range(len(temp)): nord(temp[i]) flagchr((((n-11)^0x13)-23)^0x50) print(flag{flag})然后我们得到flag为flag{tMx~qdstOs~crvtwb~aOba}qddtbrtcd}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2458594.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!