首页
社区
课程
招聘
[翻译]Windows平台下的Shellcode代码优化编写指引
发表于: 2017-5-9 22:23 13074

[翻译]Windows平台下的Shellcode代码优化编写指引

2017-5-9 22:23
13074

前言

    在构造一个Shellcode载荷时总是存在多种方法,特别是对于Windows平台来说。需要手工编写所有的汇编代码,或者说编译器能够有所帮助吗?需要直接使用syscall,还是需要在内存中搜索函数?因为构造载荷一般来说不会很简单,所以我决定写一篇文章来专门论述相关问题。我习惯于用C语言来完成所有的工作,并使用Visual Studio来对其进行编译:因为C语言的源代码更加优美,编译器能够更好地对其进行优化,并且如果需要的话可以使用LLVM框架实现自己的混淆器。

    在本例中,我将针对于x86架构下的Shellcode代码;当然,相关的分析完全可以应用于x86(64位)架构下的Shellcode代码或者别的处理器。

寻找基本DLL

简介

当一个Shellcode载荷加载到Windows系统中的时候,第一步就是要定位需要使用的函数,即搜索存储函数的动态链接库(DLL)。为此,我们需要用到以下各小节所描述的不同的结构。

线程环境块

Windows系统使用TEB结构来描述一个线程,每个线程通过使用FSx86平台)或GSx86,64位平台)寄存器来访问其自身的TEB结构。TEB结构具体如下:

    因此,若想要访问PEB结构,只需要进行如下操作:

进程环境块

如果说TEB结构给出了一个线程的相关信息,那么PEB结构将告诉我们关于进程自身的信息,其中我们所需要的信息是基本DLL的位置。实际上,在Windows系统加载一个进程到内存中的时候,至少要映射两个DLL

·ntdll.dll,其中包含执行syscall的函数,它们都以前缀Nt开头(形如Nt*),并调用内核中以Zw开头(形如Zw*)名称相同的函数;

·kernel32.dll,在更高层次上使用NTDLL中的函数。比如,kernel32!CreateFileA函数将调用ntdll!NtCreateFileW函数,而后者又将调用ntoskrnl!ZwCreateFileW函数。

在不同版本的Windows系统下,其他的DLL可能已经存在于内存中,但是是完全可移植的;因此,我们假设以上两个DLL是唯一加载的DLL模块。

让我们看一下PEB结构,如下所示:

    可以看到,其中一个成员名为PEB.BeingDebugged,可被IsDebuggerPresent()函数使用;而我们感兴趣的部分是成员PEB.Ldr,其对应于如下结构:

        顾名思义,成员PEB.Ldr->In*OrderModuleList是包含所有已加载到内存中的DLL模块的链表(LIST_ENTRY);三个表以不同的顺序指向相同的对象。我更倾向于使用InLoadOrderModuleList,因为可以像使用一个指向_LDR_DATA_TABLE_ENTRY的指针一样直接使用InLoadOrderModuleList.Flink。例如,如果使用InMemoryOrderModuleList,由于InMemoryOrderModuleList.Flink指针指向下一个InMemoryOrderModuleList,所以LDR_DATA_TABLE_ENTRY将位于(_InMemoryOrderModuleList.Flink–0x10)的位置。每个链表成员具有如下结构:

BaseDllName包含DLL模块的名称(比如,ntdll.dll),而DllBase包含DLL模块所加载到内存中的地址。通常,InLoadOrderModuleList中的第一个成员就是可执行程序自身,在之后我们能够找到NTDLLKERNEL32;然而,我们并不确定在所有版本的Windows系统中都是这个次序,所以最好根据DLL名称(大写/小写)进行搜索。

DJB散列

    如前所述,我们并不信任DLL顺序而选择根据DLL名称进行搜索。然而在一段Shellcode代码中,使用ASCII字符串(或更糟的,UNICODE字符串)并不是一个好主意:这将使得我们的Shellcode代码过于臃肿!因此我建议,使用散列机制来比较DLL名称。由于其简洁有效性我选择使用DJB散列算法,具体代码如下所示:

    由于DLL名称可能大写也可能小写,因此在散列算法中最好满足如下等式关系:

代码

    现在我们已经讨论了如何完成以上工作,是时候来编码实现我们的想法了。具体代码如下所示:

如果想要使用其他的DLL模块,只需要使用LoadLibrary()函数来将其加载。不要着急,我们将在user32.dll相关的Shellcode代码中进行该项工作。

函数地址

简介

现在我们已经找到DLL,下一步需要在DLL内存空间中搜寻所需的函数在哪儿。幸运的是,透彻理解PE文件头部结构的前提下这并不复杂。要牢记的是,当我们讨论PE文件头部时,提到的大部分地址都与可执行程序地址相关。

可移植的执行体头部

    执行体的开始位置是一个DOS头部,但它只是为了兼容(DOS系统)而存在。具体结构如下所示:

    成员e_lfanew将指示NT头部的位置。由于这是一个相对地址,所以需要进行pFile+e_lfanew操作。NT头部具体结构如下所示:

    数据目录中包含了一些有趣成员的地址;而对我们来说,它包含了所有导出函数的地址。

    因此,我们可以使用DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress来直接获取导出目录的地址:

可以通过名字或者通过序号来导出一个函数;因此,以下三个数组保持更新:

·AddressOfFunctions,按照序号顺序依次保存函数的地址;

·AddressOfNames,保存函数名称;

·AddressOfNameOrdinals,保存序号,该数组与AddressOfNames数组次序相同。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/07/12
最新回复 (19)
雪    币: 14
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
翻译小组真给力!
2017-5-9 22:40
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
3
jiaojcheng 翻译小组真给力!
2017-5-9 23:52
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
翻译得不错,收藏了
2017-5-10 00:44
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
5
yy虫子yy 翻译得不错,收藏了
能对大家有所帮助真是莫大的鼓励!我会继续努力的!
2017-5-10 06:50
0
雪    币: 189
活跃值: (154)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
文章很好,翻译的也很好。
2017-5-10 10:23
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
7
flamepeak 文章很好,翻译的也很好。
谢谢谢谢
2017-5-10 11:05
0
雪    币: 6112
活跃值: (1212)
能力值: (RANK:30 )
在线值:
发帖
回帖
粉丝
8
加油,期待更多优秀的译文
2017-5-10 22:10
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
9
哆啦咪 加油,期待更多优秀的译文[em_13]
嗯嗯!我一定继续努力,绝不辜负组织的期待,哈哈哈!
2017-5-11 07:06
0
雪    币: 152
活跃值: (29)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
谢谢分享
2017-5-11 07:22
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
11
RichardE 谢谢分享[em_63]
互相交流,共同进步
2017-5-11 10:08
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享,虽然我是一个码盲。
2017-5-12 14:43
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
13
formattings 感谢分享,虽然我是一个码盲。
水平都是一点一点提高的,加油!
2017-5-15 23:58
0
雪    币: 3302
活跃值: (1144)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
14
我想问下这个,  这个代码框里的  内容  是怎么  编辑的?  html  还是  编辑器  写的?
2017-5-17 23:48
0
雪    币: 152
活跃值: (29)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
fyb波 我想问下这个, 这个代码框里的 内容 是怎么 编辑的? html 还是 编辑器 写的?

2017-5-18 08:31
0
雪    币: 3302
活跃值: (1144)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
16
代码颜色怎么设置的
2017-5-18 09:08
0
雪    币: 1784
活跃值: (512)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
17
fyb波 代码颜色怎么设置的
代码颜色是根据你的选择自动设置的
2017-5-19 10:11
0
雪    币: 45
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
字符串那个宏太骚了
2017-8-13 23:29
0
雪    币: 79
活跃值: (373)
能力值: ( LV11,RANK:195 )
在线值:
发帖
回帖
粉丝
19
长字符串那个字符串宏有问题?谁遇到过?
2018-10-16 20:51
0
雪    币: 43
活跃值: (388)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
20
shellcode我还是喜欢用gcc,windows下可以用mingw-w64
2018-10-16 21:21
0
游客
登录 | 注册 方可回帖
返回
//