基于shellcode分析缓冲区溢出攻击
2020-04-05刘佳琳谭振江朱冰
刘佳琳 谭振江 朱冰
摘 要: 缓冲区的本质是内存中的一个片段,它用于暂时存放输入与输出的数据或者代码。缓冲区溢出是一种非常危险的漏洞,在各种应用软件及操作系统中广泛存在。如果攻击者发现目标主机存在缓冲区溢出漏洞,攻击者会利用该漏洞,执行恶意代码,最终获取被攻击主机的控制权,窃取有价值的信息。文章利用实际案例讲解shellcode的形成过程,分析缓冲区溢出攻击发生的危害及原因。
关键词: shellcode; 缓冲区溢出; 缓冲区溢出攻击; 控制权
中图分类号:TP309.2 文献标识码:A 文章编号:1006-8228(2020)02-43-04
Analyzing the buffer overflow attack by shellcode
Liu Jialin, Tan Zhenjiang, Zhu Bing
(College of Computer Science, Jilin Normal University, Siping, Jilin 136000, China)
Abstract: The essence of a buffer is a fragment in memory that is used to temporarily store input or output data or code. Buffer overflow is a very dangerous vulnerability that is widespread in a variety of applications and operating systems. If an attacker finds a buffer overflow vulnerability on the target host, the attacker exploits the vulnerability, executes malicious code, and finally gains control of the attacked host and steals valuable information. This paper uses the actual case to explain the formation process of shellcode, analyze the hazards and causes of buffer overflow attacks.
Key words: shellcode; buffer overflow; buffer overflow attack; control
0 引言
伴隨着信息科学技术的快速发展,计算机应用在各行各业,计算机软件的开发与计算机技术的应用是信息时代的产物,有越来越多的计算机软件应用于人们的工作和生活中。与此同时,软件的安全漏洞也越来越多[1]。缓冲区溢出是一种非常普遍的安全漏洞。在2018年10月、12月以及2019年1月的十大重要安全漏洞分析中都出现了缓冲区溢出漏洞,其中就存在由应用软件带来的缓冲区溢出漏洞[2-4]。SLMail软件是基于Windows环境的Internet邮件服务器系列产品,它的PASS命令存在缓冲区溢出漏洞,无需身份验证就可以实现远程代码执行[5]。缓冲区溢出漏洞虽然只是非常普遍的安全漏洞,但却是一种具有严重破坏作用的漏洞,攻击者会利用该漏洞,对计算机软件造成破坏,进而破坏应用系统,获取有价值的数据信息,影响正常的学习、工作和生活。
本文以Kali Linux 2.0作为攻击机,虚拟Windows XP作为目标主机,在目标主机中以SLMail 5.5.0 Mail Server作为目标程序,结合动态调试工具与用于定位进程模块的脚本,实现远程代码执行,达到控制目标主机的效果。在此过程中讲解shellcode的形成过程,分析缓冲区溢出攻击的危害及原因。
1 理论分析
SLMail具有缓冲区溢出漏洞,通过PASS命令就可以实现远程代码执行,因此,需要掌握缓冲区、缓冲区溢出、缓冲区溢出攻击以及程序执行的异常情况等理论知识。
1.1 缓冲区
缓冲区是内存中的一个片段。现在的计算机在运行程序时,采用的是冯·诺依曼的存储程序计算机思想。即程序运行需要的指令和数据先保存在存储器中,计算机根据地址读出指令与数据,实现连续自动地执行[6],执行的结果可能会写入到计算机的硬盘或者文件中保存,也可能会返回给用户。缓冲区就是可以用于临时存放这些数据的内存区域。
1.2 缓冲区溢出
缓冲区溢出是指有大量的数据写入缓冲区,超过了缓冲区所能容纳的最大范围,超过了最初定义的内存边界,从而覆盖了相邻内存区域的数据,这种现象大多发生在固定分配存储空间的情况下[7]。在理想状态下,程序会检查数据的长度,并且不允许输入的字符长度超过缓冲区的大小。而且,系统软件也会使用特殊的指令为每个程序划定存储区域,禁止越界访问[8]。实际上,并不是所有的程序都会具有上述功能,而是假设输入的数据长度不会超过缓冲区的边界,这就为缓冲区溢出留下隐患。
1.3 缓冲区溢出攻击
缓冲区溢出攻击是利用缓冲区溢出漏洞进行的攻击行为,这种攻击行为会出现内存数据被修改、程序执行失败、系统重启等现象,也可以在远程执行恶意代码,导致目标主机被控制[9]。这是一种具有破坏性的攻击行为。
1.4 程序执行的异常情况
在正常情况下,在向计算机传输信息时,计算机会默认提交的信息全部为数据。如果程序的设计规则不严格,在提交的信息加入代码时,计算机并不会识别出信息中包含的代码,仍会把这些内容当作数据在计算机里运行。该现象可以通过一个能够显示输入内容的脚本(a.sh)进行解释。如图1所示。
图1显示了该脚本的四次执行结果,可以发现前两次执行的输出结果与输入结果一致,后面两次执行的输出是把参数内容作为命令来执行。因为程序编写者没有对该脚本内容的书写规则做出严格的规定,导致在执行脚本时没有对输入的参数严格检查,没对普通字符和命令做严格地区分,输出许多其他信息,这是一种异常情况。
2 实际案例
攻击者会利用程序执行的异常情况,编写恶意程序,针对具有缓冲区溢出漏洞的目标主机发起攻击,使服务进程遭到破坏。下面将在引言中提到的实验环境,不断进行模糊测试,讲解shellcode的形成过程。
2.1 确定溢出的范围
编写可以向110端口(POP3协议默认的端口号)发送数据的脚本。脚本中包含大量的溢出字符,均为字母A(十六进制为41),如果不断修改字母A的发送量,当发送2700个字母A时,脚本就不再继续执行,此时,EIP寄存器的内容已被修改为“41414141”。当发送2600个字母A时,脚本也不再继续执行,但是EIP寄存器的内容并非是“41414141”,说明溢出字符还没覆盖到EIP寄存器上。因此,能够覆盖EIP寄存器的字符数目在2600到2700之间。
2.2 确定溢出的精确位置并验证
在本案例中选择使用唯一字符串法找出精确位置。将以三个为一组不重复的2700个字符替换溢出字符中的字母A,重新发送溢出字符,根据EIP寄存器的内容计算偏移量,确定溢出的精确位置。
利用该偏移量,将精确位置后的内容修改为由4个字母B(十六进制为42)和20个字母C,其余的内容修改为字母A,重新发送溢出字符,结果如圖2所示。其中,EIP寄存器的内容为“42424242”,证明之前测试得到的溢出位置是准确的。而且,图2中ESP寄存器的内容恰好为溢出字符中的20个字母C,这个现象将为在溢出字符中添加具有特定功能的十六进制操作码提供了可能性。
2.3 生成shellcode的准备工作
Aleph One在1996年的论文中把嵌入进程的代码称为“shellcode”,后来,将缓冲区溢出攻击过程植入的代码叫做“shellcode”。随着计算机语言的不断发展,现在使用的shellcode大多是由C语言和汇编语言编写,然后再对其汇编、反汇编得到十六进制的操作码[10]。为了操作简便,本实例中的溢出字符直接使用十六进制操作码。
当溢出字符数量为2700时,溢出字符可以覆盖ESP寄存器的内容,这表明该内存区域可以被用于存放shellcode。一般小型shellcode的大小为300bytes左右,因此,还需要通过增大溢出字符中字母C的数量,重新发送溢出字符,判断ESP寄存器的存储量是否可以存放小型的shellcode。
2.4 生成shellcode并执行
前面的所有准备工作是为了证明ESP寄存器能够存放shellcode,接下来需要解决的问题是编写出具有实际功能的shellcode并执行。
为了达到控制目标主机的目的,shellcode应该具有使目标主机反弹回连到攻击机指定端口的功能。EIP寄存器能够存放下一条指令的地址,如果想要执行ESP寄存器内存放的shellcode,可以把EIP的内容修改为ESP的地址。然而,SLMail是基于线程的应用程序,操作系统为每个线程分配一个地址范围,但每个线程地址范围也不确定,因此,ESP寄存器的地址是变化的,不能直接使用。但是,可以利用内存中地址固定的系统模块,在这些模块中寻找跳转ESP寄存器的指令,将该指令的地址存放在EIP寄存器内,再由该指令间接跳转到ESP,执行ESP寄存器中的内容。
2.5 控制目标主机
在实施缓冲区溢出攻击之前,先侦听攻击机的指定端口。再将溢出字符中字母B修改为跳转ESP寄存器的指令地址,字母C修改为具有反弹回连到攻击机功能的shellcode,其他的溢出字符保持不变,重新发送溢出字符。如果攻击机的命令窗口呈现出图3所示的效果,说明已经成功执行ESP寄存器的内容,目标主机已经反弹回连到攻击机的指定端口,攻击机取得目标主机控制权。
在拿到控制权后,攻击者还可以修改目标主机的注册表的相关内容,并在攻击机里安装远程桌面工具,实现对目标主机图形界面的控制。
2.6 案例总结
经过不断的模糊测试,获得目标主机的控制权。在这个过程中,每一次修改的内容都是溢出字符,并且这些溢出字符都可以在目标主机上执行,说明计算机本身并不识别程序中的数据和代码,也不会检查数据的长度。
3 缓冲区溢出攻击的原因与危害
如果把测试中的脚本看作是发送给计算机的恶意程序,这些程序在被执行时,计算机没有任何特定的机制去检查程序的数据中是否存在代码,也不会检查数据的长度是否已经超过缓冲区的大小。这些原因使得攻击者有机会执行恶意程序,导致缓冲区溢出攻击的发生。
后门程序是指通过某种方式安装在目标主机上,实现获取对程序或者系统访问权的一种方法[11]。获得目标主机的控制权后,攻击者如果想要再一次获取控制权,不会因管理员修补该漏洞而无法实现对目标主机的控制,因为攻击者有可能会在第一次取得控制权后,就立即在目标主机上安装后门程序,为再一次控制主机做准备。通过后门,攻击者不需要通过实施攻击控制目标系统,因此,缓冲区溢出对系统的威胁是潜在的、不确定的,会出现方便攻击者再次入侵、隐藏操作痕迹、避过监控系统、提供恶意代码植入手段等严重后果[12]。
4 结束语
本文是通过讲解shellcode的形成过程分析缓冲区溢出攻击的原因与危害。在这个过程中,数据和代码都是放在一起保存的,攻击者之所以能实施缓冲区溢出攻击,是因为计算机中数据和代码的边界不清晰。但是,伴随着操作系统的更新,不断有新的安全防护机制添加到操作系统中,DEP(数据执行保护)就是一种新的安全防护机制,它可以阻止代码从数据页里被执行,弥补了计算机中数据和代码混淆这一缺陷[13]。此外,SafeSEH(安全结构化的异常处理)、SEHOP(SEH覆盖保护)、堆保护以及ASLR(地址空间随机分布)等安全防护机制,都可以对Windows下的缓冲区溢出漏洞进行防范[14]。
因此,不仅需要管理员经常维护操作系统的安全防护机制,经常进行安全检查,在发现问题时能够尽早解决。而且,用户也应使用安全的应用软件,及时更新操作系统,避免信息泄露的现象发生。
参考文献(References):
[1] 桑洋.浅谈软件设计中的安全漏洞动态检测技术[J].信息化建设,2016.19(5):86.
[2] 2018年10月十大重要安全漏洞分析[J].信息网络安全,2018.18(12):95-96
[3] 2018年12月十大重要安全漏洞分析[J].信息网络安全,2019.19(2):87-88
[4] 2019年1月十大重要安全漏洞分析[J].信息网络安全,2019.19(3):89-90
[5] 马潮.基于Windows的Intranet&Internet邮件服务器[J].微型机与应用,1998.17(4):26-27
[6] 邵博文.冯·诺依曼的逻辑和计算机思想[J].数字通信世界,2017.13(10):249.
[7] 袁连海,李湘文,徐晶.缓冲区溢出攻击研究[J].舰船电子工程,2019.39(4):88-93
[8] 檀磊.计算机程序运行过程的探讨[J].软件导刊,2010.9(12):7-9
[9] 高珊,李爱华,赵晓雯.基于缓冲区溢出攻击的Shellcode編码技术研究[J].电子世界,2018.40(16):166,168.
[10] 黄惠烽.图书馆局域网缓冲区溢出之shellcode原理分析[J].湖北成人教育学院学报,2013.19(1):107-108
[11] 安志远,刘海燕.防范利用远程溢出植入后门的设计与实现[J].计算机科学,2012.39(S2):208-211
[12] 孙淑华,马恒太,张楠,卿斯汉,王晓翠.后门植入、隐藏与检测技术研究[J].计算机应用研究,2004.21(7):78-81
[13] 郭建伟.浅析DEP安全保护技术[J].网络安全和信息化, 2018.3(8):122-126
[14] 罗斌.缓冲区溢出漏洞分析及防范[J].电脑知识与技术,2018.14(33):44-45