【C++】匯編角度分析棧攻擊

棧攻擊

  • 介紹原理
  • 示例代碼
  • 匯編分析

介紹原理

核心原理是通過 緩沖區溢出(Buffer Overflow) 等漏洞,覆蓋棧上的關鍵數據(如返回地址、函數指針),從而改變程序執行流程;

在 C++ 中,每個函數調用都會在棧上創建一個棧幀(Stack Frame),包含:

  • 局部變量:函數內定義的變量。
  • 函數參數:調用函數時傳遞的參數。
  • 返回地址:函數執行完后返回的地址(保存在 EIP 寄存器)。
  • 幀指針(EBP):指向當前棧幀的基址。
    棧內存是向下增長的(從高地址向低地址)

緩沖區溢出攻擊
當程序向緩沖區寫入數據時,若未檢查輸入長度,可能導致數據超出緩沖區邊界,覆蓋相鄰的棧內存區域。攻擊者可利用這一點:

  1. 覆蓋返回地址為惡意代碼的地址。放置攻擊者指定的地址(如 shellcode 的起始地址
  2. 在棧上注入惡意代碼(如 shellcode)。
  3. 觸發溢出:當函數返回時,程序ret到攻擊者指定的地址執行;

示例代碼

下面示例代碼就是通過緩沖區溢出覆蓋掉棧的ret返回的地址從而改變函數返回后程序執行的地址(篡改為攻擊函數地址);
大致流程:

  1. 先得到攻擊函數Hack地址
  2. 調用count函數時候通過數組溢出方式,通過分析匯編代碼,將匯編ret的地址修改為我們的Hack函數的地址
  3. 如此,count函數返回后程序就會沿著我們修改的Hack方向運行;
#include <iostream>
#include <iomanip>void Hack()
{unsigned long long x = 0;for (int i = 0; true; i++){if (i % 100000000 == 0){system("cls");std::cout << "\n■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\n";std::cout << "\n 你的系統已經被我們拿下! hacked by 黑兔檔案局:[ID:000001 ]\n";std::cout << "\n\\>正在傳輸硬盤數據....已經傳輸" << x++ << "個文件......\n\n";std::cout << std::setfill('>')<< std::setw(x % 60) << "\n";std::cout << "\n\\>攝像頭已啟動!<==============\n\n";std::cout << std::setfill('#') << std::setw(x % 60) << "\n";std::cout << "\n\\>數據傳輸完成后將啟動自毀程序!CPU將會溫度提升到200攝氏度\n";std::cout << "\n■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\n";}}
}int GetAge()
{int rt;std::cout << "請輸入學員的年齡:";std::cin >> rt;return rt;
}int count()
{int i{};int total{};int age[10]{};do{age[i] = GetAge();total += age[i];//將AGE[I]保存到數據庫中} while (age[i++]);return total;
}int main()
{std::cout << "======= 驢百萬學院 學員總年齡統計計算系統 =====\n";std::cout << "\n                API:"<<Hack<<std::endl;std::cout << "\n[說明:最多輸入10個學員的信息,當輸入0時代表輸入結束]\n\n";std::cout << "\n驢百萬學院的學員總年齡為:" << count();
}

匯編分析

直接從count函數匯編入手:

int count()42: {
00061200  push        ebp  //當前函數調用前的基址指針(Base Pointer,通常用來指向當前函數的棧幀)壓入棧中,以便后續在函數結束時能夠恢復到調用前的狀態。
00061201  mov         ebp,esp  //將當前棧指針(Stack Pointer,指向當前棧頂)的值賦給基址指針 ebp,這樣 ebp 現在指向當前函數count的棧幀
00061203  sub         esp,34h  //esp=esp-52,這條指令將棧指針 esp 減去 0x34h(52 的十進制值),這樣就為當前函數的棧幀分配了 52 字節的空間。在函數執行過程中,局部變量和其他數據將會存儲在這段空間中。43: 	int i{};
00061206  mov         dword ptr [i],0  // 0移動到變量 i 所在的內存位置。dword ptr 來指示操作數(內存里的數據)的大小為雙字(32 位,4字節),這是因為 i 是一個整數類型變量。44: 	int total{};
0006120D  mov         dword ptr [total],0  45: 	int age[10]{};
00061214  xor         eax,eax  //將寄存器 eax 與自身進行異或操作,結果存儲回 eax。這個操作的目的是將 eax 清零,因為在這段代碼中,eax 被用來存儲數組 age 的起始地址。
00061216  mov         dword ptr [age],eax  
00061219  mov         dword ptr [ebp-30h],eax  //48字節偏移量
0006121C  mov         dword ptr [ebp-2Ch],eax //44 
0006121F  mov         dword ptr [ebp-28h],eax  
00061222  mov         dword ptr [ebp-24h],eax  
00061225  mov         dword ptr [ebp-20h],eax  
00061228  mov         dword ptr [ebp-1Ch],eax  
0006122B  mov         dword ptr [ebp-18h],eax  
0006122E  mov         dword ptr [ebp-14h],eax  
00061231  mov         dword ptr [ebp-10h],eax  //16

在這里插入圖片描述
棧底ebp存的就是count函數的下一條地址,我們目的是修改這一個地址;

這段代碼對應函數棧如下:

在這里插入圖片描述

46: 	do47: 	{48: 		age[i] = GetAge();
00061234  call        GetAge (0611D0h)  //調用了一個函數 GetAge,并將返回值存儲在寄存器 eax 中。
00061239  mov         ecx,dword ptr [i]  //將變量 i 的值加載到寄存器 ecx 中  ecx=i =0  ecx=i=1
0006123C  mov         dword ptr age[ecx*4],eax  //此時將寄存器 eax 中的年齡age存儲到 age[ecx*4] 中,age[ecx*4]將age數組的內存地址偏移ecx*4個字節。此時ecx*4 是因為 age 是一個數組,每個元素占據 4 個字節。 age[0] = eax =age0 age[1] = eax =age149: 		total += age[i];
00061240  mov         edx,dword ptr [i]  //將變量 i 的值加載到寄存器 edx 中  edx =i= 0   edx =i= 1
00061243  mov         eax,dword ptr [total] // 將變量 total 的值加載到寄存器 eax 中  eax = total
00061246  add         eax,dword ptr age[edx*4]  //[]里的理解為字節的位置,而不是元素,將 age[i] 的值加到 total 中     eax = eax+age[0]+age[1]
0006124A  mov         dword ptr [total],eax //將寄存器 eax 中的值存儲回變量 total 中。    total = eax50: 		//將AGE[I]保存到數據庫中51: 	} while (age[i++]);  //就是讓i++并且判斷是否這次輸入的age[i]==0
0006124D  mov         ecx,dword ptr [i]  //將變量 i 的值加載到寄存器 ecx 中    ecx=i=0
00061250  mov         edx,dword ptr age[ecx*4]  //V將 age[i] 的值加載到寄存器 edx 中  edx = age[0]//edx值放在[ebp-0Ch]這篇內存應該是專門為了與0比較開辟的內存
00061254  mov         dword ptr [ebp-0Ch],edx  //將寄存器 edx 中的值存儲到內存中的位置 [ebp-0Ch]。ebp-12 
00061257  mov         eax,dword ptr [i]  //將變量 i 的值加載到寄存器 eax 中   eax = i =0
0006125A  add         eax,1  //將寄存器 eax 中的值加 1		eax = eax+1
0006125D  mov         dword ptr [i],eax  //將寄存器 eax 中的值存儲回變量 i 中   i = eax
00061260  cmp         dword ptr [ebp-0Ch],0 //將內存中的位置 [ebp-0Ch]ebp-12 的值與 0 比較    age[0]與0比較
00061264  jne         count+34h (061234h)  //如果不相等,則跳轉到 count+34h(52) 處執行  //查詢 count  0x00061200h  +34h后是0x00061234。跳到了call GetAge處52: 	return total;
00061266  mov         eax,dword ptr [total]  // total 變量的值加載到寄存器 eax 中53: }
//函數清尾
00061269  mov         esp,ebp  
0006126B  pop         ebp  //在pop ebp指令中,ebp是一個操作數,指示將棧頂元素彈出并將其存儲到ebp寄存器中
0006126C  ret  //此時已經返回了[total]算出了正確total,運行結束!

在這里插入圖片描述

注意:下面這張圖的代碼age數組是改為5的,對應下面圖片,最后輸入的就是Hack的API地址,此時替換為了原來ret指向的地址;
在這里插入圖片描述

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

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

相關文章

訪問 Docker 官方鏡像源(包括代理)全部被“重置連接”或超時

華為云輕量應用服務器&#xff08;Ubuntu 系統&#xff09; 遇到的問題是&#xff1a; &#x1f512; 訪問 Docker 官方鏡像源&#xff08;包括代理&#xff09;全部被“重置連接”或超時了&#xff0c;說明你這臺服務器的出境網絡對這些國外域名限制很嚴格&#xff0c;常見于華…

Java語言

本文來源 &#xff1a; 騰訊元寶 Java是一種面向對象、跨平臺的高級編程語言&#xff0c;最初由Sun Microsystems&#xff08;現為Oracle公司所有&#xff09;于1995年推出&#xff0c;廣泛應用于Web開發、移動應用、大數據處理、嵌入式系統等領域。以下是其核心特點和應用概述…

無償幫寫畢業論文(看不懂的可以私信博主)

以下教程教你如何利用相關網站和AI免費幫你寫一個畢業論文。畢竟畢業論文只要過就行&#xff0c;脫產學習這么多年&#xff0c;終于熬出頭了&#xff0c;完成畢設后有空就去多看看親人好友&#xff0c;祝好&#xff01; 一、找一個論文模板 廢話不多說&#xff0c;先上干貨Ov…

python打卡day26

函數、參數、變量 知識點回顧&#xff1a; 函數的定義變量作用域&#xff1a;局部變量和全局變量函數的參數類型&#xff1a;位置參數、默認參數、不定參數傳遞參數的手段&#xff1a;關鍵詞參數傳遞參數的順序&#xff1a;同時出現三種參數類型時 def function_name(parameter…

LeetCode 熱題 100 437. 路徑總和 III

LeetCode 熱題 100 | 437. 路徑總和 III 大家好&#xff0c;今天我們來解決一道經典的二叉樹問題——路徑總和 III。這道題在 LeetCode 上被標記為中等難度&#xff0c;要求計算二叉樹中節點值之和等于給定目標值 targetSum 的路徑數目。 問題描述 給定一個二叉樹的根節點 ro…

vue3學習-局部使用vue框架案例

目錄 局部使用vue框架步驟 簡單案例1 簡單案例2【 結構化賦值語法】 簡單案例3【使用模塊化開發模式】 基本數據的簡單應用&#xff0c;對象的簡單應用 數組的簡單應用 局部使用vue框架步驟 1 引用 vue框架的核心文件和 涉及ES6語法的文件 注意&#xff1a;這里文件&am…

初識Linux · IP分片

目錄 前言&#xff1a; IP分片 分片vs不分片 如何分片 分片舉例 三個字段 前言&#xff1a; 前文IP協議上和IP協議下我們已經把IP協議的報頭的大多數字段介紹了&#xff0c;唯獨有三個字段現在還有介紹&#xff0c;即16位標識&#xff0c;8位協議&#xff0c;13位片偏移…

u3d 定義列表詳細過程

層級結構 - Canvas - Scroll View - Viewport - Content (Vertical Layout Group) - Item1 (Prefab) - Item2 (Prefab) ... 詳細設置步驟 1. 創建 Canvas 2. 添加 Scroll View 組件 3. 在 Scroll View 下創建 Content 子對象 4. 添加 …

產品方法論與 AI Agent 技術的深度融合:從決策智能到價值創造

一、引言&#xff1a;智能化時代的產品范式革命 在數字化轉型的深水區&#xff0c;產品開發正經歷著從 “功能定義” 到 “體驗設計” 再到 “智能演化” 的范式躍遷。麥肯錫 2024 年報告指出&#xff0c;采用 AI 驅動產品方法論的企業&#xff0c;新品研發周期平均縮短 40%&a…

力扣.1471數組的k個最強值,力扣.1471數組的k個最強值力扣1576.替換所有的問號力扣1419.數青蛙?編輯力扣300.最長遞增子序列

目錄 力扣.1471數組的k個最強值 力扣1576.替換所有的問號 力扣1419.數青蛙?編輯 力扣300.最長遞增子序列 力扣.1471數組的k個最強值 class Solution {public static int[] getStrongest(int[] arr,int k) {if(karr.length){return arr;}int []retnew int[k];int narr.lengt…

使用docker安裝clickhouse集群

1、簡介 clickhouse 作為大數據場景中&#xff0c;實現快速檢索的常用列式存儲數據庫&#xff0c;采用物理機部署&#xff0c;會在數據量大的場景中&#xff0c;物理機器存儲達到閾值需要擴容&#xff0c;會帶來比較大的問題&#xff0c;因此&#xff0c;使用docker部署clickho…

package-lock.json能否直接刪除?

package-lock.json能否直接刪除&#xff1f; package-lock.json 生成工具&#xff1a;由 npm 自動生成。 觸發條件&#xff1a;當運行 npm install 時&#xff0c;如果不存在 package-lock.json&#xff0c;npm 會創建它&#xff1b;如果已存在&#xff0c;npm 會根據它精確安…

如何在 Windows 命令提示符中創建多個文件夾和多個文件

如何在 Windows 命令提示符中創建多個文件夾和多個文件 雖然大多數用戶習慣使用 Windows 圖形界面來創建文件夾&#xff0c;但如果你需要一次性創建多個文件夾或文件&#xff0c;如同在類Unix系統中可以使用mkdir和touch命令一樣&#xff0c;windows下也有創建目錄和文件的對應…

leetcode - 滑動窗口問題集

目錄 前言 題1 長度最小的子數組&#xff1a; 思考&#xff1a; 參考代碼1&#xff1a; 參考代碼2&#xff1a; 題2 無重復字符的最長子串&#xff1a; 思考&#xff1a; 參考代碼1&#xff1a; 參考代碼2&#xff1a; 題3 最大連續1的個數 III&#xff1a; 思考&am…

Ubuntu20.04下如何源碼編譯Carla,使用UE4源碼開跑,踩坑集合

一、簡介 作為一個從事算法研究的人員,無人駕駛仿真一直是比較重要的一部分,但是現在比較常見的算法驗證都是在carla這個開源仿真平臺上做的,所以我有二次開發carla的需求,今天就來講講編譯CARLA。 網上的教材很多,但還是推薦大家看官網教程:Linux build - CARLA Simul…

Linux云計算訓練營筆記day09(MySQL數據庫)

Linux云計算訓練營筆記day09&#xff08;MySQL數據庫&#xff09; 目錄 Linux云計算訓練營筆記day09&#xff08;MySQL數據庫&#xff09;外鍵約束數據的導入和導出數據的導出數據的導入 DQL 數據查詢語言查指定字段查所有字段where 過濾條件and 和 orin 和 not inbetween...an…

對心理幸福感含義的探索 | 幸福就是一切嗎?

注&#xff1a;機翻&#xff0c;未校。 Happiness Is Everything, or Is It? Explorations on the Meaning of Psychological Well-Being 幸福就是一切嗎&#xff1f;對心理幸福感含義的探索 Journal of Personality and Social Psychology 1989, Vol. 57, No. 6,1069-1081 …

零基礎學Java——第十一章:實戰項目 - 微服務入門

第十一章&#xff1a;實戰項目 - 微服務入門 隨著互聯網應用的復雜性不斷增加&#xff0c;單體應用&#xff08;Monolithic Application&#xff09;在可擴展性、可維護性、技術棧靈活性等方面逐漸暴露出一些問題。微服務架構&#xff08;Microservices Architecture&#xff…

git 本地提交后修改注釋

dos命令行進入目錄&#xff0c;idea可以點擊Terminal 進入命令行 git commit --amend -m "修改內容"

Python訓練打卡Day22

復習日&#xff1a; 1.標準化數據&#xff08;聚類前通常需要標準化&#xff09; scaler StandardScaler() X_scaled scaler.fit_transform(X) StandardScaler() &#xff1a;這部分代碼調用了 StandardScaler 類的構造函數。在Python中&#xff0c;當你在類名后面加上括號…