Shellcode 分段执行技术原理
作者:riusksk(泉哥)
主页:http://riusksk.blogbus.com
前言
由于在实际溢出利用中,我们可能会遇到内存中没有足够的空间来存放我们的 shellcode,但我们又可以
控制多块小内存空间的内容,那些此时我们就可使用 shellcode 分段执行技术来进行利用,这种方法在国外被
称为“Omelet Shellcode”,属于 egg hunt shellcode 的一种形式,它先在用户地址空间中寻找与其相匹配的各
个小内存块(egg),然后再将其重构成一块大块的 shellcode,最后执行它。此项技术最初是由荷兰著名黑客
SkyLined 在其主页上公布的(具体代码参见附件),该黑客先前就职于 Microsoft,但于 2008 年初转入 Google,
同时他也是著名的字母数字型 shellcode 编码器 Alpha2 / Alpha3 的开发者。
原理分析
将 Shellcode 拆分成固定大小的多个代码块,各个代码块中包含有其字节大小 size,索引值 index,标记
marker(3 字节)和数据内容 data,如图 1 所示:
图 1
当 egghunter 代码开始执行时,它会在用户内存空间中(0x00000000~0x80000000)搜索这些被标记的小块,
然后在内存中重构成最初的 shellcode 并执行它。而当 shellcode 执行时,它还会安装 SEH 以处理访问违例时的
情况。若出现访问违例,则 SEH handler 会将地址与 0xFFF 进行或运算,然后再加 1,相当于进入下一内存页,
以跳过不可读取的内存页。如果搜索的内存地址大于 0x7FFFFFFF,那么终止搜索,并在内存中重构 shellcode
用于执行,否则重置栈空间,防止因递归进行异常处理而将栈空间耗尽,它会重新设置 SEH handler 并继续搜
索内存。相应代码如下:
reset_stack:
; 重置栈空间以防止递归进行异常处理时耗尽栈空间,并设置自己的异常处理例程以处理扫描内存时出现的访问违例情况
XOR EAX, EAX ; EAX = 0,并作为计数器
MOV ECX, [FS:EAX] ; ECX = SEH 结构链表
find_last_SEH_loop:
MOV ESP, ECX ; ESP = SEH 结构
POP ECX ; ECX = 下一个 SEH 结构指针
CMP ECX, 0xFFFFFFFF ; 判断是否是最后一个 SEH 结构
JNE find_last_SEH_loop ; 不是则跳走并继续查找
POP EDX ; 最后一个 SEH 结构中的异常处理例程 handler
CALL create_SEH_handler ; 自定义 SEH handler
SEH_handler:
评论0