유니버설 dll 납치 기술

2809 단어
원리는 간단하다. 납치된 dll을 불러오는 것이다. loadlibrary를 통해. 그러나 dll 뒤에peb가 저장한 것은 현재의 dll 핸들을 교체하는 것이다. 호출할 때 이 dll로 호출하는 것이다. 이것은 불가능한 것은 원래의 납치된 것만 있고 모든 기능을 한 번 실현할 수 없다. 방법은loadlibrary가 납치된 핸들을peb에서 네가 방어한 핸들로 바꾸는 것이다.이렇게 하면 호출할 때 원래의 것을 사용하고 당신의 dll는 다른 일을 안심하고 할 수 있다.핵심 코드//dllhijack.cpp
#include "dllhijack.h"
#include 

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _PEB_LDR_DATA
{
    ULONG Length; // +0x00
    BOOLEAN Initialized; // +0x04
    PVOID SsHandle; // +0x08
    LIST_ENTRY InLoadOrderModuleList; // +0x0c
    LIST_ENTRY InMemoryOrderModuleList; // +0x14
    LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA, *PPEB_LDR_DATA; // +0x24

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    WORD LoadCount;
    WORD TlsIndex;
    union
    {
        LIST_ENTRY HashLinks;
        struct
        {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union
    {
        ULONG TimeDateStamp;
        PVOID LoadedImports;
    };
    _ACTIVATION_CONTEXT * EntryPointActivationContext;
    PVOID PatchInformation;
    LIST_ENTRY ForwarderLinks;
    LIST_ENTRY ServiceTagLinks;
    LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

void* NtCurrentPeb()
{
#ifdef _WIN64
    return (void*)__readgsqword(0x30);
#else
    __asm {
        mov eax, fs:[0x30];
    }
#endif
}

PEB_LDR_DATA* NtGetPebLdr(void* peb)
{
#ifdef _WIN64
    return (PEB_LDR_DATA*)(*(ULONGLONG*)((BYTE*)peb + 0x18));
#else
    __asm {
        mov eax, peb;
        mov eax, [eax + 0xc];
    }
#endif
}

/*
dllname:           dll     
OrigDllPath:       dll        
*/
void SuperDllHijack(LPCWSTR dllname, LPWSTR OrigDllPath)
{
    WCHAR wszDllName[100] = { 0 };
    void* peb = NtCurrentPeb();
    PEB_LDR_DATA* ldr = NtGetPebLdr(peb);

    for (LIST_ENTRY* entry = ldr->InLoadOrderModuleList.Blink;
        entry != (LIST_ENTRY*)(&ldr->InLoadOrderModuleList);
        entry = entry->Blink) {
        PLDR_DATA_TABLE_ENTRY data = (PLDR_DATA_TABLE_ENTRY)entry;

        memset(wszDllName, 0, 100 * 2);
        memcpy(wszDllName, data->BaseDllName.Buffer, data->BaseDllName.Length);

        if (!_wcsicmp(wszDllName, dllname)) {
            HMODULE hMod = LoadLibrary(OrigDllPath);
            data->DllBase = hMod;
            break;
        }
    }
}

관련 자료https://anhkgg.com/dllhijack/
전재 대상:https://blog.51cto.com/haidragon/2363010

좋은 웹페이지 즐겨찾기