Почему внедрение пещер кода с внедрением потоков приводит к сбою моей целевой win32 EXE? - PullRequest
0 голосов
/ 03 марта 2019

В настоящее время я пытаюсь внедрить кодовую пещеру с инжекцией потока в удаленный win32 EXE-файл, работающий в моей системе win7 (x64).Чтобы добиться этого, я использую Microsoft VB6, с помощью которой я делаю следующее:

  • OpenProcess, чтобы получить дескриптор удаленного процесса [OK]
  • VirtualAllocEx, чтобы выделить некоторыепространство внутри процесса (с защитой PAGE_EXECUTE и MEM_COMMIT в качестве параметра. lpAddress установлен в NULL, чтобы функция определяла, где выделить область) [OK, возвращает действительное смещение]
  • WriteProcessMemory, чтобы написать мой шелл-код [OKфактически записывает байты правильно, я проверил с помощью CheatEngine / MemoryView]
  • CreateRemoteThread, внедрение потока для выполнения моей пещеры кода [OK, возвращает дескриптор, который не равен NULL, мой удаленный поток был, предположительно, успешно создан]
  • Мой целевой EXE (хост для только что созданного удаленного потока) в этот момент падает (exename перестал работать)
  • WaitForSingleObject / CloseHandle / VirtualFreeEx

Ради тестирования успешного внедрения кода я пытаюсь внедрить какадский код, который ничего не делает.Я не знаю много о шелл-кодировании и asm, но я только начал изучать.

Я пробовал вводить разные коды, например: - только NOP (вылетает, но я предполагаю, что это нормально): \ x90 \x90 \ x90 .. - только NULL (то же, что и выше): \ x00 \ x00 \ x00 .. Однако я не понимаю, что NOP, за которыми следует RETN, приводит к аварийному завершению работы моего целевого EXE-файла, а также \ x90 \ x90 \ x90 \ xCB.За каждой последовательностью байтов, которую я пробовал вводить, следовал нулевой байт.

Почему происходит сбой целевого процесса?Какую последовательность байтов мне нужно внедрить, чтобы выполнить успешную инъекцию, которая не приводит к сбою моего целевого EXE-файла (но ничего не делает, только для проверки схемы инъекции)?

ЧтоЯ хочу закончить тем, что ввел в игру целевую функцию PUSH x, CALL.Но если мой фиктивный шеллкод не работает с моим целевым процессом, я предполагаю, что последняя последовательность байтов тоже будет.Спасибо за ваше время.

РЕДАКТИРОВАТЬ: Исключение, которое я получаю 0xC0000005 [Нарушение доступа при записи]

Код VB6: Просто вызовите подпрограмму с pid целевого Exe в качестве аргумента

Private Const PAGE_READWRITE As Long = &H4
Private Const PAGE_EXECUTE As Long = &H10

Private Const MEM_RELEASE As Long = &H8000
Private Const MEM_COMMIT As Long = &H1000
Private Const INFINITE As Long = &HFFFFFF

Public Const PROCESS_ALL_ACCESS As Long = &H1F0FFF

Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CreateRemoteThread Lib "kernel32" (ByVal hProcess As Long, lpThreadAttributes As Long, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long

'Function that performs the shellcode injection to a remote process. Takes the target's PID as argument
Public Sub injectCode(ByVal lngPid As Long)
    Dim RemThread As Long, LngModule As Long, LngProcess As Long
    Dim i As Long

    'The byte sequence we'll inject in the remote process (
    Dim shellcode(4) As Byte
    shellcode(0) = &H90 'NOP : just to pretend that it's actual code
    shellcode(1) = &H90 'NOP : same
    shellcode(2) = &HC2 'Near return to calling procedure and pop 4 bytes from stack.
    shellcode(3) = &H4
    shellcode(4) = 0    'NULL terminator

    'OpenProcess, to get a handle to the remote process
    LngProcess = OpenProcess(PROCESS_ALL_ACCESS, False, lngPid)
    'to allocate some space inside of process (with PAGE_EXECUTE protection and MEM_COMMIT as parameter.
    'lpAddress set to NULL so that the function determines where to allocate the region)
    LngModule = VirtualAllocEx(LngProcess, 0, UBound(shellcode), MEM_COMMIT, PAGE_EXECUTE)

    Debug.Print "VirtualAllocEx: " & Hex(LngModule) 'debug info

    'writing our shellcode to the target's memory
    For i = 0 To UBound(shellcode)
        Call WriteProcessMemory(LngProcess, LngModule + i, shellcode(i), 1, 0&)
    Next i
    'thread injection to execute my code cave
    RemThread = CreateRemoteThread(LngProcess, 0&, 0&, ByVal LngModule, 0&, 0&, ByVal 0&)

    Debug.Print "CreateRemoteThread: " & Hex(RemThread) 'debug info

    'wait for the thread to run
    Call WaitForSingleObject(RemThread, INFINITE)
    CloseHandle (RemThread)
    Call VirtualFreeEx(LngProcess, LngModule, UBound(shellcode), MEM_RELEASE)

    Debug.Print "DONE" 'debug info
End Sub

Хотя происходит нечто странное.Когда я помещаю MsgBox (который приостанавливает выполнение) для целей отладки ПЕРЕД вызовом CreateRemoteThread, функция возвращает ненулевой дескриптор (но целевой EXE-файл вылетает).И если я не помещу Msgbox перед вызовом CreateRemoteThread, возвращается дескриптор NULL.

1 Ответ

0 голосов
/ 03 марта 2019

ThreadProc обратный вызов, переданный CreateRemoteThread, принимает один параметр LPVOID, а ThreadProc равен __stdcall.

LPVOID параметр для ThreadProc пересылается из CreateRemoteThread s LPVOID lpParameter.

На x86 это означает, что вам нужно поместить инструкцию RET так, чтобы освободить четыре байтаиз стека.

(Также ThreadProc возвращает DWORD, это означает, что вы должны возвращать значение EAX перед возвратом, но если вас не волнует возвращаемое значение, вы можете его пропустить)

Кроме того, CB - дальний возврат, вам нужно использовать близкий возврат.

Ищите код операции RETN imm , похоже, вам нужно C2 04 00

...