
IKEv2, ikeext.dll, CVE-2026-33824, double free, heap grooming, ROP, SKF fragmentation, Windows exploit, anti-debug, obfuscation, API hooking, shellcode, reverse shell
⚠️ 프로젝트가 마무리 중입니다. 현재 상태에서는 완전히 작동하지 않습니다.
EpSiLoNPoInTIkEv2.cpp는 Windows를 대상으로 하는 C/C++ 익스플로잇 프로토타입으로, ikeext.dll (Windows IKEv2 드라이버) 내의 double-free 유형 익스플로잇을 중심으로 개발되었으며, 연구 중 CVE-2026-33824로 참조됩니다.
이 프로젝트는 다음을 포함합니다:
EpSi_OBF_ENDL / 영감을 받은 obfusheader)코드는 컴파일 타임에 #define EpSi_OBF_ENDL을 통해 활성화되는 강력한 난독화 계층을 사용합니다.
obfusheader.h를 기반으로 하여, 적용 및 확장되었습니다.
FAKE_SIGNS == 1)알려진 프로텍터 스캐너를 속이기 위해 사용자 정의 PE 섹션이 바이너리에 삽입됩니다:
.vmp0, .vmp1, .vmp2 → VMProtectUPX0 → UPX.enigma1, .enigma2 → Enigma Protector.winlice → Themida.petite, .aspack, .adata, .rlp, .vlizer, .arch, .alien, .pwdprot,
.dsstext, , , , , , (Nuitka), (Screen2Exe) 등.VIRT == 1)모든 산술 및 논리 연산은 내부 VM(Obfh_VirtualMachine)으로 라우팅될 수 있습니다:
OP__ADD, OP__SUB, ..., OP__NOP)는 __COUNTER__ 및 RND()를 통해 컴파일 타임에 무작위로 생성됩니다._VM_ENCRYPT_INT(value) = (value - _VM_MUTATOR_KEY) * ~SALT_CMD.* -1)되며, 정크 값과 함께 전달됩니다.goto, 가짜 음수 case, BREAK_STACK_* (인라인 ASM xor; jz; .byte 0xE8; cpuid), 가짜 JMP (.byte 0xFF, 0x25) 및 디컴파일러를 속이기 위한 가짜 x86_64 코드 블록으로 가득 차 있습니다.VM_ADD, VM_SUB, , , , , ,
, , , , , , 등.NO_CFLOW != 1)#define if(cond) : 각 if는 __s_rdtsc() 호출과 죽은 BAD_CALL을 삽입합니다.#define else : 실제 else 전에 죽은 else if (0) { BAD_CALL; }를 삽입합니다.#define while(...) : __s_rdtsc() != 0.1과 터무니없는 포인터 검사로 조건화됩니다.#define for(...) : OBFUS_CONDITION_BLOCK으로 조건화됩니다.#define switch(...) : OBFUS_CONDITION_BLOCK으로 조건화됩니다.#define break : 각 전에 을 삽입합니다.HIDE_STRING)STACK_STRING(str) : 복합 리터럴을 통해 문자열을 스택에 푸시합니다.HIDE_STRING(str) : obfh_process_hidden_string() + __s_rdtsc()를 죽은 BAD_JMP와 결합하여 바이너리 내 문자열을 숨깁니다.모든 CRT 및 Win32 함수는 리디렉션됩니다:
GetProcAddress(LoadLibraryA("msvcrt"), ...) 동적: printf, scanf,
sprintf, strlen, strcmp, strcpy, strtok, memset, memcpy, strchr, strrchr,
rand, realloc, calloc, fopen, , , , , ,
, , , , , , , , .ANTI_DEBUG_V2 == 1)ThreadCompareDRs): 메인 스레드에 SuspendThread, CONTEXT_DEBUG_REGISTERS로 GetThreadContext, Dr0–Dr3, Dr7 확인, ad_ZeroDRs로 제로화.IsDebuggerPresent_proxy: kernel32.dll을 동적으로 로드하고, 휘발성 변수(_I, _s, _D, _e, _b, _u, _g, _g, _e, _r, _P, _r, _e, _s, _e, _n, _t)를 통해 함수 이름 IsDebuggerPresent를 문자별로 재구성, GetProcAddress를 통해 호출.ANTI_DEBUG: 이중 검사 , (무한 루프) 트리거, (권한이 있는 IN 명령어), , ASM, 그 다음 ( + ).민감한 함수에 삽입된 9가지 변형의 인라인 ASM 시퀀스:
xor; jz; .byte 0xE8; cpuid (eax, ebx, edx 변형), 가짜 명령어 0x50, 0x20,
0x00, 0xEB, 0xE1 (x86), 0xFF, 0x25, 0xF1, 0xF2, 0xF3, 0xF4 (x86_64).
#include "runassys/ntnative.h"
#include "runassys/runassys.h"
#include "runassys/ntdll-stubs/ntdll-stubs.c"
#include "runassys/ntdll-stubs/ntdll.def.c"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "bcrypt.lib")
#pragma comment(lib, "Version.lib")
IKEEXT_BASE_ADDRESS = 0x180000000g_IkeextDoubleFreeOffset = 0x12B960g_IkeextProcessIkePayload = 0x522200x1790A0), 가져오기 (0x179110), 예외 (0x183000),
재배치 (0x18C000), 로드 구성 (0x12AE70), 디버그 (0x155CD0).g_Offset_MMSA_SecurityRealmBlob = 0x208,
g_Offset_PacketContext_Blob = 0xC8.500 (UDP), 셸 콜백: 4444.IKE_HEADER, IKE_SA_PAYLOAD, IKE_PROPOSAL_PAYLOAD, IKE_TRANSFORM_PAYLOAD,
IKE_NONCE_PAYLOAD (32바이트 난스), IKE_KEY_EXCHANGE_PAYLOAD (DH 256바이트),
IKE_NOTIFY_PAYLOAD, IKE_VENDOR_ID_PAYLOAD, IKE_SKF_FRAGMENT_PAYLOAD.
구성된 변환: AES-CBC-128 (12), PRF HMAC-SHA2-256 (5),
INTEG HMAC-SHA2-256-128 (12), DH MODP-2048 (14).
IKE_DDOS_AMPLIFIER_PAYLOAD : 증폭 계수 + 64바이트 트리거.IKE_DDOS_LOOP_PAYLOAD : 루프 카운터 + 32바이트 loop_code.IKE_DDOS_MEMORY_PAYLOAD : 크기/개수 할당 + 64바이트 힙 스프레이 데이터.HEAP_GROOM_CONTEXT : 힙 핸들, 대상 주소, 스레드, stop_flag, allocated_chunks.HEAP_GROOM_THREAD_PARAMS : 청크 크기, 반복 횟수, thread_id, SRWLOCK, use_nt_allocate.GROOM_CONFIG : 스레드 수, 반복 횟수, 지연 시간, 청크 크기, 최소/최대 여유 %.0x1000 크기의 청크, 1000회 반복, 30–70% 사이의 단편화.모든 필요한 가젯을 포함한 완전한 ROP_CHAIN 구조체:
pop_rax/rcx/rdx/r8/r9/rsp, mov_rax_rsp, mov_rcx_rsp, mov_rcx_rax, mov_rax_rcx,
mov_rcx_rdx, xor_rax/rcx/rdx, jmp_rsp, call_rax, ret, virtual_protect,
disable_cfg, disable_cet, add_rsp, , .
512개 가젯 배열 ().
g_rop_patterns[] 테이블: 모듈 내에서 가젯을 찾기 위한 ~50개 이상의 바이트 서명 패턴:
pop rax; ret, pop rcx; ret, pop rdx; ret, ..., mov [rcx], rax; ret,
mov rax, [rcx]; ret, jmp rsp, VirtualProtect prologue,
mov [gs:0x60], rax; ret, jmp [rax+0x58]; ret, lea rax, [rip+0x0]; jmp rax,
add rsp, 0x28; ret, cmp rdx/r8/r9, 0x0; je/jne; ret 등.
uint64_t g_KernelBase, g_IkeextBase, g_SystemEprocess;
uint64_t g_IkeextDoubleFreeOffset = 0x12B960;
uint64_t g_IkeextProcessIkePayload = 0x52220;
uint64_t g_PopRax, g_PopRcx, g_PopRdx, g_PopR8, g_PopR9, g_PopRsp;
uint64_t g_MovRaxRsp, g_JmpRsp, g_VirtualProtect, g_DisableCFG, g_StackPivot;
uint64_t g_NtoskrnlBase, g_Kernel32Base, g_NtdllBase, g_HeapBase, g_ShellcodeAddr;
SOCKET g_Socket; struct sockaddr_in g_Target;
EXPLOIT_CONTEXT g_ExploitCtx; ROP_CHAIN g_RopChain;
HEAP_GROOM_CONTEXT g_GroomContext;
MODULE_DATA g_Modules; ROP_GADGET g_Gadgets;
std::vector<SUSPICIOUS_REGION> g_Regions;
main)InitializeCriticalSection, init_debug_info.is_hostile_environment() → 샌드박스/VM 감지 시 종료.disable_amsi(), disable_defender(), disable_etw(), patch_etw().start_shell_listener() → 리버스 셸 리스너 포트 4444 시작.argv[1] (대상 IP) + argv[2] (포트, 기본값 500) 파싱.init_udp_socket() + inet_pton + test_target_reachability().SKF_FRAGMENTS + 1 패킷).프로젝트는 마무리 중이며 완전히 작동하지 않습니다.
disable_amsi, disable_defender, disable_etw,
patch_etw, is_hostile_environment, test_target_reachability, start_shell_listener,
stop_shell_listener, print_usage, init_debug_info)은 선언되었지만 빌드 상태에 따라 불완전하거나 누락될 수 있습니다.runassys/ 의존성 및 링크된 라이브러리 조정 없이 컴파일되지 않을 수 있습니다.이 저장소는 Windows의 저수준 네트워크 익스플로잇 벡터(IKEv2/ikeext.dll)를 대상으로 하는 공격적 연구 프로토타입을 포함합니다.
이 코드의 사용은 명시적 허가를 받은 테스트, 연구 또는 실험실 환경으로 엄격히 제한됩니다.
저자는 이 코드의 불법적, 무단 또는 유해한 사용에 대해 어떠한 책임도 지지 않습니다. 코드는 작동, 안정성 또는 바람직하지 않은 효과의 부재에 대한 보증 없이 있는 그대로 제공됩니다.
프로젝트는 아직 마무리 중이며 현재 상태에서는 완전히 작동하지 않습니다.
logicoma__wibu00__wibu01PETETRIS.tw.rdata.text0x45,0x6e,0x69,...), Denuvo(0x64,0x65,0x6E,...)를 모방한 인코딩된 문자열.FAKE_DONGLE[] 배열: skeydrv.dll, HASPDOSDRV,
MARXDEV1.SYS, WIBUKEY, SNTNLUSB, RNBOspro 등.VM_MULVM_DIVVM_MODVM_EQUVM_NEQVM_LSSVM_GTRVM_LEQVM_GEQVM_OBF_INTVM_ADD_DBLVM_MUL_DBLbreakif (OBFUS_CONDITION_BLOCK) BREAK_STACK_1fclosefreadfwriteexitsnprintfvsprintfvsnprintfgetenvsystemabortatexitgetcwdtolowertoupperobfh_int_proxy() 래퍼: CreateFile,
ReadFile, WriteFile, CloseHandle, VirtualAlloc, VirtualFree, CreateThread,
WaitForSingleObject, WaitForMultipleObjects, ExitProcess, GetModuleHandle,
GetModuleFileName, HeapCreate, HeapAlloc, HeapFree, GlobalAlloc, GlobalFree,
GetTempPath, SetEvent, ResetEvent, Sleep, memmove, GetParent, GetWindowRect,
GetClientRect, SetWindowPos, SetConsoleTextAttribute, GetDesktopWindow, GetStockObject.GetProcAddress가 GetProcAddress_custom으로 대체됨: 수동으로 IMAGE_EXPORT_DIRECTORY 탐색
(PE 파싱: e_lfanew, IMAGE_NT_HEADERS, IMAGE_DIRECTORY_ENTRY_EXPORT, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals).LoadLibraryA는 6개의 중첩 래퍼(LoadLibraryA_0 ~ LoadLibraryA_proxy)로 난독화되며,
휘발성 변수 _k, _e, _r, _n, _e, _l 및 sprintf를 통해 DLL 이름을 문자별로 재구성합니다.IsDebuggerPresent() || IsDebuggerPresent_proxy()loop().byte 0xEDBREAK_STACK_1retcrash()int $3.byte 0xED, 0x00sub_rspstack_pivotrop_chain[MAX_ROP_CHAIN_SIZE]