免杀基础-IAT隐藏

admin 2024年12月28日13:53:49评论8 views字数 10027阅读33分25秒阅读模式

免杀基础-IAT隐藏

导入表包含了导入的DLL和使用的函数 其中如Kernel32.dll下的CreateRemoteThread VirtualAllocEx等函数被杀软认为是高度可疑的

我们可以通过导入表隐藏来减小被判断为恶意软件的几率

动态调用

使用Loadlibrary GetProcAddress来动态加载函数

pVirtualAllocEx myVirtualAllocEx = (pVirtualAllocEx)GetProcAddress(GetModuleHandleA("KERNEL32.DLL"), "VirtualAllocEx");

这个解决方案存在两个问题

第一个是VirtualAllocEx字符串会存在

第二个是导入了新的敏感函数GetProcAddress GetModuleHandleA

免杀基础-IAT隐藏

第一个问题可以通过 对字符串加密 或者使用局部变量数组来解决

char str1[] = {'V','i','r','t','u','a','l','A','l','l','o','c','E','x',''};

pVirtualAllocEx myVirtualAllocEx = (pVirtualAllocEx)GetProcAddress(GetModuleHandleA("KERNEL32.DLL"), str1);

注意是局部变量 全局变量无效

第二个问题的解决方案是自实现GetProcAddress GetModuleHandle

自实现GetProcAddress

GetProcAddress接收两个参数 一个是指定dll基址 一个是导出函数名

dll是pe文件 我们可以自己来遍历导出表对比name 来拿到RVA

免杀基础-IAT隐藏

获取导出表

void getExportTable(HMODULE module,PIMAGE_EXPORT_DIRECTORY* exportTable) {

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)module;

    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD64)module + pDosHeader->e_lfanew);

    IMAGE_DATA_DIRECTORY dataDir = (IMAGE_DATA_DIRECTORY)pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];

    *exportTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD64)module + dataDir.VirtualAddress);

}

遍历导出表拿地址
FARPROC myGetProcAddr(HMODULE module,PIMAGE_EXPORT_DIRECTORY exportTable,LPCSTR funcName) {

    PDWORD NameArray = (PDWORD)((DWORD64)module + exportTable->AddressOfNames);

    PDWORD AddressArray = (PDWORD)((DWORD64)module + exportTable->AddressOfFunctions);

    PWORD  OrdinalArray = (PWORD)((DWORD64)module + exportTable->AddressOfNameOrdinals);

    for (SIZE_T i = 0; i < exportTable->NumberOfNames; i++) {

        LPCSTR currentName = (LPCSTR)((DWORD64)module + NameArray[i]);

        if (strcmp(funcName, currentName) == 0) {

            return (FARPROC)((DWORD64)module + AddressArray[OrdinalArray[i]]);

        }

    }

}

免杀基础-IAT隐藏

自实现GetModuleHandle

现在解决了GetProcAddress的问题 再来解决HMODLUE的获取 直接读文件当然也行

PEB中有三个链表 描述的是同一组模块 但是顺序不同 其中存储着加载到进程的模块

免杀基础-IAT隐藏

通过遍历链表拿到指定的模块即可 相关结构定义可以在如下网站找到

https://github.com/winsiderss/systeminformer

https://doxygen.reactos.org/

typedef struct _UNICODE_STRING

{

    USHORT Length;

    USHORT MaximumLength;

    PWSTR  Buffer;

} UNICODE_STRING, * PUNICODE_STRING;

typedef struct _RTL_DRIVE_LETTER_CURDIR {

    USHORT                  Flags;

    USHORT                  Length;

    ULONG                   TimeStamp;

    UNICODE_STRING          DosPath;

} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;

typedef struct _RTL_USER_PROCESS_PARAMETERS {

    ULONG                   MaximumLength;

    ULONG                   Length;

    ULONG                   Flags;

    ULONG                   DebugFlags;

    PVOID                   ConsoleHandle;

    ULONG                   ConsoleFlags;

    HANDLE                  StdInputHandle;

    HANDLE                  StdOutputHandle;

    HANDLE                  StdErrorHandle;

    UNICODE_STRING          CurrentDirectoryPath;

    HANDLE                  CurrentDirectoryHandle;

    UNICODE_STRING          DllPath;

    UNICODE_STRING          ImagePathName;

    UNICODE_STRING          CommandLine;

    PVOID                   Environment;

    ULONG                   StartingPositionLeft;

    ULONG                   StartingPositionTop;

    ULONG                   Width;

    ULONG                   Height;

    ULONG                   CharWidth;

    ULONG                   CharHeight;

    ULONG                   ConsoleTextAttributes;

    ULONG                   WindowFlags;

    ULONG                   ShowWindowFlags;

    UNICODE_STRING          WindowTitle;

    UNICODE_STRING          DesktopName;

    UNICODE_STRING          ShellInfo;

    UNICODE_STRING          RuntimeData;

    RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];

} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB_LDR_DATA {

    ULONG                   Length;

    BOOLEAN                 Initialized;

    PVOID                   SsHandle;

    LIST_ENTRY              InLoadOrderModuleList;

    LIST_ENTRY              InMemoryOrderModuleList;

    LIST_ENTRY              InInitializationOrderModuleList;

} PEB_LDR_DATA, * PPEB_LDR_DATA;

typedef struct _PEB {

    BOOLEAN                 InheritedAddressSpace;

    BOOLEAN                 ReadImageFileExecOptions;

    BOOLEAN                 BeingDebugged;

    BOOLEAN                 Spare;

    HANDLE                  Mutant;

    PVOID                   ImageBaseAddress;

    PPEB_LDR_DATA           LoaderData;

    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;

    PVOID                   SubSystemData;

    PVOID                   ProcessHeap;

    PVOID                   FastPebLock;

    PVOID         FastPebLockRoutine;

    PVOID         FastPebUnlockRoutine;

    ULONG                   EnvironmentUpdateCount;

    PVOID                  KernelCallbackTable;

    PVOID                   EventLogSection;

    PVOID                   EventLog;

    PVOID         FreeList;

    ULONG                   TlsExpansionCounter;

    PVOID                   TlsBitmap;

    ULONG                   TlsBitmapBits[0x2];

    PVOID                   ReadOnlySharedMemoryBase;

    PVOID                   ReadOnlySharedMemoryHeap;

    PVOID                  ReadOnlyStaticServerData;

    PVOID                   AnsiCodePageData;

    PVOID                   OemCodePageData;

    PVOID                   UnicodeCaseTableData;

    ULONG                   NumberOfProcessors;

    ULONG                   NtGlobalFlag;

    BYTE                    Spare2[0x4];

    LARGE_INTEGER           CriticalSectionTimeout;

    ULONG                   HeapSegmentReserve;

    ULONG                   HeapSegmentCommit;

    ULONG                   HeapDeCommitTotalFreeThreshold;

    ULONG                   HeapDeCommitFreeBlockThreshold;

    ULONG                   NumberOfHeaps;

    ULONG                   MaximumNumberOfHeaps;

    PVOID* ProcessHeaps;

    PVOID                   GdiSharedHandleTable;

    PVOID                   ProcessStarterHelper;

    PVOID                   GdiDCAttributeList;

    PVOID                   LoaderLock;

    ULONG                   OSMajorVersion;

    ULONG                   OSMinorVersion;

    ULONG                   OSBuildNumber;

    ULONG                   OSPlatformId;

    ULONG                   ImageSubSystem;

    ULONG                   ImageSubSystemMajorVersion;

    ULONG                   ImageSubSystemMinorVersion;

    ULONG                   GdiHandleBuffer[0x22];

    ULONG                   PostProcessInitRoutine;

    ULONG                   TlsExpansionBitmap;

    BYTE                    TlsExpansionBitmapBits[0x80];

    ULONG                   SessionId;

} PEB, * PPEB;

typedef BOOLEAN(NTAPI* PLDR_INIT_ROUTINE)(

    _In_ PVOID DllHandle,

    _In_ ULONG Reason,

    _In_opt_ PVOID Context

    );

typedef struct _ACTIVATION_CONTEXT* PACTIVATION_CONTEXT;

typedef struct _LDR_SERVICE_TAG_RECORD

{

    struct _LDR_SERVICE_TAG_RECORD* Next;

    ULONG ServiceTag;

} LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD;

typedef struct _LDRP_CSLIST

{

    PSINGLE_LIST_ENTRY Tail;

} LDRP_CSLIST, * PLDRP_CSLIST;

typedef enum _LDR_DDAG_STATE

{

    LdrModulesMerged = -5,

    LdrModulesInitError = -4,

    LdrModulesSnapError = -3,

    LdrModulesUnloaded = -2,

    LdrModulesUnloading = -1,

    LdrModulesPlaceHolder = 0,

    LdrModulesMapping = 1,

    LdrModulesMapped = 2,

    LdrModulesWaitingForDependencies = 3,

    LdrModulesSnapping = 4,

    LdrModulesSnapped = 5,

    LdrModulesCondensed = 6,

    LdrModulesReadyToInit = 7,

    LdrModulesInitializing = 8,

    LdrModulesReadyToRun = 9

} LDR_DDAG_STATE;

typedef struct _LDR_DDAG_NODE

{

    LIST_ENTRY Modules;

    PLDR_SERVICE_TAG_RECORD ServiceTagList;

    ULONG LoadCount;

    ULONG LoadWhileUnloadingCount;

    ULONG LowestLink;

    union

    {

        LDRP_CSLIST Dependencies;

        SINGLE_LIST_ENTRY RemovalLink;

    };

    LDRP_CSLIST IncomingDependencies;

    LDR_DDAG_STATE State;

    SINGLE_LIST_ENTRY CondenseLink;

    ULONG PreorderNumber;

} LDR_DDAG_NODE, * PLDR_DDAG_NODE;

typedef enum _LDR_DLL_LOAD_REASON

{

    LoadReasonStaticDependency,

    LoadReasonStaticForwarderDependency,

    LoadReasonDynamicForwarderDependency,

    LoadReasonDelayloadDependency,

    LoadReasonDynamicLoad,

    LoadReasonAsImageLoad,

    LoadReasonAsDataLoad,

    LoadReasonEnclavePrimary, // since REDSTONE3

    LoadReasonEnclaveDependency,

    LoadReasonPatchImage, // since WIN11

    LoadReasonUnknown = -1

} LDR_DLL_LOAD_REASON, * PLDR_DLL_LOAD_REASON;

typedef struct _LDRP_LOAD_CONTEXT* PLDRP_LOAD_CONTEXT;

typedef struct _RTL_BALANCED_NODE

{

    union

    {

        struct _RTL_BALANCED_NODE* Children[2];

        struct

        {

            struct _RTL_BALANCED_NODE* Left;

            struct _RTL_BALANCED_NODE* Right;

        };

    };

    union

    {

        UCHAR Red : 1;

        UCHAR Balance : 2;

        ULONG_PTR ParentValue;

    };

} RTL_BALANCED_NODE, * PRTL_BALANCED_NODE;

typedef enum _LDR_HOT_PATCH_STATE

{

    LdrHotPatchBaseImage,

    LdrHotPatchNotApplied,

    LdrHotPatchAppliedReverse,

    LdrHotPatchAppliedForward,

    LdrHotPatchFailedToPatch,

    LdrHotPatchStateMax,

} LDR_HOT_PATCH_STATE, * PLDR_HOT_PATCH_STATE;

typedef struct _LDR_DATA_TABLE_ENTRY

{

    LIST_ENTRY InLoadOrderLinks;

    LIST_ENTRY InMemoryOrderLinks;

    LIST_ENTRY InInitializationOrderLinks;

    PVOID DllBase;

    PLDR_INIT_ROUTINE EntryPoint;

    ULONG SizeOfImage;

    UNICODE_STRING FullDllName;

    UNICODE_STRING BaseDllName;

    union

    {

        UCHAR FlagGroup[4];

        ULONG Flags;

        struct

        {

            ULONG PackagedBinary : 1;

            ULONG MarkedForRemoval : 1;

            ULONG ImageDll : 1;

            ULONG LoadNotificationsSent : 1;

            ULONG TelemetryEntryProcessed : 1;

            ULONG ProcessStaticImport : 1;

            ULONG InLegacyLists : 1;

            ULONG InIndexes : 1;

            ULONG ShimDll : 1;

            ULONG InExceptionTable : 1;

            ULONG ReservedFlags1 : 2;

            ULONG LoadInProgress : 1;

            ULONG LoadConfigProcessed : 1;

            ULONG EntryProcessed : 1;

            ULONG ProtectDelayLoad : 1;

            ULONG ReservedFlags3 : 2;

            ULONG DontCallForThreads : 1;

            ULONG ProcessAttachCalled : 1;

            ULONG ProcessAttachFailed : 1;

            ULONG CorDeferredValidate : 1;

            ULONG CorImage : 1;

            ULONG DontRelocate : 1;

            ULONG CorILOnly : 1;

            ULONG ChpeImage : 1;

            ULONG ChpeEmulatorImage : 1;

            ULONG ReservedFlags5 : 1;

            ULONG Redirected : 1;

            ULONG ReservedFlags6 : 2;

            ULONG CompatDatabaseProcessed : 1;

        };

    };

    USHORT ObsoleteLoadCount;

    USHORT TlsIndex;

    LIST_ENTRY HashLinks;

    ULONG TimeDateStamp;

    PACTIVATION_CONTEXT EntryPointActivationContext;

    PVOID Lock; // RtlAcquireSRWLockExclusive

    PLDR_DDAG_NODE DdagNode;

    LIST_ENTRY NodeModuleLink;

    PLDRP_LOAD_CONTEXT LoadContext;

    PVOID ParentDllBase;

    PVOID SwitchBackContext;

    RTL_BALANCED_NODE BaseAddressIndexNode;

    RTL_BALANCED_NODE MappingInfoIndexNode;

    ULONG_PTR OriginalBase;

    LARGE_INTEGER LoadTime;

    ULONG BaseNameHashValue;

    LDR_DLL_LOAD_REASON LoadReason; // since WIN8

    ULONG ImplicitPathOptions;

    ULONG ReferenceCount; // since WIN10

    ULONG DependentLoadFlags;

    UCHAR SigningLevel; // since REDSTONE2

    ULONG CheckSum; // since 22H1

    PVOID ActivePatchImageBase;

    LDR_HOT_PATCH_STATE HotPatchState;

} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

获取PEB

#ifdef _WIN64

    PPEB peb = (PPEB)__readgsqword(0x60);

#endif

#ifdef _X86_

    PPEB peb = (PPEB)__readfsdword(0x30);

#endif

遍历链表 通过匹配dll名称来找到指定的dll

PPEB_LDR_DATA ldrData = peb->LoaderData;

PLIST_ENTRY moduleList = &ldrData->InLoadOrderModuleList;

PLIST_ENTRY current = moduleList->Flink;

while (current != moduleList) {

    PLDR_DATA_TABLE_ENTRY entry = (PLDR_DATA_TABLE_ENTRY)current;

    if (_wcsnicmp(entry->BaseDllName.Buffer, target, wcslen(target)) == 0) {

        return (HMODULE)entry->DllBase;

    }

    current = current->Flink;

}

这里使用_wcsnicmp来忽略大小写

免杀基础-IAT隐藏
通过PEB获取HMODULE实际上是不全的 因为只能获取到进程加载的那些dll中的 可以考虑反射dll注入来获取别的dll
【作者】:Arcueid

【来源】:https://xz.aliyun.com/t/16376

原文始发于微信公众号(船山信安):免杀基础-IAT隐藏

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月28日13:53:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   免杀基础-IAT隐藏https://cn-sec.com/archives/3497559.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息