基于缓冲区溢出漏洞的攻防方案设计_第1页
基于缓冲区溢出漏洞的攻防方案设计_第2页
基于缓冲区溢出漏洞的攻防方案设计_第3页
基于缓冲区溢出漏洞的攻防方案设计_第4页
基于缓冲区溢出漏洞的攻防方案设计_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、基于缓冲区溢出漏洞的攻防方案设计基于缓冲区溢出漏洞的攻防方案设计信息安全 071 班 范静霞 指导老师:何岩内容摘要:内容摘要:。关键词:关键词:目目 录录第 1 章 引言1第 2 章 系统漏洞22.1 漏洞的概念22.2 漏洞的分类2系统配置不当2口令失窃3嗅探未加密通讯数据3设计存在缺陷3软件编写存在 bug4第 3 章 本地缓冲区溢出的原理及实现53.1 缓冲区概念53.2 缓冲区溢出攻击原理63.3 缓冲区溢出实现方式7利用跳转指令实现溢出7定位参数地址实现溢出9溢出实现用户权限提升16第 4 章 基于缓冲区溢出的防御方法194.1 关闭不需要的特权程序194.2 关闭或修改系统的某些

2、版本信息204.3 使堆栈向高地址方向增长214.4 及时给程序漏洞打补丁214.5 提供高级的用户帮助21第 5 章 总结23参考文献24第第 1 1 章章 引言引言目前中国互联网已经进入宽带时期,网络用户和网络资源持续增长。但是,互联网的开放性、商业化和应用系统的复杂性带来的安全风险也随之增加,各种安全漏洞的大量存在并不断攀升仍是网络安全的最大隐患,即使计算机系统装上了防火墙和防病毒软件,但遗憾的是系统本身的漏洞难以避免。近年由CERT/CC 发布的系统安全忠告中关于缓冲区溢出(又称堆栈溢出) 漏洞占 56.76%以上。缓冲区溢出可以让普通用户通过运行一个“错误”的程序,来使系统运行只有在

3、超级管理员环境下才能运行的程序。一旦系统存在着缓冲区溢出漏洞,系统就有可能被黑客完全控制。所以,缓冲区溢出漏洞是致命的。缓冲区溢出攻击之所以成为一种常见的攻击手段,其原因在于缓冲区溢出漏洞太普通了,并且易于实现。而且,缓冲区溢出所以成为远程攻击的主要手段,其原因在于缓冲区溢出漏洞给予了攻击者所想要的一切:植入并且执行攻击代码。被植入的攻击代码以一定的权限运行有缓冲区溢出漏洞的程序,从而得到被攻击主机的控制权。本文简单介绍了缓冲区溢出的基本原理及本文讲述了漏洞的基本概念,并列述了漏洞的分类。漏洞的种类繁多,主要就缓冲区漏洞的软件编写存在 bug、系统配置不当、口令失窃、明文通讯信息被监听以及初始

4、设计存在缺陷等方面作了简单的介绍。在简单论述漏洞的同时,本文主要以缓冲区溢出作为主要论点。下面介绍了缓冲区的概念及缓冲区溢出的基本原理,并介绍了缓冲区溢出漏洞的三大实现方式:利用跳指令实现溢出、定位参数地址实现溢出、溢出实现用户权限提升。并从预防、发现、抵御缓冲区溢出攻击以及攻击后的程序恢复等方面对目前有代表性的防御、检测方法和攻击恢复技术进行了归纳、分析和比较,指出这些方法和技术的弊端以及可能采取的规避手段。提出了在攻击技术不断发展的情况下,彻底、有效地解决缓冲区溢出所面临的问题。第第 2 2 章章 系统漏洞系统漏洞2.12.1 漏洞的概念漏洞的概念漏洞也叫脆弱性,是在硬件、软件、协议的具体

5、实现或系统安全策略上存在的缺陷。从而可以使攻击者能够在未授权的情况下访问或破坏系统。这些缺陷被非法用户利用,可以突破系统的审计和访问控制等安全机制,对系统及其承载数据的完整性、保密性和可用性造成威胁。漏洞会影响到很大范围的软硬件设备,包括系统本身及其支撑软件、网络客户和服务器软件、网络路由器和安全防火墙等,即在不同的软硬件设备中都可能存在不同的安全漏洞问题。漏洞无处不在,入侵者只要找到复杂的计算机网络中的一个漏洞,就能轻而易举地闯入系统。所以,了解这些漏洞都有可能在哪里,对于修补它们至关重要。通常,漏洞主要表现在软件编写存在 bug、系统配置不当、口令失窃、明文通讯信息被监听以及初始设计存在缺

6、陷等方面。2.22.2 漏洞的分类漏洞的分类系统配置不当系统配置不当(1)默认配置的不足:许多系统安装后都有默认的安全配置信息,通常被称为 easytouse。但遗憾的是,easytouse 还意味着 easytobreakin。所以,一定对默认配置进行扬弃的工作。(2)管理员懒散:懒散的表现之一就是系统安装后保持管理员口令的空值,而且随后不进行修改。要知道,入侵者首先要做的事情就是搜索网络上是否有这样的管理员为空口令的机器。(3)临时端口:有时候为了测试,管理员会在机器上打开一个临时端口,但测试完后却忘记了禁止,这样就会给入侵者有洞可寻、有漏可钻。通常的解决策略是:除非一个端口是必须使用的,

7、否则禁止它。一般情况下,安全审计数据包可用于发现这样的端口并通知管理者。(4)信任关系:网络间的系统经常建立信任关系以方便资源共享,但这也给入侵者有可趁之机、间接攻击的可能,例如,只要攻破信任群中的一个机器,就有可能进一步攻击其他的机器。所以,要对信任关系严格审核、确保真正的安全联盟。口令失窃口令失窃(1)弱不禁破的口令:就是说虽然设置了口令,但是非常简单,入侵者可以轻而易举的攻破。(2)字典攻击:就是指入侵者使用一个程序,该程序借助一个包含用户名和口令的字典数据库,不断地尝试登录系统,直到成功进入。毋庸置疑,这种方式的关键在于有一个好的字典。(3)暴力攻击:与字典攻击类似,但这个字典却是动态

8、的,就是说,字典包含了所有可能的字符组合。例如,一个包含大小写的 4 字符口令大约有 50 万个组合,1 个包含大小写且标点符号的 7 字符口令大约有 10 万亿组合。对于后者,一般的计算机要花费大约几个月的时间才能试验一遍。.3 嗅探未加密通讯数据嗅探未加密通讯数据(1)共享介质:传统的以太网结构很便于入侵者在网络上放置一个嗅探器就可以查看该网段上的通讯数据,但是如果采用交换型以太网结构,嗅探行为将变得非常困难。(2)服务器嗅探:交换型网络也有一个明显的不足,入侵者可以在服务器上特别是充当路由功能的服务器上安装一个嗅探器软件,然后就可以通过它收集到的信息闯进客户端机器以及信任

9、的机器。例如,虽然不知道用户的口令,但当用户使用 Telnet 软件登录时就可以嗅探到他输入的口令了。(3)远程嗅探:许多设备都具有 RMON,远程监控功能以便管理者使用公共体字符串进行远程调试。随着宽带的不断普及,入侵者对这个后门越来越感兴趣了。.4 设计存在缺陷设计存在缺陷(1)TCP/IP 协议的缺陷:TCP/IP 协议现在已经广为应用、但是它设计时却是在入侵者猖狂肆虐的今天之很早以前设计出来的。因此,存在许多不足造成安全漏洞在所难免,例如 smurf 攻击、ICMPUnreachable 数据包断开、IP 地址欺骗以及 SYNflood。然而,最大的问题在于 IP 协议

10、是非常容易“轻信”的,就是说入侵者可以随意地伪造及修改 IP 数据包而不被发现。现在 Ipsec 协议已经开发出来以克服这个不足,但还没有得到广泛的应用。.5 软件编写存在软件编写存在 bugbug无论是服务器程序、客户端软件还是操作系统,只要是用代码编写的,都会存在不同程度的 Bug。Bug 主要分为以下几类:(1)缓冲区溢出:指入侵者在程序的有关输入项目中了输入了超过规定长度的字符串,超过的部分通常就是入侵者想要执行的攻击代码,而程序编写者又没有进行输入长度的检查,最终导致多出的攻击代码占据了输入缓冲区后的内存而执行。(2)意料外的联合使用问题:一个程序经常由功能不同的多层

11、代码组成,甚至会涉及到最底层的操作系统级别。入侵者通常会利用这个特点为不同的层输入不同的内容,以达到窃取信息的目的。(3)不对输入内容进行预期检查:有些编程人员工作不负责任,对输入内容不进行预期的匹配检查,使入侵者输送炸弹的工作变得非常简单。(4)Raceconditions:多任务多线程的程序越来越多,在提高运行效率的同时,也要注意 Raceconditions 的问题。比如说:程序 A 和程序 B 都按照“读/改/写”的顺序操作一个文件,当 A 进行完读和改的工作时,B 启动立即执行完“读/改/写”的全部工作,这时 A 继续执行写工作,结果是 A 的操作没有了表现。入侵者就可能利用这个处理

12、顺序上的漏洞改写某些重要文件从而达到闯入系统的目的,所以,编程人员要注意文件操作的顺序以及锁定等问题。第第 3 3 章章 本地缓冲区溢出的原理及实现本地缓冲区溢出的原理及实现3.13.1 缓冲区概念缓冲区概念缓冲区,又称中立区、中立地带等,指的是两地的交界处因为战争或其他因素,而划定出的带状地区,此带状地区并不完全属于两方之中的一方,通常由两方共管或是由第三方协助管理。缓冲区是地理空间目标的一种影响范围或服务范围,具体指在点、线、面实体的周围,自动建立的一定宽度的多边形。缓冲区溢出的根本原因在于语言本身的一些特性。从数据结构的角度来说,最根本的原因是由于指针、数组的存在,导致了一系列存储操作上

13、的问题。而直接的原因则是“没有对数组的越界加以监视和限制” 。程序编写者的经验不足或粗心大意使得缓冲区溢出几乎无处不在,导致程序不够健壮,为缓冲区溢出攻击留下了隐患。缓冲区溢出攻击利用了程序设计语言的安全缺陷,及程序员编写代码时的疏漏,将特定的内容写到缓冲区以外的特定内存空间,以达到控制或破坏系统的目的。同时也得满足以下几个条件:(1)缓冲区溢出,首先要有一个缓冲区,当然不是所有的缓冲区都可以,要求是一块有固定大小的缓冲区,而且还要向这块缓冲区中拷贝数据。(2)在程序中存在不规范,不安全的代码,这是发生缓冲区溢出攻击最主要的前提条件。黑客就是最先利用这些不安全,不规范的代码,来首先取得系统的控

14、制权的,然后才利用系统的控制权,进一步实施攻击,产生更大的危害。(3)程序运行中栈的安排结构,有利于黑客展开缓冲区溢出攻击,这是因为在程序运行时通常栈是向下增长的,即后进栈的数据的地址小于先进栈的数据的地址。这样当发生函数调用时,首先压栈的是该函数的参数,然后是函数的返回地址,接下来是基指针,然后在进入函数体以后还会保存一些寄存器的值,再把这些寄存器的值压入栈顶,最后才是函数体中声明的各个局部变量(即前文所说的缓冲区),也有可能包含一些函数指针。因此得出结论:在函数运行中缓冲区的地址低于寄存器的地址,低于基指针的地址,低于返回地址的地址,低于该函数的参数的地址。所以要是向缓冲区中拷贝超过其容量

15、大小的数据,那么多出来的数据就会覆盖寄存器的值,覆盖基指针的值,覆盖返回地址的值覆盖参数的值,也完全可以覆盖上层函数中的缓冲区等等,只要拷贝的数据足够长。而且栈所在的地址范围又低于代码所在的地址范围,这样也完全可能覆盖程序中的代码。(4)既使上诉条件都满足,也不一定会发生缓冲区溢出攻击,只能说程序中存在缓冲区溢出漏洞,这是因为不是所有的漏洞都能被黑客利用。有些只是程序中存在的缺陷,黑客并没有办法或者说暂时没有办法通过该漏洞取得系统的控制权限,来完成其进一步攻击的目的。3.23.2 缓冲区溢出攻击原理缓冲区溢出攻击原理当正常的使用者操作程序的时候,所进行的操作一般不会超出程序的运行范围,数据被添

16、加到分配给该缓冲区的内存块之外,会发生缓冲区溢出,这时候就会出现数据泄漏或侵占了其它的数据空间。缓冲区溢出的攻击原理就是越过缓冲区长度界限向程序中输入超出其常规长度的内容,造成缓冲区的溢出从而破坏程序的堆栈,使程序运行出现特殊的问题转而执行其它指令。一般来说,单单的缓冲区溢出,并不会产生安全问题,如果将溢出送到能够以 root 权限或其它超级权限运行命令的区域去执行某些代码或者运行一个 shell 的时候,该程序就是以超级用户的权限控制了计算机。例如,有一段程序段如图 3.1(a)所示,运行时当进入一个过程,就有一个活动记录累筑于栈顶。sub 的活动记录如图 3.1(b)所示,包含连接数据、形

17、式单元、局部变量、局部数组的内情向量和临时工作单元等。其中连接数据有两个:一个是老 SP 值,即前一活动记录的地址,另一为返回地址。图 3.1 缓冲区漏洞的例子argv1是通过命令行传递给 main 的参数,由于 strcpy()函数不进行越界检查,argv1中的内容将完整地复制到 buf 中,如果 arg1中的内容长度超出了 buf 的范围,多余的内容将被写出 buf 的后续地址中,而在函数堆栈中,局部变量之后存放的有 SP 帧指针和函数返回地址。因此黑客可以通过填写argv 的内容,在 strcpy 出现缓冲区溢出时让程序转去执行相应的攻击代码,完成对系统的攻击。如图 3.1(c)所示,老

18、 SP 值被修改指向缓冲区的地址返回地址被修改指向恶意代码的入口地址。当 sub 返回时,程序将转去执行恶意代码,从而达到攻击目的。因此,为防止缓冲区溢出攻击,开发软件时应该尽量使用带边界检查的函数,或主动进行边界检查。3.33.3 缓冲区溢出实现方式缓冲区溢出实现方式利用跳转指令实现溢出利用跳转指令实现溢出在调用函数时,以下内容会依次压栈:该函数的参数(按从右向左的顺序压栈),函数的返回地址,为该函数调用分配局部栈空间之前的 EBP 寄存器的值。这些东西调试程序的时候看一看对应的汇编代码、对应地址处的内存内容和相关寄存器的值就会一清二楚。函数调用完成后会执行 ret 指令,ret 指令执行完

19、后 esp 寄存器中会指向栈的原始区(执行函数调用之前的那个栈的栈顶),所以把 shellcode 放在栈的原始区,把返回地址修改后指令 jmpesp 的地址就可以,这条 jmpesp 指令的地址是通过在操作系统的几个核心 DLL 中查找的。整个实验过程就是写代码时调用一个函数,然后在调用函数的过程中实现栈溢出。图 3.2 溢出前后堆栈分布状态对照图 3.2,在程序正常执行时,memcpy 函数被执行完毕后,指令指针会返回至 ret 地址处,继续执行 memcpy 函数调用处的后续指令;同时,执行完ret 指令后 ESP 指针也会指向堆栈原始区(调用 memcpy 函数前一时刻的堆栈分布) 。

20、因此,我们可以将溢出代码 shellcode 存在堆栈原始区,而剩下的工作就是在 memcpy 执行返回时让 EIP 指针指向原始区(也就是 ESP 指针指向的地址)即可。如何通过 ret 返回地址确定此时的堆栈 ESP 指针指向呢?在这里采用的方法是通过跳转指令“jmpesp”(无条件跳转至 esp 指向处执行)。通过在用户地址空间中查找到包含有“jmpesp”指令的存储地址,用该地址覆盖 ret 返回地址就可以了。在具体实现时,我们通过三个步骤完成缓冲区溢出:(1)编写前导码。所谓前导码就是用于覆盖局部变量到 ret 返回地址之间的堆栈空间(不包括ret 返回地址空间)的指令码。前导码仅是

21、用于填充堆栈,所以其内容不受限制。我们需要在实际的调试中来确定前导码的大小。(2)查找 jmpesp 指令地址。用”jmpesp”指令的地址覆盖 ret,就可以在 memcpy 执行返回后,让 CPU执行跳转指令,所以首要解决的是在用户空间中找到含有“jmpesp”指令的地址。通过 VC+6.0 的反汇编功能得到“jmpesp”指令的机器码为 0 xFFE4。利用FindJmpesp 工具进行指令查找,确定一个含有“jmpesp”指令的内存地址。(3)shellcode 功能体。shellcode 功能体实现了溢出后主要的执行功能,如创建超级用户,提升用户权限等。在这里我们通过自定义指令来实现

22、弹出用户对话框。攻击者可以利用缓冲区溢出漏洞,通过溢出来获取程序的控制权。若此程序具有足够的权限,则攻击者就因此获得了系统的控制权。要实施一次有效的缓冲区溢出攻击,攻击者必须完成如下任务:(a)在程序的地址空间里植入适当的代码(称为 shellcode)用于完成获取系统控制权等非法任务。(b)通过修改寄存器或内存,让程序执行流跳转到攻击者植入的shellcode 地址空间执行。下面以栈溢出为例,简要介绍一下这两个任务的实现方法:(a)shellcode 植入:当缓冲区溢出发生在程序的 IO 操作附近时,攻击者可以直接利用程序的输入,向程序中植入 shellcode。(b)程序执行流程的跳转:s

23、hellcode 植入后,缓冲区溢出便会发生,以上面的栈溢出为例,如图 3.3,函数调用的返回地址被覆盖为 AAAAA,这样当此函数执行完毕返回时,程序执行流会跳转到 0 xAAAAA(即 shellcode)处继续执行。图 3.3 堆栈溢出定位参数地址实现溢出定位参数地址实现溢出首先看下面的代码片段。Void overflow(const char* ptr, int len) Char buff400; Memcpy(buff,ptr,len);其中第二参数 len 的值为第一参数 ptr 指向的字符串长度。在函数参数 ptr 不为空的情况下,当 len 小于 400 时,该段代码能够正常

24、运行。overflow 函数被调用执行时内存堆栈分布如图 3.4 左侧所示:首先是overflow 调用执行后的下一条指令地址入栈(ret 返回地址),overflow 调用前堆栈基址指针入栈(原 ebp),接下来堆栈基址指针指向当前栈顶(ebp 指向),最后 esp 栈顶指针减去若干字节(大于 400)完成缓冲区划分。而 ebp 指针减去 400就应是局部变量 buff 指针指向。图 3.4 缓冲区溢出前后堆栈的分布当 len 大于 400 时,该段代码就会产生溢出,如图 3.4 右侧所示,溢出的数据会覆盖原 ebp 地址和 ret 返回地址,使其遭到破坏。设想:(1)用 shellcode

25、 指令首地址覆盖 ret 返回地址,当 buff 缓冲区存放shellcode 时,shellcode 指令首地址即为 buff 缓冲区地址。(2)保持原 ebp 基址不被溢出数据覆盖掉,即用 overflow 调用前的 ebp基址覆盖原 ebp 基址。(3)在 shellcode 相关指令被执行完成后,后续代码应继续被执行,利用跳转指令可以执行 overflow 后续代码。所以溢出后的程序执行流程就是:指令寄存器 EIP 指向 buff 基址执行shellcode 指令,待 shellcode 相关指令完成后通过 jmp 跳转指令跳转至 ret返回地址继续执行。将 shellcode 指令按

26、功能分为三部分来进行考虑。第一部分是 shellcode头,其主要功能是保护当前寄存器状态,为执行 shellcode 功能体做准备;第二部分是 shellcode 功能体,由其完成一定的功能如弹出对话框、添加新用户等;最后一部分就是 shellcode 尾,其功能是恢复寄存器状态、跳转至正常执行时下一条指令地址。另外 shellcode 的最后 4 字节应该是覆盖 ret 返回地址的地址。(1)shellcode 头。功能:在内存堆栈中划分额外空间(shellcode 功能体使用),并保护当前寄存器状态。实现代码:_asmsub esp, 1024hpushad(2)shellcode 功能

27、体。功能:完成具体执行功能。实现代码:具体参见实现步骤。利用 ShellExecuteAAPI 函数运行控制台程序 net 实现添加系统用户是一个不错的选择,net 添加用户及提升用户权限命令如下:新建用户:netuserusernamepassword/add用户所属组:netlocalgroupadministratorsusername/add调用执行:ShellExecuteA(0,“open”,“net”,net 执行参数,SWHIDE)其中 username 是新建用户名称,password 是用户口令,/addShellExecute 的功能是运行一个外部程序(或者是打开一个已注

28、册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。如果指定的文件是可执行文件,函数将以 open 的方式打开这个文件。(3)shellcode 尾。功能:恢复寄存器状态;shellcode 功能体执行完成后,跳转到指定代码地址继续执行;使用新地址覆盖原 ebp 地址及 ret 返回地址。实现代码:_asm popad add esp, 102Ch mov edx, OxXXXXXXXX jmp edx通过 popad 指令将恢复所有普通寄存器先前状态。恢复栈顶指针。通过 jmp 指令无条件跳转至 0 xXXXXXXXX 处执行指令。具体实现过程如下:(1)使用 VC 编写项

29、目文件:CreateShellCode、OverFlowClient 和OverFlowServer。(2)生成 shellcode 功能体(a)首先设置 OverFlowClient 项目为启动项。(b)双击打开 OverFlowClient.cpp 源文件,在该源文件中需要填写的代码有:kernel32.dll 基址(第 21 行) ,LoadlibraryA 函数的绝对内存地址(第23 行)和 shellExecuteA 函数(隶属于 Shell32.dll 动态库)的绝对内存地址。(c)编译并生成 OverFlowClient.exe,执行 OverFlowClient.exe,确定系

30、统是否新建了 jlcss 用户,并隶属 Administrators 组。(3)生成 shellcode 指令码(a)设置 CreateShellCode 为启动项。双击打开 CreateShellCode.cpp 源文件,CreateShellCode 的工作流程是:首先生成 shellcode 头,并将相关指令码写入 shellcode.shc 文件中;接下来是生成 shellcode 功能体,功能体代码来自 OverFlowClient.exe 中 shellcode函数执行体,将功能体代码追加到 shellcode.shc 中;最后是生成 shellcode尾,同样将其指令码追加到 s

31、hellcode.shc 中。(b)这里需要填写的宏数值有:SHELLCODEBODYSTART(OverFlowClient.exe 中 ShellCode 主体起始偏移地址) ;SHELLCODEBODYLEN(OverFlowClient.exe 中 ShellCode 主体代码长度) ;CORRECTRETURNADDR(OverFlowServer 中 overflow 调用完成后程序正常执行返回地址,即 OverFlow 正常调用完成后的下一条指令地址) ;在 OverFlowServer 中函数 OverFlow 调用执行前,ebp 基地指针地址;OverFlow 溢出返回地址,

32、即函数溢出后 shellcode 得以执行的首地址。获取 SHELLCODEBODYSTART、SHELLCODEBODYLEN 值调试 OverFlowClient.exe(将该项目设置为启动项)确定 ShellCode 函数入口偏移地址及函数体大小,调试过程参见图 3.3 所示。图 3.5 shellcode 函数开始、结束偏移地址根据调试结果填写 CreateShellCode.cpp 源文件中 SHELLCODEBODYSTART宏和 SHELLCODEBODYLEN 宏的值。其它数值需要通过调试 OverFlowServer 来获取,而 OverFlowServer 的执行又依赖于

33、shellcode.shc 文件,所以暂且编译生成 CreateShellCode.exe文件,执行该文件生成临时 shellcode.shc 文件。(4)调用 OverFlowServer通过上述步骤,已经获得了 ShellCode 执行体指令码,还需要获取溢出后程序正常返回地址、OverFlow 函数调用前 ebp 基础指针地址和 shellcode 执行的缓冲区首地址。(a)OverFlow 正常调用返回时的下一条指令地址。设置 OverFlowServerfiles 为启动项,双击打开 OverFlowServer.cpp 文件。程序首先打开存放 shellcode 指令码的文件(默认

34、名称为 shellcode.shc),读取 shellcode.shc 的全部内容至接收缓冲区中。接下来就是利用 memcpy 函数实现接收缓冲区的拷贝,目标地址是 OverFlow 函数内的局部缓冲区,该缓冲区默认大小为 450 字节,需要根据实际调试结果重新确定其大小。最后在 OverFlow调用完成后程序继续执行(溢出执行后程序依然能够正常继续运行)。调整 TempBuffer 缓冲区大小,使其大于临时 shellcode 指令码长度,这样做的目的是让程序正常执行(不发生溢出) ,以便我们能够获取 OverFlow 函数执行调用后的正确返回地址。调试获取 OverFlow 函数正常调用执

35、行后的下一条指令地址。调试过程如图 3.6 所示。图 3.6 函数溢出后返回地址填写该指针地址到 CreateShellCode.cpp 文件中。(b)OverFlow 函数调用前 ebp 基地址指针。单步调试程序定位到 OverFlow 函数入口处,获取此时的 EBP 指针地址,如图 3.7 所示。图 3.7 verFlow 调用执行前 EBP 指针地址填写 EBP 指针地址到 CreateShellCode.cpp 文件中。(c)最后确定 shellcode 的最后 4 字节,从原理中可知需用这 4 字节数覆盖调用返回地址,使得 shellcode 得以执行。从 OverFlowServe

36、r 程序又可知shellcode 最后被加载到 TempBuffer 缓冲区,所以只要用 TempBuffer 缓冲区首地址覆盖调用返回地址,在程序溢出后 shellcode 便会执行了。调用OverFlowServer.exe 确定 OverFlow 调用执行过程中 TempBuffer 缓冲区的首地址。调试过程如图 3.8 所示。图 3.8 局部变量内存地址将 TempBuffer 缓冲区首地址填写到 CreateShellCode.cpp 文件中。(5)调试确定 TempBuffer 缓冲区大小调试 OverFlowServer.exe 得到 OverFlow 调用返回时的地址,将返回地

37、址与 shellcode.shc 中的十六数相比较,有三种比较结果:(a)返回地址是 shellcode 最后 4 字节数据。函数返回时执行shellcode。(b)返回地址没有在 shellcode.sh 中,缓冲区空间过大,溢出未发生。可以缩小缓冲区空间或在最后 8 个字节前用 0 x90(空指令)补充。(c)返回地址在 shellcode.sh 中(不是最后 4 字节数据),缓冲区空间过小。放大缓冲区空间。当改变 TempBuffer 缓冲区大小时,其首地址可能会发生变动,调试确定TempBuffer 首地址,重新填写 CreateShellCode.cpp,并重新生成shellcode

38、.shc。经过多次调试后确定缓冲区大小,当满足第一种比较结果时,缓冲区溢出就可以执行下去。运行程序,查看系统用户 jlcss(若 jlcss 用户已存在,请先将其删除再运行程序)及其所属用户组。溢出实现用户权限提升溢出实现用户权限提升Windows 每年都会有无数的漏洞被曝光,其中影响最大危害最深的就是溢出漏洞。而溢出漏洞又分为两类,一类是远程溢出漏洞,一类是本地溢出漏洞,前者经常被黑客利用来入侵网络上的主机,后者通常被用来进行本地的账户权限提升。Windows 的本地权限溢出漏洞有很多,如最新的MicrosoftWindows 键盘事件权限提升漏洞。该漏洞通过向以更高权限运行的桌面应用程序(

39、如explorer.exe)发送恶意的键盘事件,以此得到一个拥有最高权限的 shell,在这个 shell 中可以执行任意命令,例如建立删除账户,访问修改文件等,当然也包括将用户级别的账户提升为系统权限。1、设置溢出文件所属用户(1)复制文件 attack 和 overflow 到 guest 用户主目录/home/guest 中。(2)切换工作目录至/home/guest/,修改 attack 文件属性及用户权限,要求文件隶属 guest 用户,隶属 guest 组,具体命令:chownguestattack、chgrpguestattack。(3)设置 overflow 文件 suid 属

40、性,具体命令:chmoda+soverflow。2、切换用户登录注销当前用户(root),以 guest 用户身份登录系统。3、提升权限(1)输入命令:whoami,当前登录的用户是 guest。(2)输入命令:cat/etc/shadow,尝试查看阴影文件,此时系统提示没有这个文件或目录。上述情况证实用户有对阴影文件的访问权,其它任何用户均无此权限。(3)输入命令:passwdroot,尝试修改 root 用户登录口令,此时系统提示 Only root can specify a user name。(4)执行 attack 应用程序。(5)当运行 attack 后出现“sh-3.1#”提示

41、符时,表明缓冲区溢出成功。此时我们就拥有了超级用户(root)的权限,拥有对阴影文件的访问权限,随后我们可以用口令破解程序(如 john)对该阴影文件进行口令破解。(6)在溢出成功后对 root 口令进行修改,输入命令:passwdroot 修改root 用户口令。4、 root 用户重新登录注销结束当前会话,以 root 身份重新登录系统。(1)获取 explorer.exe 进程的 PID 值由于漏洞利用程序 keybd.exe 的溢出原理,需要用到 explorer.exe 进程的PID 值。我们的第一步工作就是得到 explorer.exe 进程所相对应的 PID 值。右键点击工具栏,

42、选择任务管理器,在进程标签中可以看到当前系统中运行的所有进程,查看进程的 PID 值。(2)用keybd.exe进行溢出点击开始运行,输入CMD运行命令提示符,在命令提示符中运行keybd。exe,其溢出格式如下keybd。exeexplorer。exe 进程的 PID 值,根据上文中得出的 PID 值,我们输入keybd。exe1300即可。如果溢出成功,会出现一个新的命令提示符窗口。(3)得到系统权限溢出成功后,使用 NC 来获取一个拥有系统权限的 shell。在命令提示符中运行 NC,输入命令nc-vvlocalhost65535,回车后就会得到一个拥有系统权限的 shell,在这个 s

43、hell 中可以执行任意命令,我们的目标是将当前使用的用户权限账户提升为管理员权限。第第 4 4 章章 基于缓冲区溢出的防御方法基于缓冲区溢出的防御方法防范缓冲区溢出,要从主观和客观两方面进行入手,主观方面,要提高程序员的编程水平;客观方面,从底层系统入手,启用自动保护程序,尽量避免缓冲区溢出问题的发生,也可以从系统和软件两方面入手;遗憾的是,迄今所见的所有方法都具有弱点,因此它们不是万能药,但是它们会提供一些帮助。下面对于缓冲区溢出的特点,探讨一下防范策略。在编写程序的时候程序员有责任和义务养成安全编程的思想,应该熟悉那些可能会产生缓冲区溢出漏洞的函数,清楚那些在编程中要小心使用的函数。在软

44、件测试阶段,测试人员要专门对程序中的每个缓冲区作边界检查和溢出检测。但是,由于程序员的经验不足和测试工作不够全面,目前还不可能完全避免缓冲区溢出漏洞,因此这些漏洞在已经使用以及正在开发的软件中还是有存在的可能性,还需要在使用软件时,对它做实时的监测。当前,由于计算机厂商和系统开发商的努力,现在的计算机一般使用一种叫数据执行保护(DEP)的技术,如果数据出现在标记为不被执行的内存页中,CPU 将不予执行。从而有效的防护溢出漏洞。WindowsXPSP2 及WindowsServer2003 现在已支持这些技术,目前市面上的大多数的 32 位 CPU 及全部的 64 位 CPU,都支持 NoExe

45、cute(NX)这类安全增强技术。另外在 VisualStudio2003 及以后微软的 VC+开发平台中,编译器都加入了一个/GS 开关(即缓冲区安全检查设置项) ,该开关的打开,优化了代码的顺序,能有效防止因内存溢出而覆盖程序重要数据现象的发生。默认情况下该开关是打开的。4.14.1 关闭不需要的特权程序关闭不需要的特权程序由于缓冲区溢出只有在获得更高的特权时才有意义,所以带有特权的程序都经常是缓冲区溢出攻击的目标。这时候,关闭一些不必要的特权程序就可以降低被攻击的风险,当有缓冲区溢出漏洞的程序还没有补丁时,就可以用这种方法。4.24.2 关闭或修改系统的某些版本信息关闭或修改系统的某些版

46、本信息攻击者攻击某一个系统,必须事先通过某些途径(如通过 rpc 连接)对要攻击的系统做必要的了解,如版本信息等,然后再利用系统的某些设置直接或间接地获取控制权。因此,防范缓冲区溢出攻击的另一个方面就是对系统设置实施有效的安全策略。这些策略种类很多,比较典型措施有:(1)在装有 Telnet 服务的情况下,通过手工改写“/etc/inetd.conf”文件中的 Telnet 设置,使得远程登录的用户无法看到系统的提示信息。具体方法是将 Telnet 设置改写为:telnetstreamtcpnowaitroot/usr/sbin/tcpd/in.telnetd-h 末尾加上“-h”参数可以让守

47、护进程不显示任何系统信息,只显示登录提示,这样用户在发出远程登录的时候,没有任何可用的信息,他不知道什么版本,自然想得到某种版本的漏洞信息就比较困难了。(2)改写“rc.local”文件。默认情况下,当登录 Linux 系统时系统运行rc.local 文件,显示该 Linux 发行版本的名字、版本号、内核版本和服务器名称等信息,这使得大量系统信息被泄露。将“rc.local”文件中显示这些信息的代码注释掉,可以使系统不显示这些信息。另一种方法是将保存有系统信息的文件/etc/issue.Net 和 issue 删除。这两个文件分别用于在远程登录和本地登录时向用户提供相关信息。删除这两个文件的同

48、时,仍需要完成方法一中的注释工作,否则,系统在启动时将会自动重新生成这两个文件。(3)禁止提供 finger 服务。在 Linux 系统中,使用 finger 命令可以显示本地或远程系统中目前已登录用户的详细信息。禁止提供 finger 服务的有效方法是,通过修改该文件属性、权限(改为 600)使得只有 root 用户才可以执行该命令。(4)处理“inetd。conf”文件。Linux 系统通过 inetd(超级服务器)程序根据网络请求装入网络程序。该程序通过“/etc/inetd。conf”文件获得inetd 在监听哪些网络端口,为每个端口启动哪些特定服务等信息。因此,该文件同样会泄露大量的敏感信息。解决问题的方法是,通过将其权限改为 600只允许 root 用户访问,并通过改写“/etc/inetd。conf”文件将不需要的服务程序禁止掉,最后修改该文件的属性使其不能被修改。还有预防 ping 命令处理等系统策略。4.34.3 使堆栈向高地址方向增长使堆栈向高地址方向增长缓冲区溢出的一个重要要素是植入的代码成功地被执行。最常见的是被植入的代码放在堆栈区中。通过修改操作系统核心,在核心层引入保护机制,限制代码在堆栈区的执行,这样,缓冲区溢出攻击就不可能成功。到目前为止,本文在讨论利用函数返回地址控制程序转移到攻击代码的攻击方法时,有一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论