渗透测试与漏洞利用系列课程【第三课】

2018-04-1007:00:16 发表评论

渗透测试与漏洞利用系列课程【第三课】

漏洞利用概念

有关概念

利用程序漏洞去执行shellcode以便劫持进程的控制权。代码植入--淹没返回地址--劫持进程的控制权,让程序跳转去执行shellcode

Shellcode往往需要用汇编语言编写,并转换成二进制机器码,其内容和长度经常会受到很多苛刻限制,开发和调试的难度很高。

示例

部分内容被隐藏
需登陆后可查看

int MessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);

写出调用这个API的汇编代码--翻译成机器代码--用十六进制编辑工具填入reg.txt文件。

用汇编语言调用MessageboxA

  • 装载动态链接库user32.dll
  • 获得这个函数的入口地址
  • 调用前向栈中按从右向左的顺序压入MessageBoxA的4个参数

Dependency Walker -- 随便拖拽一个有图形界面的PE文件进去--找到并选中user32.dll---右栏中会列出所有导出函数及偏移地址 / 下栏列出了PE文件用到的所有的库的基地址

渗透测试与漏洞利用系列课程【第三课】

user32.dll 的基地址为0x77D10000MessageBoxA的偏移地址为0x000407EA。基地址加上偏移地址就得到了MessageBoxA函数在内存中的入口地址:0x 77D507EA

字符串westwest压入栈区--消息框的文本和标题都显示为westwest,重复压入指向这个字符串的指针--第1个和第4个参数这里都将设置为NULL

写出的汇编代码和指令所对应的机器代码如表所示。

机器代码(十六进制)汇编指令注释
33 DBXOR EBX,EBX将EBX的值设置为0
53PUSH EBX将EBX的值入栈
68 77 65 73 74PUSH 74736577将字符串west入栈
68 77 65 73 74PUSH 74736577将字符串west入栈
8B C4MOV EAX,ESP将栈顶指针存入EAX(栈顶指针的值就是字符串的首地址)
53PUSH EBX入栈Messagebox的4个参数-类型
50PUSH EAX入栈Messagebox的4个参数-标题
50PUSH EAX入栈Messagebox的4个参数-消息
53PUSH EBX入栈Messagebox的4个参数-句柄
B8 EA 07 D5 77MOV EAX, 0x77D507EA调用MessageBoxA函数
FF D0CALL EAX调用MessageBoxA函数

得到的shellcode为:33 DB 53 68 77 65 73 74 68 77 65 73 74 8B C4 53 50 50 53 B8 EA 07 D5 77 FF D0。将shellcode写入reg.txt文件,且在返回地址处写buffer的地址。Buffer的地址(OllyDbg查看 or 反汇编方式) = 0018FAB8

这样一运行 pwd.exe,verify函数返回地址跳到了buffer--执行 messageBox--弹出窗口

Shellcode编写

  1. 特定字符需要转码,比如NULL
  2. 动态获取API地址

自行编写Shellcode / 23333

  • 用c写要执行的shellcode
  • 换成对应的汇编代码
  • 根据汇编代码,找到对应地址中的机器码 / 在汇编第一行代码处打断点 -- 利用调试 -- 定位具体内存中的地址

漏洞利用技术

静态shellcode地址的利用技术

部分内容被隐藏
需登陆后可查看

heap spray技术

不支持或者不能实现精确定位shellcode。例,浏览器或其使用的activeX控件中存在漏洞,攻击者可以生成 HTML文件诱发用户访问来触发这个漏洞。HTML页面中的Javascript 可以在用户计算机中申请堆内存shellcode通过 Javascript 被注入到堆空间中。由于堆分配地址随机性较大,为了解决shellcode在堆中的定位以便触发,可以采用heap spray的方法

Heap Spray也称为堆喷洒技术,是在shellcode的前面加上大量的滑板指令slide code,组成一个非常长的注入代码段。然后向系统申请大量内存,并且反复用这个注入代码段来填充。这样使得内存空间被大量的注入代码所占据。攻击者结合漏洞利用技术,只要使程序跳转到堆中被填充了注入代码的任何一个地址,程序指令就会顺着滑板指令最终执行到shellcode代码。

滑板指令slide code是由大量NOP(no-operation)空指令0x90填充组成的指令序列,当遇到这些NOP指令时,CPU指令指针会一个指令接一个指令的执行下去,中间不做任何具体操作,直到“滑”过最后一个滑板指令后,接着执行这些指令后面的其他指令,往往后面接着的是shellcode代码。Shellcode的正常执行,需要从shellcode的第一条指令开始。前面加上滑板指令之后,程序跳转后只要命中滑板指令中的任何一个,就可以保证它后面接着的shellcode能成功执行。

随着一些新的攻击技术的出现,滑板指令除了利用NOP指令填充外,也逐渐开始使用更多的类NOP指令,譬如0x0C0x0D

Heap Spray用于针对浏览器漏洞的攻击较多,尤其是网页木马应用较多。这些漏洞利用程序通常会将EIP指向堆区的0x0C0C0C0C地址,然后使用Javascript脚本申请大量的堆内存,在内存空间中填充了大量包含0x90shellcode的注入代码。漏洞利用程序从低地址向高地址一直申请超过200MB的堆内存空间,由于200MB对应的内存地址为0x0C800000,高于EIP指向的0x0C0C0C0C,因而,申请的堆空间超过200MB时将覆盖0x0C0C0C0C。只要注入代码中填充的0x90能够覆盖0x0C0C0C0C的位置,shellcode就会最终执行。

Heap Spray技术通过使用类NOP指令来进行覆盖,对shellcode地址的跳转准确性要求不高,从而增加了缓冲区溢出攻击的成功率。然而,Heap Spray会导致被攻击进程的内存占用非常大,计算机无法正常运转,因而容易被察觉。一般配合堆栈溢出攻击,不能用于主动攻击,也不能保证成功。

软件防护技术

介绍Windows操作系统中提供的主要几种软件漏洞利用的防范技术。

  1. GS Stack protection

    GS Stack Protection技术是一项缓冲区溢出的检测防护技术。VC++编译器中提供了一个/GS编译选项,选择该选项,编译器针对函数调用和返回时添加保护和检查功能的代码,在函数被调用时,在缓冲区和函数返回地址增加一个32位的随机数security_cookie,在函数返回时,调用检查函数检查security_cookie的值是否有变化。

    security_cookie在进程启动时会随机产生,并且它的原始存储地址因Windows操作系统的ASLR机制也是随机存放的,攻击者无法对security_cookie进行篡改。当发生栈缓冲区溢出攻击时,对返回地址或其他指针进行覆盖的同时,会覆盖security_cookie的值,因此在函数调用结束返回时,对security_cookie进行检查就会发现它的值变化了,从而发现缓冲区溢出的操作,中断当前进程并报错。

    因此,GS技术对基于栈的缓冲区溢出攻击能起到很好的防范作用。

  2. DEP

    数据执行保护DEP(data execute prevention)技术可以 限制内存堆栈区的代码为不可执行状态 -- 防范溢出后代码的执行

    Windows操作系统中,默认情况下将 包含执行代码和DLL文件的txt段 即 代码段 的内存区域设置为 可执行代码的内存区域。其他的内存区域不包含执行代码,应该不能具有代码执行权限,但是Windows XP及其之前的操作系统,没有对这些内存区域的代码执行进行限制。因此,对于缓冲区溢出攻击,攻击者能够对 内存的堆栈 或 堆的缓冲区 进行覆盖操作,并执行写入的shellcode代码。启用DEP机制后,DEP机制将这些敏感区域设置不可执行的non-executable标志位,因此在溢出后即使跳转到恶意代码的地址,恶意代码也将无法运行,从而有效地阻止了缓冲区溢出攻击的执行。

    DEP分为软件DEP和硬件DEP。硬件DEP需要CPU的支持,需要CPU在页表增加一个保护位NX(no execute),来控制页面是否可执行。现在CPU一般都支持硬件NX,所以现在的DEP保护机制一般都采用的硬件DEP,对于DEP设置non-executable标志位的内存区域,CPU会添加NX保护位来控制内存区域的代码执行。

  3. ASLR

    地址空间分布随机化ASLR(addressspace layout randomization),将系统关键地址随机化,使攻击者无法获得需要跳转的精确地址。Shellcode需要调用一些系统函数才能实现系统功能达到攻击目的,因为这些函数的地址往往是系统DLL(如kernel32. Dll)、可执行文件本身、栈数据或PEBProcess Environment Block,进程环境块)中的固定调用地址,所以为shellcode的调用提供了方便。

    使用ASLR技术的目的就是打乱系统中存在的固定地址,使攻击者很难从进程的内存空间中找到稳定的跳转地址。ASLR随机化的关键系统地址包括: PE文件(exe文件和dll文件)映像地址、堆栈基址、堆地址、PEB和TEB(Thread Environment Block,线程环境块)地址等。

    当程序启动将执行文件加载到内存时,操作系统通过内核模块提供的ASLR功能,在原来映像基址的基础上加上一个随机数作为新的映像基址。随机数的取值范围限定为1至254,并保证每个数值随机出现。

  4. SafeSEH

    SEHStructured Exception Handler)是Windows异常处理机制所采用的重要数据结构链表。程序设计者可以根据自身需要,定义程序发生各种异常时相应的处理函数,保存在SEH中。通过精心构造,攻击者通过缓冲区溢出覆盖SEH中异常处理函数句柄,将其替换为指向恶意代码shellcode的地址,并触发相应异常,从而使程序流程转向执行恶意代码。

    SafeSEH就是一项保护SEH函数不被非法利用的技术。微软在编译器中加入了/SafeSEH选项,采用该选项编译的程序将PE文件中所有合法的SEH异常处理函数的地址解析出来制成一张SEH函数表,放在PE文件的数据块中,用于异常处理时候进行匹配检查。

    在该PE文件被加载时,系统读出该SEH函数表的地址,使用内存中的一个随机数加密,将加密后的SEH函数表地址、模块的基址、模块的大小、合法SEH函数的个数等信息,放入ntdll.dllSEHIndex结构中。在PE文件运行中,如果需要调用异常处理函数,系统会调用加解密函数解密从而获得SEH函数表地址,然后针对程序的每个异常处理函数检查是否在合法的SEH函数表中,如果没有则说明该函数非法,将终止异常处理。接着要检查异常处理句柄是否在栈上,如果在栈上也将停止异常处理。这两个检测可以防止在堆上伪造异常链和把shellcode放置在栈上的情况,最后还要检测异常处理函数句柄的有效性。

    从Vista开始,由于系统PE文件在编译时都采用SafeSEH编译选项,因此以前那种通过覆盖异常处理句柄的漏洞利用技术,也就不能正常使用了。

  5. SEHOP

    结构化异常处理覆盖保护SEHOPStructured Exception Handler Overwrite Protection)是微软针对SEH攻击提出的一种安全防护方案。SEH攻击是指通过栈溢出或者其他漏洞,使用精心构造的数据覆盖SEH上面的某个函数或者多个函数,从而控制EIP(控制程序执行流程)。

    微软提供这个功能是在Windows Vista SP1Windows 7以及它们的后续版本。它是以一种SEH扩展的方式提供的,通过对程序中使用的SEH结构进行一些安全检测,来判断应用程序是否受到了SEH攻击。SEHOP的核心是检测程序栈中的所有SEH结构链表的完整性,SEHOP针对下列条件进行检测,包括SEH结构都必须在栈上,最后一个SEH结构也必须在栈上;所有的SEH结构都必须是4字节对齐的;SEH结构中异常处理函数的句柄handle(即处理函数地址)必须不在栈上;最后一个SEH结构的handle必须是ntdll!FinalExceptionHandler函数,最后一个SEH结构的next seh指针必须为特定值0xFFFFFFFF等。

    当进行异常处理时,由系统接管进行异常处理,因此SEHOP由系统独立来完成,应用程序不用做任何改变,只需要在操作系统中开启SEHOP防护功能即可。开启SEHOP,可以在注册表编辑器找到注册表子项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel,查看其包含的DisableExceptionChainValidation的值,将其注册表项的值更改为 0,则表示启用了SEHOP。如果没有此注册表项,可创建一个DWORD类型的DisableExceptionChainValidation,并将其设为0。

CE安全网
CE安全网广告位招租

发表评论

您必须登录才能发表评论!