Patch免杀技术——及自动化的代码(1) 独家

免责声明:本公众号Hex010所提供的所有内容仅限于网络安全研究与学习,旨在为安全爱好者提供技术交流和学习的资源。任何个人或组织因传播、利用本公众号所提供的信息而进行的操作,所导致的直接或间接后果及损失,均由使用者本人负责。Hex010及作者对此不承担任何责任。

Patch免杀技术——及自动化的代码(1) 独家

PATCH

什么是patch?就是通过替换PE文件的二进制函数代码,让程序启动时执行修改后的函数代码,这个东西号称静态无敌,技术其实都是10年前的东西,当然,不是我说的,此图为证

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

技术实现

首先就是寻找合适PE文件


大小合适

没有静态链接特定DLL 文件,即打开不会出现诸如此类的弹窗:”由于找不到 xxx.dll,无法继续执行代码。重新安装程序可能会解决此问题。

寻找 Patch 点

以微信的 exe 为例,满足上述程序要求,程序名为 WeChat.exe先尝试运行一下,这里微信直接运行会弹窗,在没有 DLL 的情况下会提示(这种情况是缺少相应的动态链接的 DLL)

Patch免杀技术——及自动化的代码(1) 独家

用 IDAx64,找到 WinMain 函数,并使用 F5 查看伪代码,最终是选取了 sub_140002C700 作为 patch 的函数(其他的也可以,主要看程序启动能否调用到)

Patch免杀技术——及自动化的代码(1) 独家

然后我们要找到文件中的具体位置,也就是FOA(算法公式:VA-imagebase-节的rva+节的偏移),ida中函数的地址是140002C70,因为不是真实的地址,所以减去140000000(imagebase) 得出RVA 然后我们再减去节表的RVA(0X1000)+加上他的偏移地址那么在二进制中就是00002070

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

然后就是写shellcode

我们主要讲解后边的自动化这里不过多讲解

Sec-Fork/ShellCodeFrames: 使用纯C/C++编写的ShellCode生成框架 (https://github.com/Sec-Fork/ShellCodeFrames)

然后就是讲shellcode(bin文件用010edit打开)直接复制粘贴到这里就可以

Patch免杀技术——及自动化的代码(1) 独家

静态查杀结果还是强的

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

自动化

前边手动Patch是不是很简单,但我们是什么人,我们是要成为红队的男人,我们让他自己动(参考链接:https://xz.aliyun.com/t/15096?time__1311=GqjxuiitGQi%3DdGNDQiiQGkFyF%3D1%3Dqoera4D)

我们要patch就要找到main函数,怎么找,都是二进制文件,看官请看

流程:

  • 查找CRT函数入口点。

  • 查找CRT函数中mov r8操作指令。

  • 查找mov r8向下附近的call,找到main函数。

  • 查找main函数中call的函数,同时分析函数开头到ret的地址大小,若符合即为可patch函数。

CRT是什么,简单来说就是他掌管的是printf,内存分配等等。除非自己编写类CRT否则程序是有CRT的,而且最关键的是CRT调用了main函数,我们目前只有PE文件要获取CRT,就要解析PE,首先将文件写入内存,然后解析PE文件

Patch免杀技术——及自动化的代码(1) 独家

这里我们只分析crt在text段的情况,分析导入表中crt比较简单以后再说。

我们要定位CRT就要首先要找到他的特征,64程序中他的标志是

0x48, 0x89, 0x5C, 0x24, 0x08,当然有很多crt的相关函数都是这个标志,我们还需要其他条件来做判断

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

初始化已经完成了,接下来遍历节表寻找text段,当找到text段的时候,我们可以打印他的内存中的真实地址当他减去pMapped时就是他的文件中的真实地址也就是FOA

Patch免杀技术——及自动化的代码(1) 独家

然后遍历text查找crt的所有函数,并计算他的所有crt地址,这里就不演示了,下去自己可以试试,这里输出就一大片

Patch免杀技术——及自动化的代码(1) 独家

我们找出一堆crt怎么办呢,给他做过滤,基本过滤是寻找 mov r8 rax,也就是机械码0x4C, 0x8B, 0xC0 很多crt函数中并没有 mov r8 rax ,这个就过滤了近一半函数。

继续过滤,首先我们会遇到int 3c  就是 CC CC CC 这样的代码,这样的代码平时是一个断点,这里就是他的一个分割符,我们的crt中都没有遍历到 mov r8 rax 我们就跳出循环CC CC 也是。

有些函数呢他已经结束了,但没有用这样的分隔符号来做,“是跳转,他用了跳转!“,跳转有jmp,ret,他们的特点就是会用到5F,1个函数的结束,通常会依赖于某些典型的指令或模式,如栈恢复指令返回指令(ret)、跳转到其他函数或库(如 jmp 指令)等。但是他们都会经历一个特殊的阶段还原,5F: 这是 pop rdi,恢复寄存器 rdi,所以我们遇到5F就代表这个函数结束了就PASS。

还有的函数,运行到一定的地方就nop了,简称”死掉了”,他们可能是某些占位符,也可能是编译用来优化的结束符。所以还要过滤 0F 1F。

有可能还有我没有遇到的情况,这里所有代码主要是用来进行识别和过滤


Patch免杀技术——及自动化的代码(1) 独家

我们已经过滤了绝大多数的crt了,既然已经找到crt了,也找到crt下的 mov r8了,那么我们就离call main 不远了,这里寻找E8 (call)不仅是一个结果也是一个判断条件,当然我们还要过滤到FF FF FF 这样的机械码,因为main函数的初始化不会用到FF FF FF ,所以我们找到E8的地址就是我们call main 的地址

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

演示


Patch免杀技术——及自动化的代码(1) 独家

这里其实已经找到了,但为了各位直观我就不计算了,ida的减去140000000-1000+400 也是这个foa,直接用事实说话

Patch免杀技术——及自动化的代码(1) 独家

Patch免杀技术——及自动化的代码(1) 独家

我们010edit中查看FOA

Patch免杀技术——及自动化的代码(1) 独家

测试其他的软件

Patch免杀技术——及自动化的代码(1) 独家

篇幅问题,今天先讲到这里暂定为一,后边讲跳转到main,并检索适合存放shellcode的地方。


如果你觉得这篇文章有帮助,记得点赞、转发和收藏哦!感谢支持!有任何问题或者想讨论更多内容,都可以随时联系我。👇


原文始发于微信公众号(Hex010):Patch免杀技术——及自动化的代码(1) 独家

版权声明:admin 发表于 2024年9月29日 下午8:10。
转载请注明:Patch免杀技术——及自动化的代码(1) 独家 | CTF导航

相关文章