隐藏IAT和字符串

发布时间 2023-12-13 18:14:28作者: fdx_xdf

隐藏IAT和字符串

0x01 IAT

IAT即导入表,它记录了我们的文件用了哪些函数。

在杀软检测恶意程序时,导入表是一个重要的检测项,比如说我们的程序调用了Virtual AllocCreateThread,且VirtualAlloc的最后一个参数是0x40(即PAGE_EXECUTE_READWRITE ),那么在杀软看来,我们的程序就是一个高危文件。

我们所要做的就是隐藏我们所使用的敏感API,下面是一个小demo:

#include<stdio.h>
#include<Windows.h>

int main()
{
    printf("hello world\n");
    MessageBox(0, TEXT("hello world"), 0, 0);
    return 0;
}

我们编译后执行,得到结果如下:

image-20231213160421982

我们用dumpbin来查看我们的导入,命令如下:

dumpbin /IMPORTS demo.exe

image-20231213163255347

可以看到在USER32.dll中引用了MessageBoxW函数,我们现在尝试利用自定义MessageBoxW函数来隐藏其在导出表中的出现。

首先找到函数的原型:

image-20231213161417271

然后开始我们的自定义:

#include<stdio.h>
#include<Windows.h>

typedef int(WINAPI* pMessageBoxW)(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType
    );

pMessageBoxW MyMessageBoxW = (pMessageBoxW)GetProcAddress(LoadLibrary(L"USER32.dll"), "MessageBoxW");

int main()
{
    printf("hello world\n");
    MyMessageBoxW(0, TEXT("hello world"), 0, 0);
    return 0;
}

这里我们定义好函数之后,使用GetProcAddress将对应dll中的对应函数的地址拿到,然后给我们自己定义的函数,从而达到隐藏的目的。

GetProcAddress的定义如下:

GetProcAddress(
    _In_ HMODULE hModule,
    _In_ LPCSTR lpProcName
    );

第一个参数代表句柄,第二个参数代表函数名称。

下面看看隐藏的效果:

image-20231213163114631

image-20231213163207223

现在看不到我们的MessageBoxW了。

当然,这里还是会出现我们的GetProcAddress等等函数,我们也可以尝试使用自实现getprocaddress或者peb的方式来实现。

我们在自己编写shellcode时也会用到上面两种情况。

0x02 字符串

一般情况下,C/C++程序中的字符串常量会被硬编码到程序中(.data段,也就是数据段),尤其是全局变量最容易被定位到。

比如我们上例的hello world,利用strings查看我们程序里面一些字符串,命令如下

strings Hide_IAT_String.exe

image-20231213164453201

当然仅仅是Hello World是没问题的,如果是我们上述隐藏IAT时的api名字,或者一些工具的参数信息,被杀软检测到就极有可能被杀。

image-20231213171009547

所以我们可以自实现一些简单的加解密函数来隐藏字符串,下面是一个小demo

#include <stdio.h>
#include <Windows.h>

void reverseString(char* str) {
    int length = strlen(str);
    char temp;
    for (int i = 0; i < length / 2; i++) {
        temp = str[i];
        str[i] = str[length - i - 1];
        str[length - i - 1] = temp;
    }
}

int main() {
    char str[] = "dlrow olleh";
    reverseString(str);
    printf("%s",str);
}

image-20231213180937798

可以看到没有找到hello相关的字符串了。

0x03参考链接

静态恶意代码逃逸(第七课) | 倾旋的博客 (payloads.online)

通过隐藏导入表的方式规避杀软 - 先知社区 (aliyun.com)

静态恶意代码逃逸(第八课) | 倾旋的博客 (payloads.online)