当前位置: 首页 > news >正文

攻防世界 reverse题GFSJ0810-【crazy】

1.工具:exeinfope、IDA Pro (64-bit)、thonny

2.解题:

下载附件后,我们先在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]; // [rsp+10h] [rbp-130h] BYREF char v19[32]; // [rsp+30h] [rbp-110h] BYREF char v20[32]; // [rsp+50h] [rbp-F0h] BYREF char v21[32]; // [rsp+70h] [rbp-D0h] BYREF char v22[32]; // [rsp+90h] [rbp-B0h] BYREF char v23[120]; // [rsp+B0h] [rbp-90h] BYREF unsigned __int64 v24; // [rsp+128h] [rbp-18h] v24 = __readfsqword(0x28u); std::string::basic_string(v18, argv, envp); std::operator>><char>(&std::cin, v18); v3 = std::operator<<<std::char_traits<char>>(&std::cout, "-------------------------------------------"); std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>); v4 = std::operator<<<std::char_traits<char>>(&std::cout, "Quote from people's champ"); std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>); v5 = std::operator<<<std::char_traits<char>>(&std::cout, "-------------------------------------------"); std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>); v6 = std::operator<<<std::char_traits<char>>( &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::endl<char,std::char_traits<char>>); v7 = std::operator<<<std::char_traits<char>>(&std::cout, "*Wrestling was like stand-up comedy for me."); std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>); v8 = std::operator<<<std::char_traits<char>>( &std::cout, "*I like to use the hard times in the past to motivate me today."); std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>); v9 = std::operator<<<std::char_traits<char>>(&std::cout, "-------------------------------------------"); std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>); HighTemplar::HighTemplar((DarkTemplar *)v23, (__int64)v18); v10 = std::operator<<<std::char_traits<char>>(&std::cout, "Checking...."); std::ostream::operator<<(v10, &std::endl<char,std::char_traits<char>>); 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::operator<<<std::char_traits<char>>(&std::cout, "/////////////////////////////////"); std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>); v12 = std::operator<<<std::char_traits<char>>(&std::cout, "Do not be angry. Happy Hacking :)"); std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>); v13 = std::operator<<<std::char_traits<char>>(&std::cout, "/////////////////////////////////"); std::ostream::operator<<(v13, &std::endl<char,std::char_traits<char>>); HighTemplar::getFlag[abi:cxx11]((__int64)v22, (__int64)v23); v14 = std::operator<<<std::char_traits<char>>(&std::cout, "flag{"); v15 = std::operator<<<char>(v14, v22); v16 = std::operator<<<std::char_traits<char>>(v15, "}"); std::ostream::operator<<(v16, &std::endl<char,std::char_traits<char>>); 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);

然后我们双击就可以看到这些函数,如下

(1)a. 46行:HighTemplar::HighTemplar((DarkTemplar *)v23, (__int64)v18);

unsigned __int64 __fastcall HighTemplar::HighTemplar(DarkTemplar *a1, __int64 a2) { char v3; // [rsp+17h] [rbp-19h] BYREF unsigned __int64 v4; // [rsp+18h] [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::allocator<char>::allocator(&v3); std::string::basic_string((char *)a1 + 80, "327a6c4304ad5938eaf0efb6cc3e53dc", &v3); std::allocator<char>::~allocator(&v3); return __readfsqword(0x28u) ^ v4; }

我们分析发现主要是输入和存储数据的,我们要尤其注意存储的数据:327a6c4304ad5938eaf0efb6cc3e53dc,可能后期进行加密处理

(2)b.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; // [rsp+18h] [rbp-18h] int j; // [rsp+1Ch] [rbp-14h] if ( std::string::length((char *)this + 16) != 32 ) { v1 = std::operator<<<std::char_traits<char>>(&std::cout, "Too short or too long"); std::ostream::operator<<(v1, &std::endl<char,std::char_traits<char>>); 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在加23;

b.倒数第四行:先异或0x13在加11;

即解密就是先减11再异或0x13然后再减23再异或0x50

(3)c.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; // [rsp+1Ch] [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::operator<<<std::char_traits<char>>(&std::cout, "You did not pass "); v5 = std::ostream::operator<<(v4, i); std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>); *((_DWORD *)this + 3) = 1; return *((unsigned int *)this + 3); } v2 = std::operator<<<std::char_traits<char>>(&std::cout, "Pass "); v3 = std::ostream::operator<<(v2, i); std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>); } return *((unsigned int *)this + 3); }

我们分析发现这个是进行验证的,验证flag是否正确,这是我们基本确定了加密就是上面一步,但我们还是看一下第四个函数

(4)d.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里编写解密脚本,如下

temp='327a6c4304ad5938eaf0efb6cc3e53dc' flag='' for i in range(len(temp)): n=ord(temp[i]) flag+=chr((((n-11)^0x13)-23)^0x50) print('flag{'+flag+'}')

然后我们得到flag为flag{tMx~qdstOs~crvtwb~aOba}qddtbrtcd}

http://www.jsqmd.com/news/550307/

相关文章:

  • 语法崩坏!union 乱接底层宏,我写出了编译器看了沉默的缝合代码
  • 2026论文写作工具红黑榜:AI论文写作工具怎么选?这份榜单够用!
  • Vivado综合策略的‘隐藏菜单’:手把手教你用TCL定制专属策略,榨干UltraScale+性能
  • tchMaterial-parser:高效解析国家中小学智慧教育平台电子课本的技术实现
  • MedGemma-X真实效果展示:同一张胸片不同临床问题的智能响应对比
  • 泓信皮革:广东多品类皮革供应商,深耕佛山等地 - 十大品牌榜
  • 记忆系统优化:从记录到智能检索
  • 2026年石油树脂厂家权威推荐:碳五石油树脂/碳九石油树脂/氢化石油树脂/C5/C9/DCPD加氢石油树脂专业供应商精选 - 品牌推荐官
  • 大型船舶环境模拟实验室:在陆地上“复刻”七海风云的超级船坞
  • 别让那个黄色警告烦你!Vivado自定义AXI IP时钟参数FREQ_HZ缺失的三种解决思路
  • OptiScaler终极指南:让所有显卡都能享受AI超分辨率技术
  • 医用擦拭纸选购指南:看懂这五大认证,避开医疗耗材采购“隐形坑
  • 路径规划算法入门
  • OptiScaler:打破显卡壁垒,让所有玩家都能享受顶级上采样技术
  • VibeVoice目录结构解读:build/modelscope_cache路径作用说明
  • 合肥宝妈 教育博主实测|娃配防近视镜片,这几家闭眼选,附避坑干货 - 品牌测评鉴赏家
  • AI家电热背后:理性审视消费决策
  • 扭矩电枪的精度如何选择?
  • 【开源库 | libpng】深入解析 libpng 的 PNG 文件读写机制与实战技巧
  • 2026年3月比较好的铜狮子铸造厂推荐,这几家值得关注!铜缸/铜鼎/铜佛像/铜雕/铜牛/人物雕塑,铜狮子厂家怎么选择 - 品牌推荐师
  • 龙芯2k0300 - 久久派开发环境搭建及内核升级(下)
  • DeepSeek与通义千问:代码生成实战中的效率瓶颈与优化路径深度解析
  • Xshell7/Xftp7免费版 vs 商业版功能对比:个人用户如何合法使用正版不踩坑?
  • Matlab/Simulink 搭建两级式光伏并网系统仿真
  • 体积极小、动画拉满!LVGL 凭什么成为全球嵌入式开发者首选?
  • Tomcat服务详解:从基础到实战的全面指南
  • 从 Hello World Plug-In 看透 SAP Fiori Launchpad 插件机制与实现
  • FastAPI 2.0异步AI服务上线前必须通过的4道生死关卡:流式超时、客户端断连恢复、token级中断、可观测性埋点(附Prometheus+Grafana看板)
  • 保姆级教程:手把手教你下载、解压与解析ILSVRC2015_VID数据集(附Python脚本)
  • 北大等七大机构联手打造:让AI真正学会“看懂世界“的超级测试题