缓冲区溢出
缓冲区溢出攻击是一个老生常谈的问题了,实际上我们所在的这个世界上,每天无时无刻不在发生各种各样的缓冲区溢出的攻击,随着反制技术的不断升级,这些攻击技巧都在大量进行升级还贷,但,所谓哪里有压迫哪里就有反抗!
ASLR(地址随机化)、DEP(数据执行保护)、ASCII armoring(地址插零),GS(调用 cookie)等方面的反制技术让攻击变的越来越困难,当人类被压迫的时候会想出各式各样的方法来解决这些问题,只是变得困难了但不是说不能进行攻击,例:DEP 保护 “rop_chains、ret2libc” 可以绕过它们,GS 调用 cookie 保护,有两类方式绕过,一靠猜【蒙】函数的调用 cookie 值(这是一个固定的值)另一种是想办法利用溢出强行覆盖 “SEH(结构化异常处理)catch_chains” 中的虚函数处理地址
ASCII armoring 保护;就是想办法让每个被加载程序地址空间的 libc 函数的地址中都具有一个 NULL 字节,从而让通过字符串拷贝的 libc 的地址无效,让攻击无从谈起,但人们的智慧是无穷的,当遇到了压迫人们就会奋起的进行反抗,所以 ret2plt 技术应用而生,它利用 PPR(pop %ebx pop %ebp retn)指令序组成一段连续的 strcpy or memcpy 函数把要被调用的函数地址的字节从不同的空间拷贝到栈上,然后在进行调用,从而绕过 “ASCII armoring” 的保护机制。
上面提到这些攻击技术几乎都是利用栈溢出攻击的,那么堆溢出是不是就真的安全?显然不是的,堆溢出攻击(unlink)相信很多人可能没有听过这个东西,这是一种专门 “堆溢出攻击” 提出的一门技术,它就是想办法利用目标程序的 “堆溢出” 的漏洞,把分配的 “堆内存” 的 “chunk header” 中的虚函数地址给覆盖了,malloc 分配的内存是连续的,即 malloc 两次内存之间的地址是相互连接在一起的(从高到低,跟栈差不多)而 “堆溢出” 就是想办法覆盖掉 “下个 malloc” 函数分配的 “chunk header” 中的 free addr 当 “程序” 调用第二次 free 函数时就会执行攻击的 shellcode。
所以没有真正安全程序与技术,它只是相对的,但这对我们来说有多大的意义?我本人在这里不说推销这些技术,而是首先我们需要明白一点,技术本身是无罪的,犯罪的只是别有用心的人而已,大多数所谓进行不法活动的人都是些在某些 XX 群里面交了点学费,拿了点资料跟工具就出来祸害人的 “小害虫”,提供工具的人水平不用质疑,但是没用到正道上面!
我们了解与研究这些技术,并不一定需要真的就去 “专精” 它们,因为我们想要沐浴在 “阳光之下”,不过这个也需要看每个人的选择,或许它们觉得这很 geek ,当然走 IA / MA / SA 也很 geek,只是大多数人不知道而已,它们之间只是发展方向上的不同而已,大多数做安全更多还是去搞 “竞品分析”,地位也不能和 2010 年之前相比了。
我个体只想走 “阳光正道”,不喜欢走这些东西,而且我的确从打心底来说,并不是那种特别喜欢这些东西的人,但我还是要了解与研究它们?原因是为了更好的防护的我的 “程序” 当我不知道它们的攻击手法,你不可能在软件在做 “瀑布设计” 与 “敏捷开发” 过程中兼顾并考虑到这些问题,那么又从何去解决问题减少损失?坐等 “杀毒流氓、微软” 这些去打补丁?或者说不用考虑的直接关闭我的程式或服务器?但当我们知晓了我自然有更好的办法能够解决这些问题,减少损失不是更好?
本文只提供 jmp esp 的方式,虽然这个方式在现代来说根本不能用,但是就了解缓冲区溢出攻击是一个很不错的入门试验,后面我可能会写基于 ROP_chains 或 ret2libc 攻击的利用方式,但它们本质是想通的,只是变得更加的麻烦跟费神,但不是说不能应用,其实市面上还有很多可以通过这几类方法利用的漏洞,你不得不说大多数人包括公司的安全意识真的太差劲了。
但是要运行本文给出的代码,你必须要在 C/C++ 编译器与连接器配置中关闭掉 “GS” 与 “DEP”,DEP主要是为了防止 “不具有 PAGE_EXECUTE_READ ” 内存标志,权限的二进制代码数据的执行,而 JMP ESP 是把 shellcode 复制到栈上执行的,而栈上的内存是不具有 “PAGE_EXECUTE_READ” 的权限的,只有 PAGE_READWRITE 的权限,不过这个问题可以利用 ROP_chains 进行绕过。
参考上述要进行试验的 C/C++ 配置,说实话这个东西,如果靠给人讲其实并不是形象(有点抽象)或许说了很多其实到最后面人们可能还是没有理解,所以本文将提供可被编译且正确运行的 “C语言示意代码” 用于阐述本文的内容。
#include <stdlib.h>
#include <stdio.h>
static unsigned char shellcode[] =
{
0,0,0,0, // ebp-8
0,0,0,0, // ebp-4
0,0,0,0, // ebp-0
0,0,0,0, // ebp+4(retn addr == RIP) -- JMP ESP
//
184,0,0,0,0, // MOV EAX,fun_hijacked
255,224, // JMP EAX
};
static void fun_hijacked()
{
printf("Attack successful");
getchar();
exit(0);
}
static void fun_bug()
{
int n; // ebp-8
memcpy(&n, shellcode, sizeof(shellcode));
}
static void fun_def_jmp_esp()
{
__asm
{
jmp esp
jmp esp
jmp esp
}
}
static void* fun_get_jmp_esp_addr()
{
unsigned char* p = &fun_def_jmp_esp;
while (1)
{
if (p[0] == 0xFF && p[1] == 0xE4) // jmp esp
{
return p;
}
p++;
}
}
int main(int argc, char* argv[])
{
*(void**)&shellcode[12] = fun_get_jmp_esp_addr();
*(void**)&shellcode[17] = &fun_hijacked;
fun_bug();
}
相关阅读
作者 | 顾北 对这个世界充满向往的理想主义者 基于JAVA语言编写,模拟实现双色球摇奖器摇奖过程,产生的有效号码与用户输入的有效号
基于 HTML5 的 WebGL 3D 档案馆可视化管理系统
前言 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要
EJB(Enterprise JavaBean)是J2EE服务器端的组件模型,EJB包括会话Bean(Session Bean)、实体Bean(Entity Bean)、消息驱动Bean(Mess
设计一个基于51单片机的电子温度计系统,其采用STC12C5A60S2芯片作为控制中心,DS18B20温度传感器为测温元件,LCD为显示器件。硬件设计
任务设计有两种途径:1) 基于用户的任务设计a) 从实际出发,将用户自然状态下的场景映射为在人机界面上执行的一组类似