测试文件:https://adworld.xctf.org.cn/media/task/attachments/c5802869b8a24033b4a80783a67c858b

1.准备

获取信息

  1. 64位文件

2.IDA打开

 __int64 __fastcall main(int a1, char **a2, char **a3)
{
char *v3; // rbx
__int64 v4; // rax
__int64 v5; // rdx
__int64 v6; // rax
__int64 v7; // rdx
_BYTE *v8; // rax
__int64 i; // [rsp+10h] [rbp-60h]
char v11; // [rsp+20h] [rbp-50h]
char v12; // [rsp+4Fh] [rbp-21h]
__int64 v13; // [rsp+50h] [rbp-20h]
int v14; // [rsp+5Ch] [rbp-14h] if ( a1 != )
{
v3 = *a2;
v4 = std::operator<<<std::char_traits<char>>(&std::cout, "Usage: ", a3);
v6 = std::operator<<<std::char_traits<char>>(v4, v3, v5);
std::operator<<<std::char_traits<char>>(v6, " flag\n", v7);
exit();
}
std::allocator<char>::allocator(&v12, a2, a3);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v11, a2[], &v12);
std::allocator<char>::~allocator(&v12);
v14 = ;
for ( i = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::begin(&v11); ; sub_400D7A(&i) )
{
v13 = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::end(&v11);
if ( !(unsigned __int8)sub_400D3D(&i, &v13) )
break;
v8 = (_BYTE *)sub_400D9A(&i);
if ( *v8 != off_6020A0[dword_6020C0[v14]] )
sub_400B56();
++v14;
}
sub_400B73();
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v11);
return 0LL;
}

3.代码分析

实际上这堆代码,很大部分“垃圾代码”--不需要我们关注的

我们只需要关注26行代码以下部分即可

第27行代码,是一个for循环,没有结束条件,每次增加sub_400D7A(&i),即1字节

_QWORD *__fastcall sub_400D7A(_QWORD *a1)
{
++*a1;
return a1;
}
  for ( i = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::begin(&v11); ; sub_400D7A(&i) )
{
v13 = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::end(&v11);
if ( !sub_400D3D((__int64)&i, (__int64)&v13) )// 循环结束条件
break;
v8 = (_BYTE *)sub_400D9A((__int64)&i); // 进行某种赋值
if ( *v8 != off_6020A0[dword_6020C0[v14]] ) // 重点!这里实际上就是一个数组套着数组
sub_400B56(&i, &v13);
++v14; // 数组下标
}

3.1条件中找flag

通过对比sub_400B56(&i, &v13);和 sub_400B73(&i, &v13);函数,我们能够得到flag实际藏在if判断条件中

void __fastcall __noreturn sub_400B56(__int64 a1, __int64 a2, __int64 a3)
{
std::operator<<<std::char_traits<char>>(&std::cout, "Better luck next time\n", a3);
exit();
}
__int64 __fastcall sub_400B73(__int64 a1, __int64 a2, __int64 a3)
{
return std::operator<<<std::char_traits<char>>(&std::cout, "You should have the flag by now\n", a3);
}

进入off_6020A0和dword_6020C0我们可以看到

.data:00000000006020A0 off_6020A0      dq offset aL3tMeT3llY0uS0
.data:00000000006020A0 ; DATA XREF: main+D1↑r
.data:00000000006020A0 ; "L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{"...
.data:00000000006020A8 align 20h
.rodata:0000000000400E58 aL3tMeT3llY0uS0 db 'L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t'
.rodata:0000000000400E58 ; DATA XREF: .data:off_6020A0↓o

这实际上就是一段字符串

.data:00000000006020C0 dword_6020C0    dd 24h                  ; DATA XREF: main+DD↑r
.data:00000000006020C4 align
.data:00000000006020C8 db
.data:00000000006020C9 db
.data:00000000006020CA db
.data:00000000006020CB db
.data:00000000006020CC db 36h ;
.data:00000000006020CD db
.data:00000000006020CE db
.data:00000000006020CF db
.data:00000000006020D0 db 65h ; e
.data:00000000006020D1 db
.data:00000000006020D2 db
.data:00000000006020D3 db
.data:00000000006020D4 db
.data:00000000006020D5 db
.data:00000000006020D6 db
.data:00000000006020D7 db
.data:00000000006020D8 db 27h ; '
.data:00000000006020D9 db
.data:00000000006020DA db
.data:00000000006020DB db
.data:00000000006020DC db 26h ; &
.data:00000000006020DD db
.data:00000000006020DE db
.data:00000000006020DF db
.data:00000000006020E0 db 2Dh ; -
.data:00000000006020E1 db
.data:00000000006020E2 db
.data:00000000006020E3 db
.data:00000000006020E4 db
.data:00000000006020E5 db
.data:00000000006020E6 db
.data:00000000006020E7 db
.data:00000000006020E8 db
.data:00000000006020E9 db
.data:00000000006020EA db
.data:00000000006020EB db
.data:00000000006020EC db
.data:00000000006020ED db
.data:00000000006020EE db
.data:00000000006020EF db
.data:00000000006020F0 db 0Dh
.data:00000000006020F1 db
.data:00000000006020F2 db
.data:00000000006020F3 db
.data:00000000006020F4 db 56h ; V
.data:00000000006020F5 db
.data:00000000006020F6 db
.data:00000000006020F7 db
.data:00000000006020F8 db
.data:00000000006020F9 db
.data:00000000006020FA db
.data:00000000006020FB db
.data:00000000006020FC db
.data:00000000006020FD db
.data:00000000006020FE db
.data:00000000006020FF db
.data: db 65h ; e
.data: db
.data: db
.data: db
.data: db
.data: db
.data: db
.data: db
.data: db 2Dh ; -
.data: db
.data:000000000060210A db
.data:000000000060210B db
.data:000000000060210C db 16h
.data:000000000060210D db
.data:000000000060210E db
.data:000000000060210F db
.data: db
.data: db
.data: db
.data: db
.data: db 15h
.data: db
.data: db
.data: db
.data: db
.data: db
.data:000000000060211A db
.data:000000000060211B db
.data:000000000060211C db 65h ; e
.data:000000000060211D db
.data:000000000060211E db
.data:000000000060211F db
.data: db
.data: db
.data: db
.data: db
.data: db 29h ; )
.data: db
.data: db
.data: db
.data: db 44h ; D
.data: db
.data:000000000060212A db
.data:000000000060212B db
.data:000000000060212C db 44h ; D
.data:000000000060212D db
.data:000000000060212E db
.data:000000000060212F db
.data: db
.data: db
.data: db
.data: db
.data: db 44h ; D
.data: db
.data: db
.data: db
.data: db 2Bh ; +
.data: db
.data:000000000060213A db
.data:000000000060213B db
.data:000000000060213B _data ends

这里就相当于是一连串的整数

因此我们可以分析得出,通过v15/v14作为内部数组下标,循环获到的整数再作为外部数组的下标,获取到需要的字符串。

这里值得注意的一点是,algn 8表示两个数之间间隔8位,相当于在两个数之间插了7个0,也就相当于在头两个数之间还有一个'0'

4.脚本获取flag

S = 'L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_'

N = [0x24,0x0,0x5,0x36,0x65,0x7,0x27,0x26,0x2d,0x1,0x3,0x0,0x0d,0x56,0x1,0x3,0x65,0x3,0x2d,0x16,0x2,0x15,0x3,0x65,0x0,0x29,0x44,0x44,0x1,0x44,0x2b]

x = ''

for i in N:
x += S[i] print(x)

5.get flag!

ALEXCTF{W3_L0v3_C_W1th_CL45535}

攻防世界--re2-cpp-is-awesome的更多相关文章

  1. CTF--web 攻防世界web题 robots backup

    攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...

  2. CTF--web 攻防世界web题 get_post

    攻防世界web题 get_post https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5 ...

  3. 攻防世界 web进阶练习 NewsCenter

    攻防世界 web进阶练习 NewsCenter   题目是NewsCenter,没有提示信息.打开题目,有一处搜索框,搜索新闻.考虑xss或sql注入,随便输入一个abc,没有任何搜索结果,页面也没有 ...

  4. 【攻防世界】高手进阶 pwn200 WP

    题目链接 PWN200 题目和JarvisOJ level4很像 检查保护 利用checksec --file pwn200可以看到开启了NX防护 静态反编译结构 Main函数反编译结果如下 int ...

  5. XCTF攻防世界Web之WriteUp

    XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...

  6. 攻防世界 | CAT

    来自攻防世界官方WP | darkless师傅版本 题目描述 抓住那只猫 思路 打开页面,有个输入框输入域名,输入baidu.com进行测试 发现无任何回显,输入127.0.0.1进行测试. 发现已经 ...

  7. 攻防世界 robots题

    来自攻防世界 robots [原理] robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在, ...

  8. 【攻防世界】 高手进阶区 Recho WP

    0x00 考察点 考察点有三个: ROP链构造 Got表劫持 pwntools的shutdown功能 0x01 程序分析 上来三板斧 file一下 checksec --file XXX chmod ...

  9. CTF -攻防世界-crypto新手区(5~11)

    easy_RSA 首先如果你没有密码学基础是得去恶补一下的 然后步骤是先算出欧拉函数 之后提交注意是cyberpeace{********}这样的 ,博主以为是flag{}耽误了很长时间  明明没算错 ...

  10. 攻防世界web新手区做题记录

    学校信安协会第一次培训结束后的作业,要求把攻防世界的web新手区题目做一遍并写题解. 第一题 view_source 查看源代码右键不能用,但是F12能用,于是找到源代码 输入到flag框即可 后来在 ...

随机推荐

  1. 转发一个robotframework的循环

    Click_Element Xpath=//b[text()='系统投放管理'] Sleep 1 Click_Element Xpath=//span[text()='全部投放情况查询'] Sleep ...

  2. MFC消息详解 (WindowProc|OnCommand|OnNotify)

    1. 怎样使用MFC发送一个消息用MFC发送一个消息的方法是, 首先,应获取接收消息的CWnd类对象的指针: 然后,调用CWnd的成员函数SendMessage( ). LRESULT Res=pWn ...

  3. linux常用基本命令 grep awk 待优化

    查看centos操作系统版本:cat /etc/centos-release 切换到当前用户主目录:cd 或者cd ~ 创建文件夹/a/b/c:mkdir -pv /a/b/c.如果/a/b/c的父目 ...

  4. BZOJ 1112: [POI2008]砖块Klo Splay + 性质分析

    Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...

  5. PHP 判断是否为手机端访问

    /* * 判断是否为手机端 */function check_wap(){ // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset ($_SERVER['HTTP_X_W ...

  6. (转)k8s集群部署二:flannel网络

    转:https://blog.csdn.net/sinat_35930259/article/details/79946146 Overlay Network模式 覆盖网络,在基础网络上叠加的一种虚拟 ...

  7. php面试专题---12、JavaScript和jQuery基础考点

    php面试专题---12.JavaScript和jQuery基础考点 一.总结 一句话总结: 比较常考察的是JavaScript的HTML样式操作以及jQuery的选择器和事件.样式操作. 1.下列不 ...

  8. EZOJ #387字符串

    分析 似乎ttl的模拟赛t3总是折半搜索? 先把所有串转化为每个字母的0/1状态 之后我们将所有字符串分为两半 分别枚举状态 我们发现只有左右两边的字母状态相等才能保证这个集合合法 所以我们在搜左半边 ...

  9. spring-cloud zuul网关

    API Gateway 是随着微服务(Microservice)这个概念一起兴起的一种架构模式,它用于解决微服务过于分散,没有一个统一的出入口进行流量管理的问题. 使用 Zuul 实现 API Gat ...

  10. 用SPSS做时间序列

    用SPSS做时间序列 关于时间序列,有好多软件可以支持分析,大家比较熟悉的可能是EVIEWS.SPSS.还有STATA,具体用啥软件,结果都是一样的,但是SPSS作为一款学习简单,使用容易的软件还是值 ...