В противном случае DLL инъекций - PullRequest
2 голосов
/ 28 января 2011

Я нахожусь в процессе создания программы безопасности для моей сети.Одним из примеров является проверка и мониторинг того, как называются API и библиотеки.DLL, чтобы сделать это, и программа, которая сопровождает это, уже закончены.Но есть проблема, которую я не могу исправить.

При попытке внедрить мою dll в системные процессы (такие как explorer.exe, мой основной процесс тестирования системы) с помощью NtCreateThreadEx я получаю возвращаемое значение:C0000022, это означает что-то вроде: Status_Access_Denied (возвращается в NTSTATUS, но DWORD сделает)правильные функции, все еще я получаю c0000022

Вот код, который я использую для ввода

#include "main.h"

typedef DWORD NTSTATUS;

struct NtCreateThreadExBuffer{
    ULONG Size;
    ULONG Unknown1;
    ULONG Unknown2;
    PULONG Unknown3;
    ULONG Unknown4;
    ULONG Unknown5;
    ULONG Unknown6;
    PULONG Unknown7;
    ULONG Unknown8;
};


typedef NTSTATUS (WINAPI *LPFUN_NtCreateThreadEx)
(
 OUT PHANDLE hThread,
 IN ACCESS_MASK DesiredAccess,
 IN LPVOID ObjectAttributes,
 IN HANDLE ProcessHandle,
 IN LPTHREAD_START_ROUTINE lpStartAddress,
 IN LPVOID lpParameter,
 IN BOOL CreateSuspended,
 IN ULONG StackZeroBits,
 IN ULONG SizeOfStackCommit,
 IN ULONG SizeOfStackReserve,
 OUT LPVOID lpBytesBuffer
);

using namespace std;

//#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
#define CREATE_THREAD_ACCESS ( PROCESS_ALL_ACCESS )

BOOL LoadDll(char *procName, char *dllName);
BOOL InjectDLL(DWORD dwProcessID, char *dllName);

BOOL LoadDll(char *dllName, DWORD dwProcID){

    printf("Process Id to Inject: %d",dwProcID);

    if(!dwProcID){
        printf("No vailid PID\n");
        return false;
    }

    FILE* FileCheck = fopen(dllName, "r");

    if(FileCheck==NULL){
        printf("\nUnable to inject %s", dllName);
        return false;
    }

    fclose(FileCheck);


    if(!InjectDLL(dwProcID, dllName)){

        printf("injection failed\n");
        return false;
    } else {
        return true;
    }

}

BOOL InjectDLL(DWORD dwProcessID, char *dllName){

    HANDLE hProc;
    HANDLE hToken;
    char buf[50]={0};
    LPVOID RemoteString, LoadLibAddy;

    if(!dwProcessID)return false;


    HANDLE hCurrentProc = GetCurrentProcess();

    if (!OpenProcessToken(hCurrentProc,TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken)){

        printf("OpenProcessToken Error:%d\n", GetLastError());


    } else {

        if (!RaisePrivleges(hToken, (char*)SE_DEBUG_NAME)){

            printf("SetPrivleges SE_DEBUG_NAME Error:%d\n", GetLastError());

        }

    }


    if (hToken)CloseHandle(hToken);

    hProc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, dwProcessID);

    printf("\nHandle to process: %x\n", hProc);

    if(!hProc){

        printf("OpenProcess() failed: %d", GetLastError());
        return false;

    }

    LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");


    if(!LoadLibAddy){

        printf("GetProcAddress() failed: %d", GetLastError());
        return false;

    }

    RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllName), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

    if(RemoteString == NULL){

        printf("VirtualAllocEx() failed: %d", GetLastError());
        return false;

    }


    printf("\nRemote address: %x\n", RemoteString);

    if(WriteProcessMemory(hProc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL) == NULL){

        printf("WriteProcessMemory() failed: %d", GetLastError());
        return false;

    }

/*
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){

  printf("CreateRemoteThread() failed: %d", GetLastError());
     return false;

}
*/

    HMODULE modNtDll = GetModuleHandle("ntdll.dll");


    if( !modNtDll )
    {
        printf("n failed to get module handle for ntdll.dll, Error=0x%.8x", GetLastError());
        return 0;
    }

    LPFUN_NtCreateThreadEx funNtCreateThreadEx =
                                                (LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx");


    if( !funNtCreateThreadEx )
    {
        printf("n failed to get function (NTCreateThreadEx) address from ntdll.dll, Error=0x%.8x\nTrying CreateRemoteThread api\n", GetLastError());

        if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){

            printf("CreateRemoteThread() failed: %d", GetLastError());
            return false;

        } else {
            printf("CreateRemoteThread success!\n");
            return true;
        }


        return 0;
    }


    NtCreateThreadExBuffer ntbuffer;

    memset (&ntbuffer,0,sizeof(NtCreateThreadExBuffer));
    DWORD temp1 = 0;
    DWORD temp2 = 0;
    HANDLE pRemoteThread = NULL;

    ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
    ntbuffer.Unknown1 = 0x10003;
    ntbuffer.Unknown2 = 0x8;
    ntbuffer.Unknown3 = &temp2;
    ntbuffer.Unknown4 = 0;
    ntbuffer.Unknown5 = 0x10004;
    ntbuffer.Unknown6 = 4;
    ntbuffer.Unknown7 = &temp1;
    ntbuffer.Unknown8 = 0;

    NTSTATUS status = funNtCreateThreadEx(
                                          &pRemoteThread,
                                          0x1FFFFF,
                                          NULL,
                                          hProc,
                                          (LPTHREAD_START_ROUTINE) LoadLibAddy,
                                          (LPVOID)RemoteString,
                                          FALSE, //start instantly
                                          NULL,
                                          NULL,
                                          NULL,
                                          &ntbuffer
                                         );

    printf("NTCreateThreadEx return: %x\n", status);

    // Resume the thread execution

    WaitForSingleObject(pRemoteThread, INFINITE);


    //Check the return code from remote thread function
    DWORD dwExitCode;
    if( GetExitCodeThread(pRemoteThread, (DWORD*) &dwExitCode) )
    {
        printf("\n Remote thread returned with status = %d\n", dwExitCode);
    }


    CloseHandle(pRemoteThread); 


    CloseHandle(hProc);
    return true;

}


BOOL RaisePrivleges( HANDLE hToken, char *pPriv ){

    TOKEN_PRIVILEGES tkp;
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    tkp.Privileges[0].Luid.HighPart = 0;
    tkp.Privileges[0].Luid.LowPart = 0;

    if (!LookupPrivilegeValue(NULL, pPriv, &tkp.Privileges[0].Luid)){

        printf("LookupPrivilegeValue Error:%d\n", GetLastError());
        return FALSE;

    }

    int iRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL, 0);

    if (iRet == NULL){

        printf( "AdjustTokenPrivileges Error:%d\n", GetLastError());
        return TRUE;

    } else {

        iRet = GetLastError();

        switch (iRet){

            case ERROR_NOT_ALL_ASSIGNED:
                printf("AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED\n" );
                return FALSE;

            case ERROR_SUCCESS:
                return TRUE;

            default:
                printf("AdjustTokenPrivileges Unknow Error:%d\n", iRet);
                return FALSE;
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 11 декабря 2015

Поскольку трудно найти правильный ответ на эту проблему, я пишу, хотя ветка старая.Я пытался внедрить в службу x64 на Win7 x64 и продолжал сталкиваться с теми же проблемами.Мое решение было:

  1. Скомпилируйте инжектор и DLL впрыска как x64.
  2. Вместо CreateRemoteThread и NtCreateThreadEx (оба сбоя) используйте RtlCreateUserThread.
2 голосов
/ 28 января 2011

1) Если вы работаете в VISTA или более поздней версии, возможно, вы пытаетесь внедрить в «защищенный процесс» из «незащищенного процесса». См. Безопасность процессов и права доступа в MSDN. Незащищенные процессы не могут создавать потоки в защищенных процессах; хотя я должен признать, что ожидал, что вызов, чтобы открыть процесс, потерпит неудачу, когда вы запросите несоответствующие права доступа, а не последующий вызов создания потока потерпит неудачу.

2) Почему вы используете NtCreateThreadEx() вместо простого вызова CreateRemoteThread()?

3) Вероятно, это не является причиной вашей проблемы, но ... Вы не можете выделить память для нулевого терминатора в строке, вам следует выделить strlen(dllName) + 1.

4) Я предполагаю, что процесс, который выполняет инъекцию, и процесс, в который вы внедряете, являются одной и той же архитектурой, вы не запускаете x86 exe на x64 и ожидаете внедрения в x64 exe? 1012 *

...