安全性编程方法Word文档格式.docx
- 文档编号:19742462
- 上传时间:2023-01-09
- 格式:DOCX
- 页数:11
- 大小:54.74KB
安全性编程方法Word文档格式.docx
《安全性编程方法Word文档格式.docx》由会员分享,可在线阅读,更多相关《安全性编程方法Word文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
伴随着调试技术和逆向工程的发展,Windows平台下涌现出的众多功能强大的debug工具盒反汇编分析软件逐渐让二进制世界和操作系统变得不再神秘,这有力地推动了Windows平台下缓冲区溢出的研究。
除此之外,近年来甚至出现了基于架构(FrameWork)的漏洞利用程序开发平台,让这项技术的进入门开大大降低,舍得原来高不可攀的黑客技术变得不再遥不可及。
遗憾的是,与国外飞速发展的高级黑客技术相比,目前国内还没有系统等知识和领域介绍Windows平台下缓冲区溢出漏洞利用技术并且相当匮乏。
本文在大量文献的基础上,并结合“安全性编程方法”课程上的了解,讲述有关“zerodayattack”的内容,例如计算机漏洞、安全性编程方法等。
1.基础知识
1.1漏洞概述
1.1.1bug与漏洞
随着现代软件工业的发展,软件规模不断扩大,软件内部的逻辑也变得异常
复杂。
为了保证软件的质量,测试环节在软件生命周期中所占的地位已经得到了普遍重视。
在一些著名的大型软件公司中,测试环节(QA)所耗费的资源甚至已经超过了开发。
即便如此,不论从理论上还是工程上都没有任何人敢声称能够彻底消灭软件中所有的逻辑缺陷——bug。
在形形色色的软件逻辑缺陷中,有一部分能勾引去非常严重的后果。
例如,网站系统中,如果在用户输入数据的限制方面存在缺陷,将会使服务器变成SQL注入攻击和XSS(CrossSiteScript,跨站脚本)攻击的目标;
服务器软件在解析协议时,如果遇到出乎预料的数据格式而没有进行恰当的异常处理,那么久很可能会给攻击者提供远程控制服务器的机会。
我们通常把这类能够引起软件做一些“超出设计范围的事情”的bug成为漏洞(vulnerability)。
(1)功能性逻辑缺陷(bug):
影像软件的正常功能,例如,执行软件错误、图标显示错误等。
(2)安全性逻辑缺陷(漏洞):
通常情况下不影响软件的正常功能,但呗攻击
者成功利用后,有可能引起软件区执行额外的恶意代码。
常见的漏洞包括软件中的缓冲区溢出漏洞、网站中的跨站脚本漏洞(XSS)、SQL注入漏洞等。
1.1.2几个令人困惑的安全问题
也许您有一定的计算机知识,但仍然经常费结于下面这些安全问题。
(1)我从不运行任何来历不明的软件,为什么还会中病毒?
如果病毒利用重量级的系统漏洞进行传播,您将在劫难逃。
因为系统漏洞可以引起计算机被远程控制,更何况传播病毒。
横扫世界的冲击驳蠕虫、slammer蠕虫等就是这种类型的病毒。
如果服务器软件存在安全漏洞,或者系统中可以被RPC远程调用的函数中存在缓冲区溢出漏洞,攻击者也可以发起“主动”进攻。
在这种情况下,您的计算机会轻易沦为所谓的“肉鸡”。
(2)我只是点击了一个URL链接,并没有执行任何其他操作,为什么会
中木马?
如果您的浏览器在解析HTML文件时存在缓冲区溢出漏洞,那么攻击者就可以惊心构造一个承载着恶意代码的HTML文件,并把其连接发给您。
当您点击这种链接时,漏洞被触发,从而导致HTML中所承载的恶意代码(shellcode)被执行。
这段代码通常是在没有任何提示的情况下去指定的地方下载木马客户端并运行。
此外,第三方软件所加载的ActiveX空间中的漏洞也是被“网马”所经常利用的对象。
所以千万不要忽视URL链接。
(3)Word文档、PowerPoint文档、Excel表格文档并非可执行文件,它们会导致恶意代码的执行吗?
和html文件一样,这类文档本身虽然是数据文件,但是如果Office软件在解析这些数据文件的特定数据结构时存在缓冲区溢出漏洞的话,攻击者就可以通过一个惊心构造的Word文档来触发并利用漏洞。
当您在用Office软件打开这个Word文档的时候,一段恶意代码可能已经悄无声息地被执行过了。
(4)上网时,我总是使用高强度的密码注册账户,我的账户安全么?
高强度的密码只能抵抗密码暴力猜解的攻击,具体安全与否还取决于很多其他因素:
密码存在哪里,例如,存本地计算机还是远程服务器。
密码怎样村,例如,明文存放还是加密存放,什么强度的加密算法等。
密码怎样传递,例如,迷药交换的过程是否安全,网络通讯是否使用SSL等。
这些过程中如果有任何一处失误,都有可能引起密码泄露。
例如,一个网站存在SQL注入漏洞,而您的帐号密码有一明文形式存在Web服务器的数据库中,那么无论您的密码多长,包含多少奇怪的字符,最终仍将为脚本注入攻击者获取。
此外,如果密码存在本地,即使使用高强度的Hash算法进行加密,如果没有考虑到CRACK攻击,验证机制也很可能被轻易突破。
1.1.3漏洞挖掘、漏洞分析、漏洞利用
利用漏洞进行攻击可以大致分为漏洞挖掘、漏洞分析、漏洞利用三个步骤。
这三个部分所用的技术有相同之处,比如都需要精通系统底层知识、逆向工程等;
同时也有一定的差异。
1.1.3.1挖掘漏洞
安全漏洞往往不会对软件本身功能造成很大影响,因此很难被QA工程师的功能性测试发现,对于进行“正常操作”的普通用户来说,更难体会到软件中的这类逻辑瑕疵了。
由于安全漏洞往往有极高的利用价值,例如,导致计算机被非法远程控制,数据库数据泄漏等,所以总是有无数技术精湛、精力旺盛的家伙在夜以继日地寻找软件中的这类逻辑瑕疵。
他们精通二进制、汇编语言、操作系统底层的知识;
他们往往也是接触的程序员,因此能够敏锐地捕捉到程序员所犯的细小错误。
寻找漏洞的人并非全是攻击者。
大型的软件企业也会雇佣一些安全专家来测试自己产品中的漏洞,这种测试工作被称做Penetrationtest(攻击测试),这些测试团队泽被称做Tigerteam或者Ethichacker。
从技术角度讲,漏洞挖掘世界上是一种高级的测试(QA)。
学术界一直热衷于使用静态分析的方法学找源代码中的漏洞;
而在工程界,不管是安全专家还是攻击者,普遍采用的漏洞挖掘方法是Fuzz,这实际是一种“灰”盒测试。
1.1.3.2漏洞分析
当fuzz捕捉到软件中一个严重的异常时,当您想透过厂商公布的简单描述了解漏洞细节的时候,您就需要具备一定的漏洞分析能力。
一般情况下,我们需要调试二进制级别的程序。
在分析漏洞时,如果能够搜索到POC(proofofconcept)代码,就能重现漏洞被触发的现场。
这是可以使用调试器观察漏洞的细节,或者利用一些工具(如Paimei)更方便得找到漏洞的触发点。
当无法获得POC时,就只有厂商提供的对漏洞的简单描述了。
一个比较通用的办法是使用补丁比较器,首先比较patch前后可执行文件都有那些地方被修改,之后可以利用反汇编工具(如IDAPro)重点逆向分析这些地方。
1.1.3.3漏洞利用
漏洞利用技术可以一直追溯到20世纪80年代的缓冲区溢出漏洞的利用。
然而直到AlephOne于1996年在P话rack第49期上发表了注明的文章《SmashingTheStackForAndProfit》,这种技术才真正流行起来。
随着时间的推移,经过无数安全专家和黑客们针锋相对的研究,这项技术已经在多种流行的操作系统和编译环境下得到了实践,并入去完善。
这包括内存漏洞(堆栈溢出)和Web应用漏洞(脚本注入)等。
1.1.4漏洞的公布与0day响应
漏洞的公布的流程取决于漏洞是被谁发现的。
如果是安全专家、PenTester、EthicHacker在测试中发现了漏洞一般会立刻通知厂商的产品安全中心。
软件厂商在经过漏洞确认、补丁测试之后,会正式发布漏洞公告和官方补丁。
然而事情总是没有那么简单,如果漏洞被攻击者找到,肯定不会立刻通知软件厂商。
这是漏洞的信息只有攻击着自己知道,他可以写出exploit利用漏洞来做任何事情。
这种未被公布、未被修改的漏洞往往被称作0day。
0day漏洞是危害最大的漏洞,当然对攻击者来说也是最有价值的漏洞。
0day毕竟只是被少数攻击者掌握,并且大多数情况下也不会有人浮躁到写出蠕虫来攻击整个Internet。
但有时0day漏洞会被曝光,那意味着全世界的黑客都知道这个漏洞,也懂得怎么去利用它,在场上的官方补丁发布前,整个Internet的网络将处于高位预警状态。
0day曝光属于严重的安全事件,一般情况下,软件厂商都会进入应急响应处理流程,以最快的速度修复漏洞,保护用户的合法权利。
2.漏洞挖掘技术
2.1文件类型漏洞挖掘与SmartFuzz
不管是IE还是Office,它们都有一个共同点,那就是用文件作为程序的主要
输入。
从本质上来说,这些软件都是按照事先约定好的数据结构对文件中不同的数据进行解析,已决定用什么颜色、在什么位置显示这些数据。
不少程序员会存在这样的惯性思维,即假设他们所使用的文件时严格遵守软件规定的数据格式的。
这个假设在普通的使用过程中似乎没有什么不妥——毕竟用Word生成的.doc文件一般不会存在什么非法的数据。
但是攻击者往往会挑战程序员的假定假设,尝试对软件所约定的数据格式进行稍许修改,观察软件在解析这种“畸形文件”时是否会发生错误,发生什么样的错误,以及堆栈是否能被溢出等。
文件格式Fuzz(FileFuzz)就是这种利用“畸形文件”测试软件鲁棒性的方法。
您可以在Internet上找到许多用于FileFuzz的工具。
抛开界面、运行平台等因素不管,一个FileFuzz工具大体的工作流程包括以下几步,如图1所示
图1Fuzz的一般步骤
(1)以一个正常的文件模版为基础,按照一定规则产生一批畸形文件。
(2)将畸形文件注意送入软件进行解析,并监视软件是否会抛出异常。
(3)记录软件产生的错误信息,如寄存器状态、栈状态等。
(4)用日志或其他UI形式向测试人员展示异常信息,以进一步坚定这些错误是否能被利用。
2.2FTP的漏洞挖掘
FTP服务全称为文件传输协议服务,英文全称为FileTransferProtocol,其工
作模式采用客户端/服务器的模式,也就是C/S模式。
用户想要通过FTP服务访问到共享的文件信息时,首先需要在自己的计算机系统上运行一个FTP客户端,这个客户端可以是一个FTP应用程序,也可以是操作系统自带的命令行程序;
然后再FTP客户端中输入用户名和密码来登录FTP服务程序;
成功登陆后,用户就可以获取到远程计算机上烘箱的文件信息了。
2.3E-mail的漏洞挖掘
E-mail的漏洞挖掘,即SMTP漏洞的挖掘。
SMTP协议的全称是建安邮件传
输协议,它建立在TCP协议上,采用明文的方式来传递邮件发送命令,使用端口25与邮件服务器进行通讯。
SMTP具体的邮件发送命令被规定在RFC0821文档中。
3.操作系统内核安全
3.1探索ring0
一个内核漏洞的学习过程可以总结为4个环节:
漏洞重现、漏洞分析、漏洞利用和漏洞总结。
漏洞重视环节,需要搭建测试环境,通常为虚拟机环境;
另外需要注意有漏洞的内科文件或旭东文件的版本,如果版本不对,是不可能重现的;
还要确认该漏洞暂时还未打补丁;
最后,如果该漏洞公布有POC源码,还需要对POC源码进行编译。
在漏洞重视环节中,通过漏洞分析可以加深对漏洞的理解,这样边分析边重现,往往问题就迎刃而解了。
3.2内核漏洞利用技术
内核漏洞主要的作用包括:
远程任意代码执行,本地权限提升,远程拒绝服务攻击,本地拒绝服务攻击。
从漏洞的利用来看,远程拒绝服务和本地拒绝服务类型的内核漏洞利用起来比较简单,不必过多地考虑“构造”。
相反,远程任意代码执行和本地权限提升类型的内核漏洞,利用起来往往比较复杂,需要有精心的构造,包括漏洞触发条件的构造,相关数据的构造等。
3.3FUZZ驱动程序
漏洞挖掘有两种方式,一是工具挖掘,二是手工挖掘。
无论哪种方法,首先都要有一个切入点,也就是内核Fuzz的思路。
(1)内核API函数:
内核API函数是提供给Ring3调用,在Ring()完成最终功能的函数。
这些函数接受Ring3传入的参数,如果处理参数的过程存在函数的话,很有可能成为一个内核漏洞。
(2)HookAPI的代码:
目前有很多安全软件为了防御病毒木马,对很多内核API进行了Hook/InlineHook。
然而这些Hook内核API的代码也存在安全问题。
如果对参数的处理不当或内部逻辑的错误,也有可能出现内核漏洞。
(3)网络协议处理的内核代码:
有一些协议的处理是在SYSSTSEM进程中的,也就是在内核模块中处理的,可以通过网络协议Fuzz,构造畸形协议数据包,来挖掘这方面的漏洞。
4.漏洞分析的案例
下面我们用一个简单的例子来展示堆栈的模样:
example1.c:
------------------------------------------------------------------------------
voidfunction(inta,intb,intc){
charbuffer1[5];
charbuffer2[10];
}
voidmain(){
function(1,2,3);
------------------------------------------------------------------------------
为了理解程序在调用function()时都做了哪些事情,我们使用gcc的-S选项编译,以产
生汇编代码输出:
$gcc-S-oexample1.sexample1.c
通过查看汇编语言输出,我们看到对function()的调用被翻译成:
pushl$3
pushl$2
pushl$1
callfunction
以从后往前的顺序将function的三个参数压入栈中,然后调用function().指令call
会把指令指针(IP)也压入栈中.我们把这被保存的IP称为返回地址(RET).在函数中所做
的第一件事情是例程的序幕工作:
pushl%ebp
movl%esp,%ebp
subl$20,%esp
将帧指针EBP压入栈中.然后把当前的SP复制到EBP,使其成为新的帧指针.我们把这
个被保存的FP叫做SFP.接下来将SP的值减小,为局部变量保留空间.
我们必须牢记:
内存只能以字为单位寻址.在这里一个字是4个字节,32位.因此5字节
的缓冲区会占用8个字节(2个字)的内存空间,而10个字节的缓冲区会占用12个字节(3个字)
的内存空间.这就是为什么SP要减掉20的原因.这样我们就可以想象function()被调用时
堆栈的模样(每个空格代表一个字节):
内存低地址
内存高地址
buffer2
buffer1
sfp
ret
a
b
c
<
------
[
][
]
堆栈顶部
堆栈底部
缓冲区溢出
~~~~~~~~~~~~
缓冲区溢出是向一个缓冲区填充超过它处理能力的数据所造成的结果.如何利用这个
经常出现的编程错误来执行任意代码呢?
让我们来看看另一个例子:
example2.c
voidfunction(char*str){
charbuffer[16];
strcpy(buffer,str);
charlarge_string[256];
inti;
for(i=0;
i<
255;
i++)
large_string[i]='
A'
;
function(large_string);
这个程序的函数含有一个典型的内存缓冲区编码错误.该函数没有进行边界检查就复
制提供的字符串,错误地使用了strcpy()而没有使用strncpy().如果你运行这个程序就
会产生段错误.让我们看看在调用函数时堆栈的模样:
buffer
*str
]
这里发生了什么事?
为什么我们得到一个段错误?
答案很简单:
strcpy()将*str的
内容(larger_string[])复制到buffer[]里,直到在字符串中碰到一个空字符.显然,
buffer[]比*str小很多.buffer[]只有16个字节长,而我们却试图向里面填入256个字节
的内容.这意味着在buffer之后,堆栈中250个字节全被覆盖.包括SFP,RET,甚至*str!
我们已经把large_string全都填成了A.A的十六进制值为0x41.这意味着现在的返回地
址是0x41414141.这已经在进程的地址空间之外了.当函数返回时,程序试图读取返回
地址的下一个指令,此时我们就得到一个段错误.
因此缓冲区溢出允许我们更改函数的返回地址.这样我们就可以改变程序的执行流程.
现在回到第一个例子,回忆当时堆栈的模样:
现在试着修改我们第一个例子,让它可以覆盖返回地址,而且使它可以执行任意代码.
堆栈中在buffer1[]之前的是SFP,SFP之前是返回地址.ret从buffer1[]的结尾算起是4个
字节.应该记住的是buffer1[]实际上是2个字即8个字节长.因此返回地址从buffer1[]的开
头算起是12个字节.我们会使用这种方法修改返回地址,跳过函数调用后面的赋值语句
'
x=1;
为了做到这一点我们把返回地址加上8个字节.代码看起来是这样的:
example3.c:
int*ret;
ret=buffer1+12;
(*ret)+=8;
intx;
x=0;
x=1;
printf("
%d\n"
x);
我们把buffer1[]的地址加上12,所得的新地址是返回地址储存的地方.我们想跳过
赋值语句而直接执行printf调用.如何知道应该给返回地址加8个字节呢?
我们先前使用
过一个试验值(比如1),编译该程序,祭出工具gdb:
[aleph1]$gdbexample3
GDBisfreesoftwareandyouarewelcometodistributecopiesofit
undercertainconditions;
type"
showcopying"
toseetheconditions.
Thereisabs
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 安全性 编程 方法