Re
0x01 reverse1_final
先用esp定律脱壳,然后导入IDA
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
进入sub_401000
1 | unsigned int __cdecl sub_401000(const char *a1) |
推测是密码表,由于都是在寄存器内运算,ida反编译之后不利于分析,于是使用od动态调试
最后发现以下数据
1 | 00402FF8 00 00 00 00 00 00 00 00 |
它的算法是把输入的字符变成ascii,然后按照ascii作为位置在以上密码表中选出密文
所以算出变换后的对应表来找就好了
1 | #include<iostream> |
所以FLAG为 ZZ[JX#,9(9,+9QY!
0x02 reverse2_final
先用esp定律脱壳,然后导入IDA
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
先进入sub_4011F0,会发现函数对输入的字符串做出了限制只能是0-9,A-F,输入的数量必须是偶数
1 | char __usercall sub_4011F0@<al>(const char *a1@<esi>) |
根据执行结果,就是将字符串转化为十六进制,比如 输入AA 就转化为0xAA 输入BB 就转化为0xBB,然后执行sub_401000
1 | int __usercall sub_401240@<eax>(const char *a1@<esi>, int a2) |
这个代码其实和re1是差不多的,同时我们发现了密码表byte_403020
1 | int __cdecl sub_401000(int a1, void *a2) |
由于每加密之后都要异或一次,不如我们先对密码表进行第一次还原,即异或0x76
发现密码表是有规律的
1 | 0x0003f000 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/wvvv頧LvN;Lvvvvv |
总结:就是输入的字符两两变成十六进制,然后取左边6位作为key取出密码表的字符,不够则用0填充
所以我们先算出密文在密码表的位置
r e v e r s e +
43 30 47 30 43 44 30 62
转化为二进制,然后六个六个分割
10101101 11101011 11011110 10101110 11000111 10111110
然后转化为ascii,即为flag
ADEBDEAEC7BE
Pwn
0x01 pwn strike
第一次输入溢出ebp,第二次输入负数绕过if并且无限长的读入
然后溢出libc,然后再跳会main函数
但是直接跳回main函数会导致ebp无法溢出,所以必须跳到start上,对数据进行初始化
然后rop跳到libc空间然后执行system拿到shell
exp如下
1 | #!/usr/bin/env python |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 咲夜南梦's 博客!
评论