PWN入門分享


pwn基礎入門分享

什么是PWN?

以下內容摘自百度百科:

”Pwn”是一個黑客語法的俚語詞,是指攻破設備或者系統 。發音類似“砰”,對黑客而言,這就是成功實施黑客攻擊的聲音——砰的一聲,被“黑”的電腦或手機就被你操縱了 。

​ PWN也可譯為二進制漏洞挖掘,在CTF比賽中,PWN題的目標是拿到flag,一般是在linux平台下通過二進制/系統調用等方式編寫漏洞利用腳本exp來獲取對方服務器的shell,然后get到flag。

PWN的前置技能

匯編語言,函數調用約定,大小端,函數棧幀

C語言,python語言,gdb調試,IDA pro分析

linux相關:32位與64位,各類防護機制(NX,ASLR,Canary,Relro),ELF文件格式,系統調用,shell命令

相關課程:

匯編語言

編程語言(C語言和Python)

計算機組成與原理

軟件工具:

虛擬機以及VMtoolsubuntu(以及插件gdbpwntoolspedapwndbg等)IDA(32位和64位)

首先我們要了解一個可執行文件的生成過程
請添加圖片描述

可執行文件

文件中的數據是可執行代碼的文件.out、.exe、.sh、.py

可執行文件的分類

Windows:PE(Portable Executable)
可執行程序.exe
動態鏈接庫.dll
靜態鏈接庫.lib

Linux:ELF(Executable and Linkable Format)
可執行程序.out
動態鏈接庫.so
靜態鏈接庫.a

詳細解釋請參考:

https://blog.csdn.net/weixin_44169596/article/details/112969081?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=2

常見漏洞

  1. 棧溢出
  2. 堆溢出
  3. 整數溢出(Integer overflow)
  4. 格式化字符串(Format string)

​ .....

請添加圖片描述
請添加圖片描述

這個思維導圖中的內容過於龐大,在現階段的學習中其實很多都學不到。我們今天從環境和基礎出發,主要的任務是配備pwn環境和了解簡單的Pwn題目。

基礎環境

環境配置步驟

  1. 下載Vmware管理虛擬機。
  2. 下載Ubuntu Linux鏡像文件

需要注意,Linux的版本太高很多插件容易出問題,所以不建議使用最新版本的Linux系統,最穩定的不是太老舊的就可以。

Ubuntu清華大學源

https://mirrors.tuna.tsinghua.edu.cn/

請添加圖片描述

請添加圖片描述

  1. 安裝虛擬機系統,詳情請百度。
  2. 更換下載源
  3. 下載pwntools

pwntools是一款專門用於CTF Exploit的python庫,能夠很方便的進行本地與遠程利用的切換,基本涵蓋了pwn題利用腳本所需要的各種工具。

參考:

https://www.cnblogs.com/pcat/p/5451780.html

sudo apt update
sudo apt install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential -y
python3 -m pip install --upgrade pip
pip3 install --upgrade pwntools
  1. 安裝gdb (動態調試軟件)
apt-get install gdb
  1. peda/pwngdb/gef

這是常見的gdb的三個插件,配合gdb使用可以提升調試效率。

安裝pwndbg

git clone https://github.com/pwndbg/pwndbg
 
cd pwndbg
 
./setup.sh

安裝peda

git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
  1. 安裝LibcSearcher

泄露libc庫中函數的偏移的庫,建議安裝,可以節省時間,提高效率。

sudo pip install capstone
git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop
  1. ROPgadgetone_gadget

ROPgadget是用來找gadget的,one_gadget用來尋找libc庫中的execve('/bin/sh', NULL, NULL)可以一個gadget就可以getshell

安裝ROPgadget

sudo apt-get install python-capstone
 
git clone https://github.com/JonathanSalwan/ROPgadget.git
 
cd ROPgadget
 
sudo python setup.py install

安裝one_gadget

sudo apt -y install ruby
sudo gem install one_gadget
  1. windows下的IDA

    靜態調試工具

棧溢出漏洞

在了解棧溢出漏洞前,我們要先了解棧這個數據結構。

棧是一種典型的先進后出( First in Last Out )的數據結構,其操作主要有壓棧(push)與出棧(pop)兩種操作,如下圖所示。兩種操作都操作棧頂,當然,它也有棧底。

請添加圖片描述

每個程序在運行時都有虛擬地址空間,其中某一部分就是該程序對應的棧,用於保存函數調用信息和局部變量。此外,常見的操作也是壓棧與出棧。

請添加圖片描述

函數調用棧

程序的執行過程可看作連續的函數調用。當一個函數執行完畢時,程序要回到調用指令的下一條指令(緊接匯編中的call指令)處繼續執行。函數調用過程通常使用堆棧實現,每個用戶態進程對應一個調用棧結構(call stack)。編譯器使用堆棧傳遞函數參數、保存返回地址、臨時保存寄存器原有值(即函數調用的上下文)以備恢復以及存儲本地局部變量。

ELF文件

ELF:Executable and Linkable Format
一種Linux下常用的可執行文件、對象、共享庫的標准文件格式

文件保護機制

Linux ELF文件的保護主要有四種:CanaryNXPIERELRO
在Linux中可以用checksec來檢測文件的保護機制
如下圖為一例:

請添加圖片描述

第一行的arch 表示 程序架構信息

Canary

Canary是金絲雀的意思。技術上表示最先的測試的意思。這個來自以前挖煤的時候,礦工都會先把金絲雀放進礦洞,或者挖煤的時候一直帶着金絲雀。金絲雀對甲烷和一氧化碳濃度比較敏感,會先報警。所以大家都用Canary來搞最先的測試。Stack Canary表示棧的報警保護。

在函數返回值之前添加的一串隨機數(不超過機器字長)(也叫做cookie),末位為/x00(提供了覆蓋最后一字節輸出泄露Canary的可能),如果出現緩沖區溢出攻擊,覆蓋內容覆蓋到Canary處,就會改變原本該處的數值,當程序執行到此處時,會檢查Canary值是否跟開始的值一樣,如果不一樣,程序會崩潰,從而達到保護返回地址的目的。
機制繞過:
開啟canary后就不能直接使用普通的溢出方法來覆蓋棧中的函數返回地址了,要用一些巧妙的方法來繞過或者利canary本身的弱點來攻擊

(1)泄露棧中的 Canary:泄露棧中的 Canary 的方法是打印棧中 Canary 的值。 這種利用方式需要存在合適的輸出函數得到canary的值。再構造payload的時候再將cannary的值寫回棧中從而繞過CANNARY的保護。
(2)爆破 Canary:對於 Canary,雖然每次進程重啟后的 Canary 不同,但是同一個進程中的不同線程的 Canary 是相同的,並且通過 fork 函數創建的子進程的 Canary 也是相同的,因為 fork 函數會直接拷貝父進程的內存。我們可以利用這樣的特點,徹底逐個字節將 Canary 爆破出來。
(3)劫持__stack_chk_fail 函數:Canary 失敗的處理邏輯會進入到 __stack_chk_failed 函數,__stack_chk_failed 函數是一個普通的延遲綁定函數,可以通過修改 GOT 表劫持這個函數。
(4)覆蓋 TLS 中儲存的 Canary 值:Canary 儲存在 TLS 中,在函數返回前會使用這個值進行對比。當溢出尺寸較大時,可以同時覆蓋棧上儲存的 Canary 和 TLS 儲存的 Canary 實現繞過。

NX

NX即No-eXecute(不可執行)的意思,NX(DEP)的基本原理是將數據所在內存頁標識為不可執行,當程序溢出成功轉入shellcode時,程序會嘗試在數據頁面上執行指令,此時CPU就會拋出異常,而不是去執行惡意指令。
機制繞過:
當程序開啟NX時, 如果我們在堆棧上部署自己的 shellcode 並觸發時, 只會直接造成程序的崩潰,開啟NX之后棧和bss段就只有讀寫權限,沒有執行權限了,所以就要用到rop這種方法拿到系統權限,如果程序很復雜,或者程序用的是靜態編譯的話,那么就可以使用ROPgadget這個工具很方便的直接生成rop利用鏈。有時候好多程序不能直接用ROPgadget這個工具直接找到利用鏈,所以就要手動分析程序來getshell了。

PIE(ASLR)

一般情況下NX(Windows平台上稱為DEP)和地址空間分布隨機化(PIE/ASLR)(address space layout randomization)會同時工作。內存地址隨機化機制有三種情況:

0 – 表示關閉進程地址空間隨機化。

1 – 表示將mmap的基地址,棧基地址和.so地址隨機化

2 – 表示在1的基礎上增加heap的地址隨機化

該保護能使每次運行的程序的地址都不同,防止根據固定地址來寫exp執行攻擊。

可以防止Ret2libc方式針對DEP的攻擊。ASLR和DEP配合使用,能有效阻止攻擊者在堆棧上運行惡意代碼
機制繞過:
PIE 保護機制,影響的是程序加載的基址,並不會影響指令間的相對地址,因此如果我們能夠泄露程序的某個地址,就可以通過修改偏移獲得程序其它函數的地址。

RELRO

Relocation Read-Only (RELRO) 此項技術主要針對 GOT 改寫的攻擊方式。它分為兩種,Partial RELRO 和 Full RELRO。

部分RELRO 易受到攻擊,例如攻擊者可以atoi.got為system.plt,進而輸入/bin/sh\x00獲得shell

完全RELRO 使整個 GOT 只讀,從而無法被覆蓋,但這樣會大大增加程序的啟動時間,因為程序在啟動之前需要解析所有的符號。
機制繞過:
如果程序開啟了FULL RELRO,意味着我們無法修改got表,所以一般也采用通過ROP繞過的方法。

linux內存布局

Kernel Space:Kernel space 是 Linux 內核的運行空間,User space 是用戶程序的運行空間。在設計時考慮到安全因素,內核空間和用戶用戶是隔離的,即使用戶的程序崩潰了,內核也不受影響。

Stack: Linux中的棧與數據結構中的棧類似,是計算機程序中非常重要的理論之一,可以說沒有一個程序程序可以離開這種結構棧。用戶或者程序都可以把數據壓入棧中,不管如何棧始終有一個特性:先入棧的數據最后出棧(First In Last Out, FIFO)。

Heap:堆相對相對與棧來說比較復雜,編程人員在設計時程序可能會申請一段內存,或者刪除掉一段已經申請過的內存,而且申請的大小也不確定,可以是從幾個字節,也可以是數 GB ,所以堆的管理相對來說比較復雜。

bss段:BSS段通常是一塊內存區域用來存放程序中未初始化的或者初始化為0的全局變量和靜態變量的。特點是可讀寫的,程序初始化時會自動清零。

Data段 :數據段是一塊內存區域它用來存放程序中已初始化的全局變量的。數據段是靜態內存分配。

Code段:代碼段是一塊內存區域來存放程序執行代碼的。代碼段在程序運行前就已經確定,代碼段在內存中是一段只讀空間,但有些架構也允許代碼段可讀寫,即允許自修改程序。

緩沖區溢出分為棧溢出堆溢出。棧溢出是由於在棧的空間內,放入大於棧空間的數據,導致棧空間以外有用的內存單元被改寫,這種現象就稱為棧溢出

普通的溢出不會有太大危害,但是如果向溢出的內存中寫入的是精心准夠着的數據(payload),就可能使得程序流程被劫持,使得危險的代碼被執行,最終造成重大危害。

棧溢出漏洞例題:

攻防世界level_0:

首先在ubuntu中使用checksec檢查文件保護機制:
請添加圖片描述

之后在64位IDA中打開查看,
請添加圖片描述

IDA使用基本教程可參考:

https://www.52pojie.cn/thread-886103-1-1.html

https://blog.csdn.net/ilnature2008/article/details/54912854

https://www.cnblogs.com/iBinary/p/7721042.html?utm_source=debugrun&utm_medium=referral

其中比較重要的使用有:

  1. 空格可以切換匯編代碼為流程圖瀏覽模式
  2. shift + F12按鍵用來查看字符串
  3. ctrl + x 按鍵可以跳轉到指定地址的匯編代碼段。
    地址為語句前的.text:xxxxxxxxxxxxxxxx
  4. F5按鍵用來查看偽代碼

回歸到本題,我們查看有效字符串,發現兩個重要信息。

請添加圖片描述

第一個是/bin/sh

我們首先要知道的是/bin/sh在Pwn題目中尤為重要,因為system("/bin/sh")這個函數作用很大。

system擁有系統的高級權限,當它和"/bin/sh"鏈接到一起,就會為我們提供一個類似cmd的操作面板,我們可以用它來進行查看/修改/操作等動作。

簡單來說,這是一個可以獲取系統權限的危險函數。

第二個是Hello,World,這個字符串很可能是在主函數中出現,我們可以順着它去往主函數的地址。

我們雙擊Hello,World,然后按下ctrl + x

請添加圖片描述

點擊ok,之后再按下F5查看偽代碼。

請添加圖片描述

之后發現這個函數很簡單,就是一個寫入字符串的操作。

順着主函數我們找到另一個函數:
請添加圖片描述

我們在這里補充一下ebpesp的概念

(1)ESP:棧指針寄存器(extended stack pointer),其內存放着一個指針,該指針永遠指向系統棧最上面一個棧幀的棧頂。

(2)EBP:基址指針寄存器(extended base pointer),其內存放着一個指針,該指針永遠指向系統棧最上面一個棧幀的底部。

esp始終指向棧頂,ebp是在堆棧中尋址用的

調用一個函數時,先將堆棧原先的基址(EBP)入棧,以保存之前任務的信息。然后將棧頂指針的值賦給EBP,將之前的棧頂作為新的基址(棧底),然后再這個基址上開辟相應的空間用作被調用函數的堆棧。函數返回后,從EBP中可取出之前的ESP值,使棧頂恢復函數調用前的位置;再從恢復后的棧頂可彈出之前的EBP值,因為這個值在函數調用前一步被壓入堆棧。這樣,EBP和ESP就都恢復了調用前的位置,堆棧恢復函數調用前的狀態。

buf 這個字符數組的長度只有 0x80,而我們可以輸入 0x200 的東西。我們的輸入不但可以填充滿整個數組還能覆蓋掉數組外面的東西。

當屬於數組的空間結束后(到 0x0000000000000000 時),首先,有一個 s,8 個字節長度,其次是一個 r,重點就在這,r 中存放着的就是返回地址。即當 read 函數結束后,程序下一步要到的地方。

請添加圖片描述

我們的輸入完全可以覆蓋掉這個ret地址,即修改這個地址。

我們可以利用這一點,把返回地址修改為system("/bih/sh")的地址,這樣就會運行我們剛剛找到的那個危險函數。

我們在IDA中找到system("/bih/sh")的地址:

請添加圖片描述

那么我們在Linux可以編寫腳本了。

python3版:

python3運行常見WP會報錯TypeError: a bytes-like object is required, not ‘str’

Python2沒有這個問題,因此python3代碼做了一定修改

from pwn import *
r = remote("111.200.241.244", 50348)
payload = "A" * 0x80 + "a" * 0x8 + p64(0x00400596).decode("iso-8859-1")

r.recvuntil("Hello, World\n")

r.sendline(payload)
r.interactive()

python2:

from pwn import *
r = remote("111.200.241.244", 50348)
payload = "A" * 0x80 + "a" * 0x8 + p64(0x00400596)

r.recvuntil("Hello, World\n")

r.sendline(payload)
r.interactive()

運行腳本:

請添加圖片描述
獲得flag。

這就是最簡單的棧溢出題目。它屬於棧的ret2text類型。

結語

本題目中system("/bih/sh")算是一個后門函數,我們利用他來獲取系統權限,那么如果程序中沒有使用這個函數呢?我們怎么獲取系統權限呢?我們去哪里找這個函數地址呢?

在這之上的題目類型就是ret2shellcodere2syscallret2libc,等等等

之后也會學到ROP技術來解決這類題目。

棧溢出的學習路線就是沿着題目類型去學習。

在棧溢出之外,還有堆利用,格式化字符串漏洞,整數溢出漏洞等。

學習建議是在了解基礎的ROP之后去學習格式化字符串,堆等其他漏洞,之后開始刷Pwn的題目,一邊刷題一邊學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM