2.1.1 使用范圍
當系統打開ASLR(基本都打開了)時,使用硬編碼地址的話,就無法成功利用漏洞.在這種情況下就可以使用這種技術.程序必須關閉NX
2.1.2 原理
當函數執行完,彈出了返回地址,rsp往往指向(返回地址+8),我們將shellcode放在此處就可以讓程序執行,注意跳板不一定是rsp(和和程序的位數有關)
2.1.2 原理
當函數執行完,彈出了返回地址,rsp往往指向(返回地址+8),我們將shellcode放在此處就可以讓程序執行,注意跳板不一定是rsp
2.1.3 實踐
1 拿到程序第一件事就是先運行一下,熟悉要分析的東西(這一點不光是pwn,不管是re還是滲透,先對於目標有個直觀了解都是很重要的事)

2 打開ida,,可以看到程序非常的簡單
我們輸入的數據最終會復制到[bp-20h],而且沒有長度限制,肯定就是有棧溢出漏洞
3 接下來我們檢查一下程序打開了哪些保護措施

可以看到程序沒有沒有打開任何保護措施,現在唯一需要解決的就是系統自帶的ASLR,(注意,使用gdb調試時,每次看到的棧地址可能是不變的,這並不代表系統沒有打開ASLR,gdb調試時會自動關閉ASLR)
4 接下來是定位返回地址
前面看到了我們輸入的數據最終會復制到[bp-20h],我們先嘗試輸入40個數據,用python生成40個數據
從第四十個字節開始的八個字節就會覆蓋返回地址
5 寫exp
首先我們需要一個shellcode,這可以通過msf生成 生成命令如下
#!bash
show payload
use linux/x64/exec
set cmd /bin/sh
generate -t py -b "/x00"
即可得到shellcode
然后我們還需要一個跳板作為返回地址 peda就有這種功能
jmpcall rsp

我們就采用第一個地址, 注意64位系統,和little endian
然后我們使用zio寫exp
python pwn1.py
運行即可看到
已拿到shell

2.2 GOT覆寫
2.2.1 使用范圍
剛才我們是通過棧溢出漏洞攻擊函數的返回地址,但是現在對於棧溢出,已經有很多保護,例如canary(與windows下的GS技術類似).同時現在更常見的是指針覆蓋漏洞,在這種情況下我們擁有一次修改任意內存的機會,在這時我們采用的往往就是GOT覆寫技術.
2.2.2 原理
GOT是全局偏移表,類似於windows中PE結構的IAT,只不過windows中IAT中的函數地址是寫保護的,沒辦法利用,但是GOT是可寫的,我們可以將其中的函數地址覆蓋為我們的shellcode地址,在程序后面調用這個函數時就會調用我們的shellcode了
2.2.3 實踐
在這兒我用的實驗程序來自panable.kr中的passcode,比較簡單,源碼如下
編譯后的程序見附件,32位 linux
感覺銳銳_z的指點
1 分析程序可知,scanf時,沒有用取地址符,會使用棧上的數據作為指針存放輸入的數據,而我們第一次輸入的數據就是在棧上,簡單調試可知,在welcome()函數中的name的最后4字節會在login()函數中被用作地址指針
2 這樣,我們就獲得了修改任意地址數據的一次機會
3 分析程序可知如果我們用后面調用system()的地址覆蓋了printf()在GOT中的指針,那么在第二次login()中第二次調用printf()時就會直接去調用system()
4 現在我們需要知道兩個東西,一是GOT中printf()的地址,二是程序中調用system()的地址
objdump -R passcode

即可獲得printf()
在的地址0804a000
這是攻擊目標,
然后打開gdb,運行到調用system()的地方,為什么我們可以直接使用這個地址呢,因為linux下面的程序默認沒有隨機化code段,
要寫入的值即為 0x080485e3
2.3 ret2libc技術
2.3.1 使用范圍
當系統打開DEP時,我們不能自己直接在棧上放shellcode,就使用幾乎每個linux系統都會自帶的libc中的代碼.
2.3.2 原理
一種常見的利用方式是用libc中的system()的地址覆蓋返回地址,同時在棧上布置好的參數,程序返回時就會產生一個shell
2.3.3 實踐
在這兒用的程序是強網杯的urldecoder(程序見附件),再次感謝tracy_子鵬學長指點
這道題同時開了ASLR和DEP.,運行環境為32位linux
- 分析程序后發現,前面讀入數據時,只有遇到換行和EOF才會結束,但是后面檢查字符串長度是用的strlen,於是可以通過在字符串中加入\x00來繞過長度檢查
- 繼續分析程序流程,發現,當輸入為%1\x00時就可以成功覆蓋返回地址
- 接下來就考慮利用漏洞的方法
- 觀察到溢出后,程序會多輸出一些棧上的數據出來,想到可以利用輸出出來的一些數據定位libc加載的基址,然后將返回地址覆蓋為前面讀入數據的代碼地址,再讀一次數據,再溢出一次,這一次執行到返回時,就執行libc中的system函數
- 題目提供了libc,可以計算其中各函數的偏移,找到libc中system函數和/bin/sh字符串的地址,同時在棧上布置好參數,即可成功利用
