0x00 前言
- 借助这道题目记录一下
LibcSearcher
的使用,当然这道题目用DynELF
也可以。
0x01 分析
1 | Arch: amd64-64-little |
程序流程比较简单,在
encrypt
函数里由于使用的是gets(s)
,存在栈溢出。但是程序会对我们输入的字符串s
进行一系列异或操作。这里需要注意这个
(unsigned int)x
。
再看到下面的
++x;
,然后也可以推测出x的初始值为0。这也就是说,只有当我们输入的字符串的长度大于x的值的时候,才会执行这一系列异或操作。
所以如果我们输入两次长度相等的字符串,那么只会对第一次输入的字符串进行异或。
由于程序没有后门函数,我们需要自己泄露libc了。
0x02泄露libc
我们可以通过用
puts
函数打印出puts_got
的内容,从而通过LibcSearcher
得到libc,进而得到libcbase
、system
、/bin/sh
。由于异或运算是可逆的,我们首先写出来一个
encrypt函数(实际上叫decrypt更合适)
,但是似乎不对payload进行encrypt也可以….
1 | def encrypt(payload): |
- 简单构造一下payload用以输出
puts_got
的内容。
1 | elf = ELF('./ciscn_2019_c_1') |
- 获取
libcbase、system、binsh
。
1 | c.recvuntil('Ciphertext\n') |
0x03 getshell
- 这里需要注意一点
由于Ubuntu18运行机制与前面版本的不同,在调用system的时候需要进行栈对齐
- 我们可以使用
ret
进行栈对齐。
1 | ret = 0x4006b9 |
0x04 完整exp
1 | from pwn import * |