我正在学习更多关于ctypes
及其函数的知识,我正在尝试创建一个脚本,通过它的PID(process ID)
将WriteProcessMemory
放到记事本中。然而,当我试图执行脚本时,记事本立即崩溃。我遵循this的教程,我认为这与“Gray Hat for Hacking Python”一书是一样的。正确地说,执行的shell代码应该创建一个消息框。你知道吗
这是我的密码。你知道吗
import os
import colorama
from colorama import Fore, Back, Style
import win32com.client
from ctypes import *
from ctypes import wintypes
import ctypes
from ctypes.wintypes import BOOL
from ctypes.wintypes import DWORD
from ctypes.wintypes import HANDLE
from ctypes.wintypes import LPVOID
from ctypes.wintypes import LPCVOID
from ctypes.wintypes import LPCWSTR
colorama.init()
kernel32 = ctypes.WinDLL('Kernel32', use_last_error=True)
LPCSTR = LPCTSTR = ctypes.c_char_p
LPDWORD = PDWORD = ctypes.POINTER(DWORD)
class _SECURITY_ATTRIBUTES(ctypes.Structure):
_fields_ = [('nLength', DWORD),
('lpSecurityDescriptor', LPVOID),
('bInheritHandle', BOOL),]
SECURITY_ATTRIBUTES = _SECURITY_ATTRIBUTES
LPSECURITY_ATTRIBUTES = ctypes.POINTER(_SECURITY_ATTRIBUTES)
LPTHREAD_START_ROUTINE = LPVOID
OpenProcess = kernel32.OpenProcess
OpenProcess.restype = HANDLE
OpenProcess.argtypes = (DWORD, BOOL, DWORD)
VirtualAllocEx = kernel32.VirtualAllocEx
VirtualAllocEx.restype = LPVOID
VirtualAllocEx.argtypes = (HANDLE, LPVOID, ctypes.c_size_t, DWORD, DWORD)
ReadProcessMemory = kernel32.ReadProcessMemory
ReadProcessMemory.restype = BOOL
ReadProcessMemory.argtypes = (HANDLE, LPCVOID, LPVOID, DWORD, DWORD)
WriteProcessMemory = kernel32.WriteProcessMemory
WriteProcessMemory.restype = BOOL
WriteProcessMemory.argtypes = (HANDLE, LPVOID, LPCVOID, DWORD, ctypes.c_int)
CreateRemoteThread = kernel32.CreateRemoteThread
CreateRemoteThread.restype = HANDLE
CreateRemoteThread.argtypes = (HANDLE, LPSECURITY_ATTRIBUTES, ctypes.c_size_t , LPTHREAD_START_ROUTINE, LPVOID, DWORD, ctypes.c_ulong)
GetLastError = kernel32.GetLastError
GetLastError.restype = DWORD
GetLastError.argtypes = ()
GetModuleHandle = kernel32.GetModuleHandleA
GetModuleHandle.restype = HANDLE
GetModuleHandle.argtypes = (LPCWSTR,)
GetProcAddress = kernel32.GetProcAddress
GetProcAddress.restype = LPVOID
GetProcAddress.argtypes = (HANDLE, LPCWSTR)
# https://www.aldeid.com/wiki/Process-Security-and-Access-Rights
PROCESS_VM_READ = 0x0010 # Required to read memory in a process using ReadProcessMemory.
PROCESS_VM_WRITE = 0x0020
PROCESS_VM_OPERATION = 0x0008 # Required to write to memory in a process using WriteProcessMemory.
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_CREATE_THREAD = 0x0002
PROCESS_ALL_ACCESS = (PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD) #0x1F0FFF
print(Fore.RED + 'Retrieving PIDs...')
WMI= win32com.client.GetObject('winmgmts:')
processes = WMI.ExecQuery('SELECT * from win32_process')
print(Fore.GREEN)
process_list = [i.Properties_('ProcessId').Value for i in processes] # list of available processes
for process in processes:
print(process.Properties_('ProcessId').Value , " - " , process.Properties_('Name').Value)
PID = int(input('Enter the PID of the process '))
# https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
process_handle = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, PID) # creating the handle
if not process_handle:
print ("Couldn't acquire a handle to PID: %s" % PID)
shellcode = "C:\\Users\\User\\Desktop\\py\\injector\\hello-world-x64.dll"
# https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex
memory_alloc = kernel32.VirtualAllocEx(process_handle,0, len(shellcode), (0x1000 | 0x2000), 0x40) # allocating memory to the process
write = kernel32.WriteProcessMemory(process_handle, memory_alloc, shellcode, len(shellcode), 0)
ModuleHandle = kernel32.GetModuleHandleA('kernel32.dll')
LoadLibraryA = kernel32.GetProcAddress(ModuleHandle,"LoadLibraryA")
if not kernel32.CreateRemoteThread(process_handle, None, 0, LoadLibraryA, memory_alloc, 0, 0):
print("Failed injection..")
print("ModuleHandle : ", ModuleHandle)
print("LoadLibrary : ", LoadLibraryA)
print("process handle : ", process_handle)
print("VirtualAllocEx : ",memory_alloc)
print("WriteProcessMemory : ",write)
print(ctypes.GetLastError())
我试过打印返回值,很明显给我错误的是ModuleHandle
和LoadLibrary
,返回的是None值。但据微软称:
If the function succeeds, the return value is nonzero. If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError. The function fails if the requested write operation crosses into an area of the process that is inaccessible.
我还尝试了GetLastError()
方法,该方法返回6,在google上,它表示“无效处理程序”。你知道吗
如果有帮助的话,我的操作系统、记事本、VScode(我的ide)、python(3.6.8)都是64位的。 我为混乱的代码道歉,请随时纠正我,因为我在这方面是一个完全的初学者。你知道吗
编辑
这是我打印输出的图像。我也试过LoadLibraryW
和GetModuleHandleW
,但也没用,我的记事本坏了。我使用的dll是一个普通的dll文件,它只会生成一个消息框,说“helloworld”
好吧,我在写这个脚本时犯了很多错误,@eryksun在评论部分给出了很多精彩的答案。我写这个答案是为了巩固我所学到的东西。你知道吗
1)我应该用
kernel32 = ctypes.WinDLL('Kernel32', use_last_error=True)
而不是kernel32 = ctypes.windll.kernel32
。这避免了与使用windll
的其他模块的冲突。它还可以保护线程的LastErrorValue
。在这种情况下,请使用ctypes.get_last_error()
和ctypes.set_last_error(err)
,而不是直接调用WinAPIGetLastError
和SetLastError
。你知道吗2)
WriteProcessMemory.argtypes = (HANDLE, LPVOID, LPCVOID, DWORD, ctypes.c_int)
设置错误。argtype根据文档,应该是:其中最后两个参数应该是
[HANDLE, LPVOID, LPCVOID, SIZE_T, PSIZE_T]
。你知道吗3)
PROCESS_ALL_ACCESS
只应获得CreateRemoteThread
和WriteProcessMemory
所需的必要权利,这些权利是PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION
。你知道吗4)与其将我传递的字节大小分配为
len(shellcode)
,不如将其分配为(len(shellcode) + 1) * WCHAR_SIZE
。你知道吗5)
GetModuleHandleA
和LoadLibraryA
应替换为各自的W函数。此外,GetModuleHandleW
和GetProcAddress
步骤是不必要的。ctypes已经帮你做了。只需使用kernel32.LoadLibraryW。这取决于kernel32.dll在每个进程中总是映射到相同的基址,我认为对于现有版本的Windows也是如此。你知道吗感谢@eryksun的帮助!你知道吗
相关问题 更多 >
编程相关推荐