来源:https://buuoj.cn/
内容:
附件:https://pan.baidu.com/s/1g6wnqkuqydzHHlXInmRCNQ?pwd=mjlu 提取码:mjlu
答案:pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}
总体思路详细步骤发现主要流程三个函数,分别是输出一个欢迎语、要求用户输入、判断用户输入
欢迎语
中会判断用户的输入是否是在0x7e以内的,即是否是ascii,不是的话则认为用户在pwn,报警并退出程序
用户输入
中会将用户的输入逐项与 0x91+sum(index)异或
判断用户输入
中是将用户的输入逐项与g_key
判断是否相等反向编写脚本,得到答案
-
查看文件内容
-
查看main函数,发现三个主要函数,分别是输出一个欢迎语、要求用户输入、判断用户输入
-
进入
f_banner
,发现内部是要求用户输入一个字符。随便输入一个字符回车即可。- 如果
getc(stdin) - 33) > 93
即 char > 126的时候就会输出Hey now, what're you trying to pull over on me, conductor?
,估计是可能防止用户pwn
- 如果
-
进入
f_input
发现是要求用户输入字符串,有个混淆流程,可不管。随后进入f_xor_with_0x91_series
将所有用户的输入异或 0x91+sum(index)- 判断输入是否有\n,有的话就抛出异常。否则就会对输入进行转换,v_temp从0x91开始,每轮增加index,然后与当前字符异或
-
注意v_temp是一个byte类型,需要判断是否有溢出,溢出的时候则恢复到0
v_temp %= 0xff
。 -
进入
f_check
发现是先将g_key
复制0x12C个(300个)字节到v_key
,qmemcpy(v_key, g_key, 0x12CuLL);
qmemcpy和memcpy是等价的,定义如下-
以source指向的地址为起点,将连续的n个字节数据,复制到以destin指向的地址为起点的内存中。C/C++语言中的一个用于内存复制的函数,声明在 string.h 中(C++是 cstring)。
void *memcpy(void *destin, void *source, unsigned n); // 目标地址,源地址,数据长度。
-
-
然后设置 *(v_key_addr + 292) =* ( v_key[36] + 4),即将v_key_addr第292个字节设置为了 v_key的第292个字节的值,没有变化。(v_key是int64类型,一个数值等于4个字节)
-
随后调用了一个没有 *** 作任何数值的memcpy
-
qmemcpy( (void *)((unsigned __int64)(v_key_addr + 1) & 0xFFFFFFFFFFFFFFF8LL), (const void *)((char *)v_key - ((char *)v_key_addr - ((unsigned __int64)(v_key_addr + 1) & 0xFFFFFFFFFFFFFFF8LL))), 8LL * (((unsigned int)v_key_addr - (((_DWORD)v_key_addr + 8) & 0xFFFFFFF8) + 300) >> 3));
-
-
并开始逐个字符判断输入是否等于v_key
-
动调到判断逐个字符的位置,双击v_key,按shift+e复制其数值,得到exp
-
import struct g_key = 'E1E6D04AF2C37EAAE6FC42B2F2B501B4EC7D3920EFC04E13C82F67AA95796BF5F2064179D835F9C88EDE8851AC4CF081E0F4EE14ADF125BD827C6230A5F8802B79852AF86E5AAECB183AA2D009C58C5D3D346BF93B724B0E4AC37153E1E907BBC11AE7078F1B7574B98E5D2EC2F6173B52EDD7BD5EE9766372E2EA8951D74F34DC39D55892D9D2D2AA69F1BF9076E19C390D0CB3400648DA27D51EB84A944C98C48A68A8975E64F9C058F702728D3B881814EC8F42700C0B9666228EF758012EC5DC4BC071F4DAE63D73887DE4911F759070D60CA7097CF25A4EA1090C513CBAA864382D8C0088E36FEA77907439AA56F1A86E80CA3D9E69A46948F20A2CF733170F5CF28AE52F55A59F8B655476E064EE9D9B2D9B5F727F3BD9DF0569F09FF0A38CE6CDEFB4BC44543EE344' g_key = bytearray.fromhex(g_key) split_count: int = 4 g_key = [g_key[x*split_count] for x in range(int(len(g_key)/split_count))] print([struct.pack(', x) for x in g_key]) xor_pointer = 0x91 result = [] for index, x in enumerate(g_key): result.append(x ^ xor_pointer) xor_pointer += index xor_pointer %= 0xff # 防止溢出 print([struct.pack(', x) for x in result]) result = [chr(x) for x in result] result = result[0:75] print(''.join(result)) # pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}
-
得到答案
pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}
-
需要注意的是
- 因为v_key的类型是int64,所有split_count=4按每4个字节分割开来。
- 在每次增加xor_pointer的时候需要判断是否溢出
- struct.pack
-
参考Python使用struct库的用法
- CTF逆向-常用的逆向工具 提取码:pnbt
- 常见用法
- 使用python快捷处理加密算法(RSA、AES、DES、3DES、XXTEA、blowfish)
- Python使用struct库的用法
- B站教程中国某省队CTF集训(逆向工程部分)
- 中国某省队CTF集训(逆向工程部分)(已授权)(一)
- 基础加密方式例如
XXTEA
、Base64
换表 - Python库
Z3
方程式、不定式等的约束求解
- 基础的假跳转花指令(脏字节)
- 非自然程序流程
- 扁平化程序控制流
- OLLVM程序流程(虚拟机壳) 很难一般不考
- ida里面按
X
键跟踪,寻找所有Ty
为w
的引用(即类型是写入的),通常就是关键位置
- 中国某省队CTF集训(逆向工程部分)(已授权)(二)
- ollydb动调去壳,upx为例子
- python的逆向和自定义虚拟指令
- 使用pycdc 提取码:dorr 解密python编译的exe或者pyc
- 逐条去解析用py字典手动实现的指令调用
- C++编译的程序的逆向
- 中国某省队CTF集训(逆向工程部分)(已授权)(三)
- 简单模运算加密
- base58 寻找一下特别大的数,这种数通常是算法的标识,或者ida7.7版本以上自带的
find crypt
插件ctrl+alt+f
- 常见的关键位置是有新的内存分配的地方通常是关键地方,或者函数中间突然return的地方也是
- 迷宫题 注意绘制出来就好
- 动调题
- 注意观察会执行的反调试分支,例如出现
int 3
,需要跳过去
- 注意观察会执行的反调试分支,例如出现
- 基本知识
- 大小端序
更多CTF逆向题通用性做法和常用工具下载参考该博文内容:CTF逆向Reverse题的玩法
相关逆向CTF题-
Python
- Python反汇编方法 Python的pyc字节码反编译反汇编相关知识
- [CTF逆向-羊城杯 2020]Bytecode-WP-Python字节码反编译
-
远程调试汇编
- CTF逆向-[watevrCTF 2019]Timeout-WP-远程调试和修改程序当前运行位置RIP
- CTF逆向-[watevrCTF 2019]esreveR-看似复杂流程,发现核心逻辑,按64位架构导出栈中和寄存器中的值得到结果
-
流程控制
- CTF逆向-Dig the way Interesting Pointer-通过栈溢出方式覆盖变量以达到修改执行流程的目的
-
逆向思维
- [CTF逆向-NPUCTF2020]Baby Obfuscation-逆向思维编写脚本以及函数含义的逻辑理解
- [CTF逆向-MRCTF2020]EasyCpp - C++类型的逆向通用 *** 作方法
- [CTF逆向-SUCTF2018]babyre-WP-cpp简单迭代并按表输出值的爆破
-
安卓
- [CTF逆向-网鼎杯 2020 青龙组]bang-安卓脱壳逆向:frida-dexdump导出得到源码
-
虚拟机
- [CTF逆向-GWCTF 2019]babyvm-WP-虚机模拟流程反向编码和z3约束求解器解方程工具的使用
- [CTF逆向-WMCTF2020]easy_re-WP_虚机-perl加载器截取
-
反调试和SMC
- [CTF逆向-SCTF2019]creakme-WP-基于AES加密算法下的保护:反调试及except_handler和SMC
- CTF逆向-[FlareOn1]Shellolololol-栈上执行,多层smc的动调得到最终结果
-
加密
- Python 基于pycryptodome,实现对AES、DES、3DES、RSA等常用加密算法的使用,文末附各种加密的源码示例
- [CTF逆向-FlareOn2]very_success-WP_rol循环位移加密
- base64换表
- [CTF逆向-CISCN2018]2ex-WP_mips-32架构以及base64换表
- [CTF逆向-De1CTF2019]Re_Sign-简单脱壳和base64换表编码的深度算法跟踪
-
花指令
- [CTF逆向-SCTF2019]babyre-WP_简单去花指令和流程识别
- CTF逆向-[MRCTF2020]VirtualTree-恒成立的jz花指令去除及smc变换原执行流程在二叉树上的应用,通过逆向思维编写脚本以解决
-
流程混淆的扁平化处理
-
[CTF逆向-RoarCTF2019]polyre-WP_控制流扁平化去混淆idcpy去指令
-
CTF逆向-[SUCTF2019]hardcpp-使用优化过的deflat.py处理混淆的控制流并将cpp的lambda解析得到实际处理逻辑
-
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)