安界|自动重构Meterpreter绕过杀软·续

前言
要与Windows操作系统进行交互 , 软件通常会从动态链接库(DLL)中导入函数 。 这些函数往往以明文形式存在“导入表”中 , 杀毒软件通常会利用此功能来检测和推断恶意行为 。 为此我们展示了混淆器的思路和实现 , 该混淆器允许重构任何C/C++软件以消除此痕迹 , 我们研究的重点是Meterpreter 。 源代码位于:https://github.com/scrt/avcleaner.
介绍
在先前的文章中 , 我们展示了如何在不使用正则表达式的情况下准确地替换源代码中的字符串 。 目的是减少那些依靠静态签名的二进制和安全性软件的内存占用 。
然而 , 除了源代码本身中的字符串文字外 , 我们还可以静态地收集和分析许多其他的指纹 。 在这篇文章中 , 我们将展示如何从二进制文件中手动隐藏API导入 , 然后自动执行C/C++编写的软件 。
【安界|自动重构Meterpreter绕过杀软·续】API导入问题
让我们编写并构建一个简单的C程序 , 执行该程序会弹出一个警告框:#include
intmain(intargc,char**argv){MessageBox(NULL,"Test","Something",MB_OK);return0;}
然后 , 使用你喜欢的编译器进行编译 。 在这里 , MinGW用于从macOS到Windows的跨版本编译:x86_64-w64-mingw32-gcctest.c-o/tmp/toto.exe
之后 , 可以使用rabin2(包含在radare2中)或者GNU的字符串处理工具strings列出字符串:205│2010x00003c920x0040869278.idataasciistrncmp206│2020x00003c9c0x0040869c89.idataasciivfprintf207│2030x00003ca80x004086a81112.idataasciiMessageBoxA208│2040x00003d100x004087101213.idataasciiKERNEL32.dll209│2050x00003d840x004087841011.idataasciimsvcrt.dll210│2060x00003d940x004087941011.idataasciiUSER32.dll...9557│95530x0004f4810x00458e813031ascii.refptr.__native_startup_state9558│95540x0004f4a00x00458ea01112ascii__ImageBase9559│95550x0004f4ac0x00458eac1112asciiMessageBoxA9560│95560x0004f4b80x00458eb81213asciiGetLastError9561│95570x0004f4c50x00458ec51718ascii__imp_MessageBoxA9562│95580x0004f4d70x00458ed72324asciiGetSystemTimeAsFileTime9563│95590x0004f4ef0x00458eef2223asciimingw_initltssuo_force9564│95600x0004f5060x00458f061920ascii__rt_psrelocs_start
从上面显示的控制台输出中可以明显看出 , 字符串MessageBoxA出现了3次 。 这是因为此函数必须从User32.dll中导入(稍后会对此进行详细介绍) 。
当然 , 该字符串不容易引起反病毒人士的注意 , 但是对于以下API来说绝对会备受关注:
InternetReadFile
ShellExecute
CreateRemoteThread
OpenProcess
ReadProcessMemory
WriteProcessMemory

隐藏API导入
在继续之前 , 让我们简要介绍一下开发人员在Windows系统上调用外部库中函数的不同方法:加载时动态链接运行时动态链接加载时动态链接
这是解析外部库中函数的默认方法 , 并且实际上由链接程序自动处理 。 在编译时 , 将应用程序链接到它依赖的每个动态链接库(DLL)的导入库(.lib) 。 对于每个导入的函数 , 连接器会分别将对应条目写入关联DLL的IAT(导入地址表)中
启动应用程序后 , 操作系统将扫描IAT并映射进程地址空间中列出的所有库 , 并且每个导入函数的地址都将更新为指向DLL的导出地址表中的相应条目 。
安界|自动重构Meterpreter绕过杀软·续
文章图片
运行时动态链接
另一种方法是手动执行此操作 , 方法是先用LoadLibrary加载相应的库 , 然后用GetProcAddress解析函数的地址 。 例如 , 可以修改前面的示例 , 使其依赖于运行时动态链接 。
首先 , 必须为APIMessageBoxA定义一个函数指针 。 在开始之前 , 让我们分享一个小技巧 , 以帮助那些不熟悉C的人了解C语言中函数指针的语法: