攻防世界--re2-cpp-is-awesome
测试文件:https://adworld.xctf.org.cn/media/task/attachments/c5802869b8a24033b4a80783a67c858b
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的更多相关文章
- CTF--web 攻防世界web题 robots backup
攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...
- CTF--web 攻防世界web题 get_post
攻防世界web题 get_post https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5 ...
- 攻防世界 web进阶练习 NewsCenter
攻防世界 web进阶练习 NewsCenter 题目是NewsCenter,没有提示信息.打开题目,有一处搜索框,搜索新闻.考虑xss或sql注入,随便输入一个abc,没有任何搜索结果,页面也没有 ...
- 【攻防世界】高手进阶 pwn200 WP
题目链接 PWN200 题目和JarvisOJ level4很像 检查保护 利用checksec --file pwn200可以看到开启了NX防护 静态反编译结构 Main函数反编译结果如下 int ...
- XCTF攻防世界Web之WriteUp
XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...
- 攻防世界 | CAT
来自攻防世界官方WP | darkless师傅版本 题目描述 抓住那只猫 思路 打开页面,有个输入框输入域名,输入baidu.com进行测试 发现无任何回显,输入127.0.0.1进行测试. 发现已经 ...
- 攻防世界 robots题
来自攻防世界 robots [原理] robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在, ...
- 【攻防世界】 高手进阶区 Recho WP
0x00 考察点 考察点有三个: ROP链构造 Got表劫持 pwntools的shutdown功能 0x01 程序分析 上来三板斧 file一下 checksec --file XXX chmod ...
- CTF -攻防世界-crypto新手区(5~11)
easy_RSA 首先如果你没有密码学基础是得去恶补一下的 然后步骤是先算出欧拉函数 之后提交注意是cyberpeace{********}这样的 ,博主以为是flag{}耽误了很长时间 明明没算错 ...
- 攻防世界web新手区做题记录
学校信安协会第一次培训结束后的作业,要求把攻防世界的web新手区题目做一遍并写题解. 第一题 view_source 查看源代码右键不能用,但是F12能用,于是找到源代码 输入到flag框即可 后来在 ...
随机推荐
- MongoDB的应用
一.MongoDB后台管理 # ./mongo MongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1:27017 MongoD ...
- springboot集成hibernate
package com.jxd.Boot.hibernate.dao.impl; import java.util.List; import javax.persistence.EntityManag ...
- 关于pug的笔记
一.简介 Pug 是一款健壮.灵活.功能丰富的模板引擎,专门为 Node.js 平台开发.Pug 是由 Jade 改名而来,他可以帮助我们写html的时候更加的简单明了.安装.使用pug的过程打开cm ...
- 使用Fabric在tomcat中部署应用的问题总结
关闭tomcat时 A.为什么调用shutdown时,报错连接拒绝 结论——很可能是因为tomcat没启动或没完全启动:而这个时候调用shutdown就会出现此类报错 解决方法:time.sleep ...
- OC 类的load方法
+(void)load 方法 不需要主动调用,类加载时会走这个方法
- python 全栈开发,Day9(函数的初始,返回值,传参,三元运算)
一.函数的初始 比如python没有len()方法,如果求字符串的长度 使用for循环 s = 'asdfadsf' count = 0 for i in s: count += 1 print(co ...
- MyView.java 自己画的view
package myapplication21.lum.com.mycanvas; import android.content.Context;import android.graphics.Can ...
- php面试专题---13、AJAX基础内容考点
php面试专题---13.AJAX基础内容考点 一.总结 一句话总结: ajax对提升用户速度,缓解服务器压力方面也是很有可取之处的,毕竟传递的数据少了 1.AJAX基础概念? Asynchronou ...
- php基础函数,数组
1·字符串的处理: 2·爆炸函数(explode()): 里面填两个参数把.炸掉,在abc里 炸出来的数组 粘回去(implode()): 两个参数同上 3·截取字符串(substr()) 里面放三个 ...
- 什么时候需要用的Vue.nextTick()
什么时候需要用的Vue.nextTick() 你在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中.原因是什么呢,原因是在created() ...