CTF中做Linux下漏洞利用的一些心得


其實不是很愛搞Linux,但是因為CTF必須要接觸一些,漏洞利用方面也是因為CTF基本都是linux的pwn題目。

基本的題目分類,我認為就下面這三種,這也是常見的類型。

下面就分類來說說

 

0x0.棧溢出

  棧溢出一般都是CTF中,PWN類別的第一題。基本思想就是覆蓋棧中返回地址啦,這個誰都知道。這種題一定會有NX保護,怎么跳是問題。常見的是leak出一個函數的got表,leak方法題中一定會給出的,然后看看有沒有給出libc。如果有libc就能算system()和/libc/sh的地址了,直接溢出就OK了。如果沒有libc的話,如果能構造一個無限次循環的漏洞函數的話,可以使用pwn庫的DynELF函數找出system地址,再想方設法的往一個地方寫個/libc/sh就可以了(因為DynELF沒法泄漏字符串的地址)。如果這道題比較簡單的話,出題人會在程序里調用system()函數,這樣你直接跳過去用就可以了。

  基本的思路就是這些,如果不能(不樂意)使用DynELF函數就可以使用ret2dl_resolve方法了,這兩者是差不多的。之前寫過的www.Ox9A82.com/Ox9A82/p/5487275.html

  還有一種就是x64下的棧溢出,因為x64並不是通常的使用棧傳遞參數,而是把參數放在寄存器中傳遞所以不能直接的去布置參數了。但是,可以有通用的gadgets來用。http://www.Ox9A82.com/Ox9A82/p/5487725.html這個是用來布置參數加執行,而且可以構成rop鏈。

  另外的是,如果有canary保護的話,可能就不是棧溢出(或者不是要去覆蓋返回地址了),因為canary對於直接的覆蓋返回地址來說是沒辦法繞過的。

總體思路如下:

 

0x1.格式化字符串

  格式化字符串的題,一般都比棧溢出分值高一檔。格式化字符串漏洞找起來應該還是相當的容易的,主要格式化串是否可控即可。對於傳統的格式化字符串漏洞來說,只要在格式化串中帶有要進行寫入的目標地址即可,使用%1000x來形成1000字符,使用%4$n來指定棧中的參數即可達到目的。而現在很多人不這么玩了,很多出題人把格式化串放到堆或是bss段中,這樣你就不能像傳統的那樣去讀取格式化串中的目標地址了,不在棧中你是不可能讀到的。對於這種題目的做法就是要進行兩次漏洞利用,第一次在棧中構造跳板。第二次利用跳板去進行任意地址寫。具體的說就是:第一次:在棧中找一個指向棧里面的指針(這種指針肯定會有,因為堆棧框架就是這樣的),往這個棧的地方寫入第二次要寫入的地址。第二次:就跟正常利用一樣了,使用前面輸入的那個進行任意地址寫。

  然后要明確的一點是,格式化字符串漏洞的本質是任意地址寫。所以參數構造也是一個問題,因為不像棧溢出,棧溢出了參數就構造出來了。任意地址寫參數可能沒地方搞。另外注意一點是:要注意開沒開nx、要注意開沒開nx、要注意開沒開nx。重要的事情說三遍。因為沒開nx的話,幾乎就是明晃晃的說,往我的堆/bss寫shellcode吧,我可以執行。

總體思路:

 

0x2.堆

  對於堆進行考察的題一般都處於壓軸的位置。我個人認為堆的應該分為兩種,即堆的漏洞和模擬堆的漏洞。先說模擬堆的漏洞,這種題並不是真的在考堆的漏洞利用。而且出題人自己利用鏈表去模擬出一個堆來,更恰當的說我認為應該叫鏈表漏洞。這類題的一大特征就是給出了一個內存塊的詳細構造,比如有一個前向指針、一個后向指針(雙鏈表)、有一個放用戶名的域、有一個放編號的域等等。這個是在模擬一種堆的管理機制,所以最大的區別在於這個東西它沒有check機制,不像堆一樣有溢出保護機制。這種出法或者有溢出有unlink導致任意地址寫等玩法。

  再來說真正的考察堆漏洞的,因為堆是有溢出保護的,unlink的宏在進行unlink之前會檢查當前的指針合不合法,這個在題中的體現就是有的題會在bss段中存放每個塊的指針,利用這個指針就可以bypass保護機制。然后就是利用方法,這個在之前也寫過,就是去偽造兩個堆塊,利用堆的空塊合並機制。當然了,首先得有堆溢出,沒有溢出你拿什么去偽造堆塊。偽造的目的是構造如下情況:

在灰色的原堆塊中搞了個新的偽空堆塊出來(注意,是通過堆溢出,溢出下一堆塊頭部實現的構造偽空堆塊)。然后,我們再想辦法去釋放橙色堆塊,就引發了空塊合並機制。

最后談談經驗,不一定對,就是做了幾個題總結出來的。首先堆的題很多情況下不只是一個漏洞,往往有個什么整數溢出啊棧溢出啊什么的做輔助利用。然后就是堆的題一般都是標准的選單程序,就是給你個類似於記事本的功能選單,有什么新建筆記、編輯筆記、刪除筆記、查看筆記之類的。一般都是先看新建的功能,因為通過新建功能可以看出分配的結構是什么樣的,和怎么分配的。而刪除功能往往都是用來進行free的。編輯筆記是經常設置漏洞的出題點。查看筆記可能會用於leak東西。

 

0x3.End

最后說下調試,因為用python庫寫exp(如pwn庫和zio庫)時都是打本地的,而且都是自動的,所以調試起來就很難辦。可以在py中加入raw_input("wait input");來中斷一下,然后用gdb附加。附加方法是gdb attch pid,pid可以用看pid的命令得到,也可以gdb attch `pidof elf文件名`來實現附加到進程上。而且還有一個好處就是脫離調試器后進程不會終止,這是和windows不一樣的地方。但是注意調exp的時候如果python腳本退出了是會殺掉進程的,所以要保證python腳本不能提前退出,比如可以在最后加上.interact()函數來防止退出。

個人實在不是太喜歡Linux,所以也都是因為做比賽才來接觸。感覺PWN這個東西積累很重要,套路也很重要。


免責聲明!

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



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