ctfshow pwn pwn02 同時也作為入門題目無比細致講解分析 真0基礎入門


棧溢出是pwn的HelloWorld!

正所謂萬事開頭難,打開這篇文章也將可能成為你進入pwn世界的叩門石。由於本文過於詳細,會耽擱大佬很多時間,同時本人學識尚淺,如有錯誤請指正。

我們先打開題目
image
launch an instance創建容器,創建容器后就會顯示相應的host與port。
stack是可以下載的附件,就是我們要尋找漏洞的程序,點擊下載即可。
而我們剛入門的做題步驟就是:

  1. 下載附件stack,並找到漏洞。
  2. 利用工具,nc創建出的host與port,利用工具進行攻擊,得到權限后從host得到flag。

題目做法有很多,可以使用不同工具,但由於我是菜雞,就只講解一種方法

Diagnose:NOT Win EXE - .o - ELF [ 32bit obj. Exe file - CPU : Intel 80386 - OS/ABI: unspecified ]
緊隨其后的: -> Compiler : GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
大意就是32位的Ubuntu下的文件


我們也可以用pwntool工具中的checksec來檢測可執行文件開啟的各種安全機制(checksec講解(點擊跳轉)
image
簡單的說:
Stack:No canary found沒有防溢出。
NX:NX enabled不可執行的
PIE:No PIE()未使用隨機地址


恭喜你,你已經邁出了一大步ヽ(゚∀゚)メ(゚∀゚)ノ

image
打開后,看見花花綠綠的界面“我是誰,我在哪,我要去干什么”。別急,當你先會簡單使用IDA就沒什么問題了。
那么問題又來了,該干嘛?

  • 我們先看左側的FcuntionWindow里面的函數,不難發現存在一個main函數,眾所周知main函數為是程序執行的起點。我們雙擊他(其實一開始IDA-View-A顯示的就是),然后在IDA-View-A窗口看見匯編語言,可以按F5進行反匯編,開啟pseudocode-B窗口輸出偽代碼。
    image
  • setvbuf()函數相當於對文件流的規定,對文件進行操作,需要將磁盤中的文件寫入內存中,相應的會在內存區建立一個緩存區用於與磁盤交換數據。stdout是屏幕輸出設備,stdin是鍵盤輸入設備,在開機時自動打開,相當於將緩存區清0,可以做到及時輸入輸出,不會等到緩存區寫滿后才引入結果,對此不需要深究。詳細自行搜索,puts()輸出字符串,pwnme()函數,雙擊查看其定義
    image
    雙擊fgets()發現是:
    image

意義不明,其實是調用的庫函數,自行百度即可(上文的setvbuf()也是庫函數)
百度得到fgets()相當於對數組s,從stdin文件中輸入50個字節,但是注意char s;的長度。
按esc返回上一級,到pwnme()並雙擊char s;的s得到:
image
顯然s只有9字節大小,但是卻輸入了50個字節,未對輸入字節正確控制導致棧溢出,可通過這個漏洞干一票大的。


棧溢出漏洞(這時你可能需要一點內存知識了自行百度,多看一點集百家之言,自然會了解)(也有許多有趣的視頻
溢出溢出,字面上就是往容器里加的水超過了水的容積,簡單講,棧溢出就是向棧中某個變量中寫入的字節數超過了這個變量本身所申請的字節數,造成溢出。發生棧溢出的條件:程序必須向棧上寫入數據。寫入的數據大小沒有被良好地控制。利用方式:覆蓋程序的返回地址為攻擊者所控制的地址,比如該地址為執行shellcode的地址shellcode是一段用於利用軟件漏洞而執行的代碼,shellcode為16進制的機器碼,可以讓攻擊者獲得shell,利用pwntools可自動生成,等用到再說。
可能造成棧溢出的函數有:gets,scanf,vscanf,sprintf,strcpy,strcat,bcopy
摘自某大佬博客

  • 注意在+0000004處,就是s下面有一個r,這個r就是ret(Push, Pop, call, leave 和 Ret 指令圖解)我們可以通過輸入9字節占滿s的大小,然后+4覆蓋ret,讓其返回到我們想要到的地方(輕則破壞程序,重則得到shell)。
    • 為什么能做到這一點呢,就是因為棧的性質,棧是從高地址向下的,故從-00000009開始向下+00000000(此處為相對位置)存儲,由於未作出合理限制輸入,故可以繼續覆蓋低地址中存儲,ret因此被覆蓋。

  • 當然我們的目的不是破壞程序,是get shell。從左處FunctionWindow處可以看見還有很多沒用調用的函數,我們可以通過棧溢出,跳轉執行。
  • 可以從StringWindows(View->open subviews->string)處看見
    image

服務器一般架設在Linux內核之上,對於Linux來說一切都是文件的存在,而/bin存儲了許多系統可執行文件目錄:cat,mv,date.......
/bin/sh 就是Bourne shell

雙擊該處就可跳轉至
image
在根據右邊 stack+9↑o 雙擊后跳轉至相應的stack處並反編譯
image
看見了stack()函數調用了system("/bin/sh"),於是我們可以通過棧溢出跳轉至這里並執行。
既然要跳轉至stack(),我們相對應的也要知道其首地址,拉大FunctionWindows后可以看見image
從而得到0804850F


接下來就是我們Linux大顯身手的時候,本人用的是Kail。
我們將會使用pwntools工具(windows無法使用)

  • 進行編寫exp(exploit漏洞利用)
  • 編寫exp一般使用python3語言,相應的會使用pwn包(自行導入)進行操作

本人使用vim寫py代碼然后丟入py3中運行(注意縮進,由於個人問題縮進沒有顯現出來)。
from pwn import * //引入pwn包所有函數
content = 1
def main():
if content = 0
p = process("./stack")//這是連接本地文件,其實在這里沒什么用不寫也可以因為根本就不會執行
else:
p = remote("pwn.challenge.ctf.show",28040)//建立一個遠程連接需要相應URL/IP和port當然這就是在前面創建的容器(服務器)信息,將remote對象保存至變量p中
payload = b'a'*13//數據打包,由於前文提到的在s處填入9+4個字節
payload += p32(0x804850F)//同上,p32()將整數值轉為32位打包
p.send(payload)//調用對象p的方法,send()將shellcode送至服務器端
p.interactive()//將控制權交給用戶可使用打開的shell
main()

pwntools使用簡介(點擊跳轉)
pwntools各使用模塊簡介(點擊跳轉)
exploit利器-pwntools(點擊跳轉)
當然官方的說明才是最好最全的,但是剛入門就簡單了解一下看看文章即可(注意要博彩多家)


編輯好后執行得到:
image

根據顯示表明我們成功入侵對方,然后用ls查看對方/中文件,我們要的flag就赫然出現在第一個位置
image
最后我們cat flag(以只讀模式打開)flag,得到flag。
注意:連接上一段時間后會自動斷掉連接,此時再次執行腳本即可,所以手腳快一點。


(づ。◕ᴗᴗ◕。)づ<(▰˘◡˘▰)✧。٩(ˊᗜˋ)و✧。♪(^∀^●)ノ☆(≧∀≦)ノ


免責聲明!

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



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