测试文件: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. BZOJ2440/洛谷P4318 [中山市选2011]完全平方数 莫比乌斯函数

    题意:找到第k个无平方因子数. 解法:这道题非常巧妙的运用了莫比乌斯函数的性质! 解法参考https://www.cnblogs.com/enzymii/p/8421314.html这位大佬的.这里我 ...

  2. struts2+ajax 前后端传值

    摘要: 主要实现步骤如下: 1.JSP页面使用脚本代码执行ajax请求 2.Action中查询出需要返回的数据,并转换为json类型模式数据 3.配置struts.xml文件 4.页面脚本接受并处理数 ...

  3. linux运维、架构之路-keepalived高可用

    一.Keepalived介绍          Keepalived起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能,Ke ...

  4. C指针,&,*,指针的指针

    C指针: 指向变量的地址,想象成房间号 &: 取地址符号 *:间接访问符号, 访问p所存地址的内容 #include <iostream> int main(int argc, c ...

  5. vue框架搭建--axios使用

    前后端数据交互作为项目最基础需求(静态的除外),同时也是项目中最重要的需求. 本文重点介绍axios如何配合vue搭建项目框架,而axios的详细使用介绍请移步使用说明 1.安装 cnpm insta ...

  6. 实现word在线预览 有php的写法 也有插件似

    <?php //header("Content-type:text/html;charset=utf-8"); //word转html 展示 $lj=$_GET['file' ...

  7. js 通过浏览器直接打开应用程序(IOS,Android)

    实现效果 如下图所示,在手机浏览器中访问京东的手机版网站(m.jd.com),顶部会有一个广告图,点击这个广告图,如果手机上已经安装了京东App,则直接打开,如果没有安装,则开始下载. 实现方式 1. ...

  8. Charles抓取https

    步骤一:将Charles的根证书(Charles Root Certificates)安装到Mac上. Help -> SSL Proxying -> Install Charles Ro ...

  9. win10下VMware15运行ubuntu18.04无法和主机之间复制粘贴问题

    可以运行以下命令行: sudo apt-get autoremove open-vm-tools sudo apt-get install open-vm-tools sudo apt-get ins ...

  10. polly的几种常用方法

    参考资料:https://www.cnblogs.com/edisonchou/p/9159644.html 特征:可以实现一些代码的熔断和降级 代码: ////普通,其中 Fallback相当于降级 ...