木马免杀之PE文件

当你好不容易弄出来一个木马(具体可参考这里)的时候,却被杀毒软件轻易的就检测出来了,那一切岂不是白费了。Win10中的windows defender基于流量检测很容易把常见的木马程序检测出来,那怎么绕过这些检测?

对于此问题,打算开一个专题进行木马免杀的分析,先从最最重要的PE文件说起,要攻击Windows系统,如果不懂PE文件,面对杀毒软件,则只能束手就擒了。

PE文件

PE(Portable Execute)文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任何扩展名

PE全称是Portable Execute,实际上,这种文件格式没有做到Portable Execute,只能用在Windwos。

基本结构

32位PE的基本结构如下,64位的大同小异。
在这里插入图片描述

如下是qq的16进制打开后解析出相应的字段,和上图是匹配的。
在这里插入图片描述
Dos文件头和Dos块

<pre class="prettyprint linenums prettyprinted" style="box-sizing: border-box; margin: 0px; padding: 8px 0px 6px; font-family: consolas, menlo, courier, monospace, "Microsoft Yahei" !important; background: rgb(241, 239, 238); border: 1px solid rgb(226, 226, 226) !important; display: block; border-radius: 0px; overflow-y: auto; color: rgb(80, 97, 109); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; font-size: 10px; line-height: 12px;">

  1. typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
  2. WORD e_magic; // Magic number
  3. WORD e_cblp; // Bytes on last page of file
  4. WORD e_cp; // Pages in file
  5. WORD e_crlc; // Relocations
  6. WORD e_cparhdr; // Size of header in paragraphs
  7. WORD e_minalloc; // Minimum extra paragraphs needed
  8. WORD e_maxalloc; // Maximum extra paragraphs needed
  9. WORD e_ss; // Initial (relative) SS value
  10. WORD e_sp; // Initial SP value
  11. WORD e_csum; // Checksum
  12. WORD e_ip; // Initial IP value
  13. WORD e_cs; // Initial (relative) CS value
  14. WORD e_lfarlc; // File address of relocation table
  15. WORD e_ovno; // Overlay number
  16. WORD e_res[4]; // Reserved words
  17. WORD e_oemid; // OEM identifier (for e_oeminfo)
  18. WORD e_oeminfo; // OEM information; e_oemid specific
  19. WORD e_res2[10]; // Reserved words
  20. LONG e_lfanew; // File address of new exe header
  21. } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

</pre>

对于PE文件来说,有用的是最后一个字段,这个字段指出了真正的PE头在文件中的位置。 [图片上传失败...(image-290f53-1597586969215)]

PE文件头

<pre class="prettyprint linenums prettyprinted" style="box-sizing: border-box; margin: 0px; padding: 8px 0px 6px; font-family: consolas, menlo, courier, monospace, "Microsoft Yahei" !important; background: rgb(241, 239, 238); border: 1px solid rgb(226, 226, 226) !important; display: block; border-radius: 0px; overflow-y: auto; color: rgb(80, 97, 109); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; font-size: 10px; line-height: 12px;">

  1. typedef struct _IMAGE_NT_HEADERS {
  2. DWORD Signature;
  3. IMAGE_FILE_HEADER FileHeader;
  4. IMAGE_OPTIONAL_HEADER32 OptionalHeader;
  5. } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

</pre>

Signature是00004550h,也就是字符'P'和'E'。对于OptionalHeader尽管按照字面的理解是可选的,实际上在每一个PE文件中都是需要的。
在这里插入图片描述

每个结构体的具体信息如下:

  1. IMAGEFILEHEADER

    在这里插入图片描述

    最后一个字段Characteristics代表文件的属性。如果是PE文件,这个字段的值是010fh,如果是dll文件,这个字段的值是210eh。

  2. IMAGEOPTIONALHEADER32

    在这里插入图片描述

  • AddressOfEntryPoint指出文件被执行时的入口地址,这个地址是RVA(稍后会介绍)。如果像在程序运行前执行一段程序,那么可以把这个入口地址指向你想执行的程序。

  • ImageBase指出文件优先载入的地址,一般exe默认优先装入的地址是400000h,而dll是10000000h

  • SectionAlignment指定了节被装入内存后的对齐单位,FileAlignment指定了节存储在磁盘文件时的对齐单位

  • DataDirectory
    在这里插入图片描述

    很重要的结构,由16个相同的IMAGEDATADIRECTORY结构组成。其中有导入表、导出表、资源表数据块。

节表和节

Windows装载器在装载DOS部分,PE文件头部分和节表头部分不进行任何处理,而装载节的时候根据节的属性做不同的处理。下图展示了PE文件到内存的映射。
在这里插入图片描述
  1. 节表
    在这里插入图片描述
  • VirtualAddress指出节被装载到内存后的偏移位置
  • PointerToRawData指出节在磁盘文件中所处的位置

RVA和文件偏移的转换

RVA应该时PE文件相关最重要的概念了,导入表导出表等的定位都需要用到RVA。

在这里插入图片描述

下图展示了RVA的含义:
在这里插入图片描述

相关计算:
在这里插入图片描述

msf中巧妙调用ReflectiveLoader

在msf中,反射dll注入使用的非常普遍。这段代码后续会详细讲解,这是msf远程控制最核心的一段代码,"小马"(stager)拉"大马"(stage)得以实现,基于的就是这段代码。

<pre class="prettyprint linenums prettyprinted" style="box-sizing: border-box; margin: 0px; padding: 8px 0px 6px; font-family: consolas, menlo, courier, monospace, "Microsoft Yahei" !important; background: rgb(241, 239, 238); border: 1px solid rgb(226, 226, 226) !important; display: block; border-radius: 0px; overflow-y: auto; color: rgb(80, 97, 109); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; font-size: 10px; line-height: 12px;">

  1. def asm_invoke_dll(opts={})
  2. asm = %Q^
  3. ; prologue
  4. dec ebp ; 'M'
  5. pop edx ; 'Z'
  6. call $+5 ; call next instruction
  7. pop ebx ; get the current location (+7 bytes)
  8. push edx ; restore edx
  9. inc ebp ; restore ebp
  10. push ebp ; save ebp for later
  11. mov ebp, esp ; set up a new stack frame
  12. ; Invoke ReflectiveLoader()
  13. ; add the offset to ReflectiveLoader() (0x????????)
  14. add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)}
  15. call ebx ; invoke ReflectiveLoader()
  16. ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
  17. push edi ; push the socket handle
  18. push 4 ; indicate that we have attached
  19. push eax ; push some arbitrary value for hInstance
  20. mov ebx, eax ; save DllMain for another call
  21. call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
  22. ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
  23. ; push the exitfunk value onto the stack
  24. push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
  25. push 5 ; indicate that we have detached
  26. push eax ; push some arbitrary value for hInstance
  27. call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
  28. ^
  29. end

</pre>

其中 add ebx,#{"0x%.8x" % (opts[:rdi_offset] - 7)} 用来获取ReflectiveLoader的虚拟地址。rdi_offset获取的是ReflectiveLoader的RVA地址。这段代码翻译过来就是ebx-7 = 基址,然后再加上RVA就得到了ReflectiveLoader的虚拟地址。

公众号

更多内容,欢迎关注我的公众号:无情剑客。 [图片上传失败...(image-f00d29-1597586969215)]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350