随着网络的普及,我们的生活越来越方便,但是网络安全也成了很多人面临的一个问题。特别是那些有着商业数据的企业电脑,更要注意上网安全常识,不然病毒会对我们造成严重的威胁。
一 前言
本文介绍的技术在实战中应用已久,但是由于一些原因并没有做文档化。本文对关键点给出了代码实现,加入了一些笔者的新的理解。
测试代码的目录结构如下:
test1: 32位 64位的shellcode和相应的测试工具 test2: x86 c2shellcode框架 test3: dup指令占位.text段的shellcode编写技巧 test4: 实现shellcode的二次SMC test5: x64 c2shellcode框架
二 功能性shellcode的概念
这是一个攻防对抗很激烈的年代,杀毒软件的查杀技术是立体的,特征码、云、主防、启发、虚拟机。如果恶意代码还只局限在必须依赖固定的PE格式,无 法快速变异和免杀。这要求恶意代码经过简单的处理就应该能躲过静态检测,不依赖于windows本身的loader可以加载运行。而shellcode正 好符合这种形式。本文所说的shellcode并不是传统意义上对长度容易产生苛刻要求的在漏洞利用场景里面使用的shellcode,而是一段可能源代 码有几千或者上万行,但是CopyMemory出来EIP指向过去之后就可以加载运行的二进制,称之为功能性shellcode。很明显,由于代码行数或 者对于功能性的要求,使用纯汇编来进行功能性shellcode的编写是很不划算的。
三 高级语言的选择
1 使用delphi编写功能性shellcode
目前流行的编写功能性shellcode的编译器主要是delphi跟vc。简单介绍一下delphi,由于Borland编译器的原因,编译的时 候字符串常量不是放在数据段里面,而是放到所在函数的后面,在处理字符串的时候比VC方便了不少,并且delphi支持X64内联汇编,写起X64的 shellcode更是如虎添翼。圈内比较早的前辈如Anskya(女王) xfish一般都是用delphi来进行功能性shellcode的编写。
2 使用VC编写功能性shellcode
在test1目录中,有两段二进制代码:32shellcode.bin、 64shellcode.bin。分别是两段可以运行于x86和x64上面的shellcode。可以打开debugview工具进行log捕捉。使用下面的命令测试两段shellcode。
32runbin.exe 32shellcode.bin
64runbin.exe 64shellcode.bin
如果是x64的系统,32shellcode.bin也将很健壮的运行在wow64上面。
接下来着重介绍VC编写功能性shellcode。
四 x86 c2shellcode 框架
1 c2shellcode框架简介
这是一个使用VS2008生成的编写32位shellcode的框架。使用它可以很方便的在shellcode中调用native api和ring3 api。在注释掉HHL_DEBUG开关之后,运行生成的EXE就可以生成shellcode。
我们来看一下这个工程。
void main() { #ifdef HHL_DEBUG InitApiHashToStruct(); ShellCode_Start(); #else InitApiHashToStruct(); #endif }
Main函数很简单,定义了一个调试开关。这个调试开关影响ShellData这个全局结构体。当注释掉这个开关,ShellData将附着在 shellcode的尾部。开启这个开关ShellData将存在于.data段,方便使用VC的IDE对shellcode进行C源代码级别的调试。
2 开启HHL_DEBUG调试开关之后的函数执行的流程
2.1填充函数hash到ShellData结构体当中
首先是InitApiHashToStruct这个函数。这里是一个比较传统的移位生成hash的函数,可以调用GetRolHash直接传递字符串来进行hash生成,也可以批量直接将hash填充到ShellData结构体当中。
DWORD GetRolHash(char *lpszBuffer) { DWORD dwHash = 0; while(*lpszBuffer) { dwHash = ( (dwHash <<25 )