記一次有趣的 buffer overflow detected 問題分析

来源:https://www.cnblogs.com/Iflyinsky/archive/2023/10/22/17780890.html
-Advertisement-
Play Games

1. on-my-zsh安裝 1.1. 使用curl方式安裝 1.1.1 官方鏡像源 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 1.1.2 國內Git ...


PS:要轉載請註明出處,本人版權所有。

PS: 這個只是基於《我自己》的理解,

如果和你的原則及想法相衝突,請諒解,勿噴。

環境說明

  無

前言


  在我開發的一個實驗和學習庫中,在很久以前全面啟用了編譯器的sanitize功能。

  這次報錯的程式,是我這個庫中某個模塊的單元測試模塊。但是前面說的都不是重點。詭異的是本次出現的單元測試模塊是很久未動的一個模塊,而且在本地的單元測試過程中,是能夠運行通過的,但是在github的ci上面出問題了。

  首先,報這個錯誤的原因肯定是我們的程式有問題,但是以前結合調試模式+sanitize功能基本能夠把問題排除了,結合了github的ci出現問題,初步判斷是由於GCC版本升級後,對於棧溢出的檢查更加準確了。

  此外由於此報錯是存在在一個release版本的模塊,因此我們不能夠採取通用的通過代碼行來定位問題的方法。

問題初步定位


  首先gdb 初步分析定位,定位到如下地址:

#4  0x00007ffff6a4db81 in __GI___fortify_fail (msg=msg@entry=0x7ffff6acf7e6 "buffer overflow detected") at fortify_fail.c:44
#5  0x00007ffff6a4b870 in __GI___chk_fail () at chk_fail.c:28
#6  0x00007ffff79c06fc in ?? () from ../lib/libylib.so.0

從這裡可以知道,我們在執行0x00007ffff79c06fc前面的一個指令的時候出現了"buffer overflow detected"。然後我們通過layout asm查看彙編指令,找到前面一行指令如下:

0x7ffff79c06f2:	b9 00 10 00 00       	mov    $0x1000,%ecx
0x7ffff79c06f7:	e8 44 1e fe ff       	callq  58540 <__memset_chk@plt>
0x7ffff79c06fc:	4c 89 e2             	mov    %r12,%rdx

  其實到了這裡,我們可以根據一些手段,可以查到是memset導致了我們的原因,如果要是可以進行源碼調試的話,我們甚至馬上就能夠定位是哪一行導致的。

  但是今天這裡提供一種方法,可以複雜定位(相容一個庫裡面多個memset調用,相容release版本調試等等)我們出錯這行彙編在我們源碼中的大概位置。





問題初步定位


  首先,我們查看一下當前我們這個so文件在記憶體中的映射位置:

          Start Addr           End Addr       Size     Offset objfile
      0x7ffff794a000     0x7ffff7bc2000   0x278000        0x0 /xxx/libylib.so.0.1.0
      0x7ffff7bc2000     0x7ffff7dc2000   0x200000   0x278000 /xxx/libylib.so.0.1.0
      0x7ffff7dc2000     0x7ffff7dcc000     0xa000   0x278000 /xxx/libylib.so.0.1.0
      0x7ffff7dcc000     0x7ffff7dd1000     0x5000   0x282000 /xxx/libylib.so.0.1.0

  首先我們可以分析出0x7ffff79c06f7是存在在記憶體映射0x7ffff794a000~0x7ffff7bc2000區段中的。此外,我們還知道了一個重要的消息是,當前我們關註的0x7ffff79c06f7在so中的偏移地址是0x7ffff79c06f7-0x7ffff794a000=0x766F7。

  這個時候,我們可以通過objdump -d對libylib.so.0.1.0進行反編譯分析。註意,這裡要往我們關註的0x766F7偏移前面去尋找,而且還要反覆去尋找,直到找到類似函數的邊界(這裡我建議新手直接上ida,快速解決問題),一般來說就是找函數幀,如果對這個不熟悉,建議使用ida等工具進行分析,可能更加方便。

libylib.so.0.1.0:     file format elf64-x86-64


Disassembly of section .text:

00000000000764d0 <_ZNSt6vectorIhSaIhEE17_M_default_appendEm@@Base+0x2b0>:
   764d0:	fe                   	(bad)  
   764d1:	fd                   	std    
   764d2:	ff 90 66 90 66 2e    	callq  *0x2e669066(%rax)
   764d8:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
   764df:	00 

00000000000764e0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base>:
   764e0:	48 8b 05 81 b4 40 00 	mov    0x40b481(%rip),%rax        # 481968 <_ZN4yLib6yShell10class_infoE@@Base-0x5058>
   764e7:	c3                   	retq   
   764e8:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
   764ef:	00 
   //註意這裡開始
   764f0:	41 57                	push   %r15
   764f2:	41 56                	push   %r14
   764f4:	49 89 fe             	mov    %rdi,%r14
   764f7:	41 55                	push   %r13
   764f9:	41 54                	push   %r12
   764fb:	55                   	push   %rbp
   764fc:	48 89 d5             	mov    %rdx,%rbp
   764ff:	53                   	push   %rbx
   76500:	48 81 ec a8 00 00 00 	sub    $0xa8,%rsp
   76507:	48 8b 56 08          	mov    0x8(%rsi),%rdx
   7650b:	48 2b 16             	sub    (%rsi),%rdx
   7650e:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
   76515:	00 00 
   76517:	48 89 84 24 98 00 00 	mov    %rax,0x98(%rsp)
   7651e:	00 
   7651f:	31 c0                	xor    %eax,%eax
   76521:	48 8b 47 08          	mov    0x8(%rdi),%rax
   76525:	48 2b 07             	sub    (%rdi),%rax
   76528:	48 c1 fa 05          	sar    $0x5,%rdx
   7652c:	48 c1 f8 05          	sar    $0x5,%rax
   76530:	48 8d 7c 02 01       	lea    0x1(%rdx,%rax,1),%rdi
   76535:	48 89 f8             	mov    %rdi,%rax
   76538:	48 c1 e8 3c          	shr    $0x3c,%rax
   7653c:	0f 85 67 54 fe ff    	jne    5b9a9 <fwrite@plt+0x1221>
   76542:	48 c1 e7 03          	shl    $0x3,%rdi
   76546:	49 89 f4             	mov    %rsi,%r12
   76549:	48 89 cb             	mov    %rcx,%rbx
   7654c:	e8 2f dc fd ff       	callq  54180 <_Znam@plt>
   76551:	49 8b 7e 08          	mov    0x8(%r14),%rdi
   76555:	49 8b 14 24          	mov    (%r12),%rdx
   76559:	49 89 c5             	mov    %rax,%r13
   7655c:	49 8b 74 24 08       	mov    0x8(%r12),%rsi
   76561:	49 8b 06             	mov    (%r14),%rax
   76564:	48 29 d6             	sub    %rdx,%rsi
   76567:	48 29 c7             	sub    %rax,%rdi
   7656a:	49 89 f9             	mov    %rdi,%r9
   7656d:	49 89 f2             	mov    %rsi,%r10
   76570:	49 89 f0             	mov    %rsi,%r8
   76573:	48 01 c7             	add    %rax,%rdi
   76576:	49 c1 f9 05          	sar    $0x5,%r9
   7657a:	49 c1 fa 05          	sar    $0x5,%r10
   7657e:	4b 8d 0c 11          	lea    (%r9,%r10,1),%rcx
   76582:	49 c7 44 cd 00 00 00 	movq   $0x0,0x0(%r13,%rcx,8)
   76589:	00 00 
   7658b:	4c 89 e9             	mov    %r13,%rcx
   7658e:	4d 85 c9             	test   %r9,%r9
   76591:	74 19                	je     765ac <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xcc>
   76593:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
   76598:	48 8b 30             	mov    (%rax),%rsi
   7659b:	48 83 c0 20          	add    $0x20,%rax
   7659f:	48 83 c1 08          	add    $0x8,%rcx
   765a3:	48 89 71 f8          	mov    %rsi,-0x8(%rcx)
   765a7:	48 39 c7             	cmp    %rax,%rdi
   765aa:	75 ec                	jne    76598 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xb8>
   765ac:	4d 85 d2             	test   %r10,%r10
   765af:	74 23                	je     765d4 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xf4>
   765b1:	48 89 d0             	mov    %rdx,%rax
   765b4:	4b 8d 54 cd 00       	lea    0x0(%r13,%r9,8),%rdx
   765b9:	4a 8d 34 00          	lea    (%rax,%r8,1),%rsi
   765bd:	0f 1f 00             	nopl   (%rax)
   765c0:	48 8b 08             	mov    (%rax),%rcx
   765c3:	48 83 c0 20          	add    $0x20,%rax
   765c7:	48 83 c2 08          	add    $0x8,%rdx
   765cb:	48 89 4a f8          	mov    %rcx,-0x8(%rdx)
   765cf:	48 39 f0             	cmp    %rsi,%rax
   765d2:	75 ec                	jne    765c0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xe0>
   765d4:	48 8b 7d 08          	mov    0x8(%rbp),%rdi
   765d8:	48 2b 7d 00          	sub    0x0(%rbp),%rdi
   765dc:	48 c1 ff 05          	sar    $0x5,%rdi
   765e0:	48 83 c7 01          	add    $0x1,%rdi
   765e4:	48 89 f8             	mov    %rdi,%rax
   765e7:	48 c1 e8 3c          	shr    $0x3c,%rax
   765eb:	0f 85 93 0a 00 00    	jne    77084 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xba4>
   765f1:	48 c1 e7 03          	shl    $0x3,%rdi
   765f5:	e8 86 db fd ff       	callq  54180 <_Znam@plt>
   765fa:	48 8b 75 08          	mov    0x8(%rbp),%rsi
   765fe:	48 89 c2             	mov    %rax,%rdx
   76601:	48 89 44 24 08       	mov    %rax,0x8(%rsp)
   76606:	48 8b 45 00          	mov    0x0(%rbp),%rax
   7660a:	48 29 c6             	sub    %rax,%rsi
   7660d:	48 89 f1             	mov    %rsi,%rcx
   76610:	48 01 c6             	add    %rax,%rsi
   76613:	48 c1 f9 05          	sar    $0x5,%rcx
   76617:	48 8d 3c ca          	lea    (%rdx,%rcx,8),%rdi
   7661b:	48 c7 07 00 00 00 00 	movq   $0x0,(%rdi)
   76622:	48 85 c9             	test   %rcx,%rcx
   76625:	74 1d                	je     76644 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x164>
   76627:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)
   7662e:	00 00 
   76630:	48 8b 08             	mov    (%rax),%rcx
   76633:	48 83 c0 20          	add    $0x20,%rax
   76637:	48 83 c2 08          	add    $0x8,%rdx
   7663b:	48 89 4a f8          	mov    %rcx,-0x8(%rdx)
   7663f:	48 39 c6             	cmp    %rax,%rsi
   76642:	75 ec                	jne    76630 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x150>
   76644:	48 c7 07 00 00 00 00 	movq   $0x0,(%rdi)
   7664b:	48 8b 35 06 b2 40 00 	mov    0x40b206(%rip),%rsi        # 481858 <_ZSt7nothrow@GLIBCXX_3.4>
   76652:	bf 00 10 00 00       	mov    $0x1000,%edi
   76657:	e8 b4 2d fe ff       	callq  59410 <_ZnamRKSt9nothrow_t@plt>
   7665c:	48 8d 7c 24 28       	lea    0x28(%rsp),%rdi
   76661:	48 89 c5             	mov    %rax,%rbp
   76664:	48 8b 05 5d 1c 1a 00 	mov    0x1a1c5d(%rip),%rax        # 2182c8 <_ZTSNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN4yLib11yThreadPoolEFvvEPS4_EEEEEE@@Base+0x4e8>
   7666b:	48 89 44 24 28       	mov    %rax,0x28(%rsp)
   76670:	e8 fb 1c fe ff       	callq  58370 <pipe@plt>
   76675:	85 c0                	test   %eax,%eax
   76677:	0f 88 69 03 00 00    	js     769e6 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x506>
   7667d:	e8 4e e5 fd ff       	callq  54bd0 <fork@plt>
   76682:	41 89 c4             	mov    %eax,%r12d
   76685:	85 c0                	test   %eax,%eax
   76687:	0f 88 08 07 00 00    	js     76d95 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x8b5>
   7668d:	0f 84 1d 01 00 00    	je     767b0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x2d0>
   76693:	8b 7c 24 2c          	mov    0x2c(%rsp),%edi
   76697:	e8 24 3e fe ff       	callq  5a4c0 <close@plt>
   7669c:	48 8d 74 24 1c       	lea    0x1c(%rsp),%rsi
   766a1:	31 d2                	xor    %edx,%edx
   766a3:	44 89 e7             	mov    %r12d,%edi
   766a6:	e8 55 00 fe ff       	callq  56700 <waitpid@plt>
   766ab:	8b 44 24 1c          	mov    0x1c(%rsp),%eax
   766af:	a8 7f                	test   $0x7f,%al
   766b1:	0f 85 8a 07 00 00    	jne    76e41 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x961>
   766b7:	0f b6 cc             	movzbl %ah,%ecx
   766ba:	f6 c4 ff             	test   $0xff,%ah
   766bd:	0f 85 cd 03 00 00    	jne    76a90 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x5b0>
   766c3:	8b 7c 24 28          	mov    0x28(%rsp),%edi
   766c7:	48 8d 35 52 cb 1c 00 	lea    0x1ccb52(%rip),%rsi        # 243220 <_ZTSN4Json12RuntimeErrorE@@Base+0x60>
   766ce:	e8 cd 0d fe ff       	callq  574a0 <fdopen@plt>
   766d3:	49 89 c4             	mov    %rax,%r12
   766d6:	48 85 ed             	test   %rbp,%rbp
   766d9:	0f 84 f1 02 00 00    	je     769d0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x4f0>
   766df:	4c 8d 74 24 70       	lea    0x70(%rsp),%r14
   766e4:	0f 1f 40 00          	nopl   0x0(%rax)
   766e8:	31 f6                	xor    %esi,%esi
   766ea:	ba 01 10 00 00       	mov    $0x1001,%edx
   766ef:	48 89 ef             	mov    %rbp,%rdi
   766f2:	b9 00 10 00 00       	mov    $0x1000,%ecx
   766f7:	e8 44 1e fe ff       	callq  58540 <__memset_chk@plt>
   766fc:	4c 89 e2             	mov    %r12,%rdx

  我們往此偏移往上查找,找到了764f0偏移的特殊指令,這裡一看就是一個函數的開始位置(這裡為啥是函數開始,主要是操作備份rbp,申請棧,操作rsp等等)。

  這裡其實又有兩個選擇,我們在分析函數頭的過程中,其實已經找到了足夠多的我們想要找的函數特征:例如這裡調用了fork/pipe/fdopen等等,如果情況是這樣的,那麼其實我們可以綜合分析,找到我們源碼對應出錯的位置了。

  那如果我們的函數平平無奇,沒有什麼明顯特征怎麼搞呢?還是只有利用我們的函數頭來判斷,到底是我們寫的哪個函數出問題了。

  於是我們拿著764f0偏移,通過readelf -s來查找符號,發現不是任何一個我們已知的符號,這尼瑪就坑了啊。到了這裡,其實現在不好搞啊。我們用gdb record / ida / objdump + grep 來綜合分析,發現了跳轉到當前地址的一個地方。下麵是用readelf+objdump+grep來得到的一段片段:

   764f0:	41 57                	push   %r15
   77090:	e9 5b f4 ff ff       	jmpq   764f0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x10>

  我們再次用objdump和readelf查找77090這個偏移,終於在符號表查到了我們關心的這個偏移,如下:

   559: 0000000000077090     5 FUNC    GLOBAL DEFAULT   12 _ZN4yLib6yShell7ExecuteERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_SB_RS9_

  到此,通過複原cxx函數名字,我們就知道了我們在哪個函數裡面崩潰的,而且是在這個函數的memset的地方導致溢出崩潰的。





後記


  此問題的分析加深了我們對電腦的理解,使用了較多的二進位分析工具。

  結合我以前的調試和反調試經驗,新手我還是建議直接上刑具ida進行分析,這樣更棒哦。

參考文獻




打賞、訂閱、收藏、丟香蕉、硬幣,請關註公眾號(攻城獅的搬磚之路)
qrc_img

PS: 請尊重原創,不喜勿噴。

PS: 要轉載請註明出處,本人版權所有。

PS: 有問題請留言,看到後我會第一時間回覆。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 函數是一段代碼塊,只有在調用時才會運行。您可以將數據(稱為參數)傳遞給函數。 函數可以返回數據作為結果。 創建函數 在Python中,使用def關鍵字定義函數: 示例 def my_function(): print("Hello from a function") 調用函數 要調用函數,請使用函數 ...
  • Python流程式控制制是Python編程中非常重要的一部分,它用於控製程序的執行流程。Python提供了多種流程式控制制語句,包括if語句、while迴圈、for迴圈、break和continue語句等。這種流程式控制制在各個語言中都是大同小異的,如果你已經學過其他的語言,那麼這章節就可以直接跳過。 if語句 ...
  • 模板智能數組指針 1.管理任意類型的數組指針 2.釋放的時候自動刪除數組指針指向的記憶體 //模板智能數組指針 template<typename T> class AiArrayPtr { public: AiArrayPtr(T *pArray) { m_pAiPtr = pArray; m_bI ...
  • 通過前面13天的學習,對Dart基礎有了系統的熟悉,今天我們開始學習Dart類和對象,本文主要學習Dart類,包括類方法,構造器,對象類型,實例變數,隱性介面,類變數和類方法等…… ...
  • 【學習課程】:【【小白入門 通俗易懂】2021韓順平 一周學會Linux】 https://www.bilibili.com/video/BV1Sv411r7vd/?p=14&share_source=copy_web&vd_source=2c07d62293f5003c919b2df9b2e054 ...
  • 在 Linux 系統中,/proc和/sys都是特殊的文件系統,數據內容是存放在記憶體中,這兩個目錄文件中的內容由內核動態生成,查看這個文件中的內容,實際上就是查詢內核的某些狀態或信息。 可以將這兩個目錄文件理解為虛擬的目錄,即在硬碟上不存在。 /proc 文件系統 proc 是process(進程) ...
  • 導讀: 本文系原創,歡迎規範轉載。 本文描述瞭如何處理linux虛擬機從xen虛擬化遷移kvm虛擬化遇到問題,包括重建initramfs,處理未卸載的tools等。 系列文章: xen2kvm遷移-Windows篇 xen2kvm遷移-Linux篇 遷移環境: 源平臺:華為FusionCompute ...
  • 痞子衡嵌入式半月刊: 第 83 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...