
Windows 메모리 포렌식 및 위협 헌팅 도구로, 실행 중인 프로세스 메모리를 스캔하여 악성 패턴, 인젝션 기법, 반사적으로 로드된 .NET 어셈블리를 탐지하며, 다층 신뢰도 모델을 사용하여 오탐(false positive)을 줄입니다.

version : 0.9 (안정 버전)
Aether는 라이브 프로세스 메모리에서 악성 패턴을 스캔하고, 인젝션 기법, 임플란트 시그니처, 리플렉티브 로드된 .NET 어셈블리를 탐지하는 Windows 메모리 포렌식 및 위협 헌팅 도구입니다. 다중 계층 신뢰도 모델(multi-layer confidence model)을 사용하여 오탐(false positive)률을 크게 줄이고 악성 행위를 탐지합니다. Aether는 할로잉(Hollowing), APC, 스레드 하이재킹 기법 탐지에 뛰어난 역량을 갖추고 있습니다. 보안 분석가는 이 도구를 사용하여 의심스러운 영역을 스캔·헌팅하고, 오프라인 분석을 위해 스냅샷을 캡처할 수 있습니다.
문서: https://0xsp.com/docs/aether-getting-started/
연구 문서:
Aether 핵심 기능에 대한 간략한 설명입니다. 더 자세한 내용은 전체 기술 블로그 포스트를 참조하세요:
"msxsl:script"가 6D 00 73 00 78 00 ...로 저장되는 경우)rules/에 새 시그니처 추가MEM_PRIVATE 영역의 PE 헤더 탐지 — 리플렉티브 로드된 .NET 어셈블리 플래그 지정
(MZ + PE + BSJB 메타데이터)Aether는 원시 작업 집합(working-set) 신호 위에 다섯 개의 필터를 계층화하여, 하나의 탐지 결과가 보고되기 전에 여러 지표가 일치해야 하도록 FP 필터링을 적용합니다:
| 레이어 | 필터 | 목적 |
|---|---|---|
| L1 | 구조적 | 실행 가능한 IMAGE 하위 영역만 고려 (.data / .rdata COW 노이즈 제거) |
| L2 | 정량적 | private_pages 수와 private_ratio로 등급 부여 (낮음 / 중간 / 높음) |
| L3 | 교차 검증 | 독립적인 신호가 동일한 할당 베이스에서 일치하는 경우에만 승격 — 시그니처 히트, missing_peb_entry, private_rwx, 훅 프롤로그 또는 온디스크 diff |
| L4 | CLR 인지 | CLR이 로드될 때 전체를 건너뛰는 대신 ngen / R2R / 계층형 JIT 대상(*.ni.dll, mscor*, clr*, coreclr, system.private.corelib*)에 대해 모듈별 억제 |
| L5 | 온디스크 diff | CreateFileMappingW(SEC_IMAGE_NO_EXECUTE)로 모듈 파일을 매핑하고, 각 프라이빗 실행 페이지의 처음 16바이트를 디스크의 동일한 RVA와 비교. 차이가 있으면 실제 수정 IOC |
기타 구조적 검사:
MEM_IMAGE 할당
(DLL 할로잉 / 모듈 스톰핑)K32QueryWorkingSetEx를 통한 수정된 코드 페이지 탐지.
4KB 페이지마다가 아니라 영역마다 한 번의 syscall로 일괄 처리
(단순 루프보다 약 50~100배 빠름)MEM_PRIVATE + PAGE_EXECUTE_*
할당을 플래그 처리 (셸코드, JIT 스프레이, 동적 코드 스텁 할당)E9 ?? ?? ?? ?? — JMP rel32FF 25 ?? ?? ?? ?? — JMP [rip+disp32]68 ?? ?? ?? ?? C3 — PUSH imm32 ; RET48 B8 ?? ?? ?? ?? ?? ?? ?? ?? FF E0 — MOV RAX, imm64 ; JMP RAX49 BB ?? ?? ?? ?? ?? ?? ?? ?? 41 FF E3 — Detours 스타일
MOV R11, imm64 ; JMP R11Cor_Private_IPCBlock_v4_<PID> 및 v2 Cor_Private_IPCBlock_<PID>
(레거시 .NET 2/3 / mscorwks)에 대한 섹션 객체 프로브.
이를 통해 이전 런타임을 실행하는 노이즈가 많은 앱 풀이 잘못 분류되지 않습니다.Aether는 더 엄격한 분류와 L1~L5 탐지 결과와의 교차 상관 관계로 스레드를 검사합니다.
대상 프로세스의 모든 생성된 스레드에 대해 Aether는 NtQueryInformationThread를 통해
Win32StartAddress를 읽고, 접근이 허용되면 GetThreadContext / Wow64GetThreadContext를
통해 라이브 Rip / Eip도 읽습니다.
그런 다음 각 주소는 아래 표와 같이 등급이 매겨집니다. 자세한 내용은 블로그 포스트를 참조하세요:
| 판정 | 심각도 | 조건 |
|---|---|---|
TSAV_SHELLCODE_PRIVATE | CRITICAL | 주소가 MEM_PRIVATE + PAGE_EXECUTE_* 영역에 있음 — 전형적인 CreateRemoteThread 셸코드 |
TSAV_SUSPENDED_RIP | CRITICAL | 일시 중단된 스레드의 Rip이 Win32StartAddress와 일치하지 않고 의심스러운 영역으로 확인됨 — Win32StartAddress 스푸핑(EarlyBird / APC 트릭) 및 SetThreadContext 하이재킹 탐지 |
TSAV_HOLLOWED_HOST | HIGH | PEB 모듈 목록에 없는 MEM_IMAGE 할당 내부의 주소 (DLL 할로잉 / 모듈 스톰핑) |
TSAV_MODIFIED_HOST | HIGH | L1~L5 파이프라인이 이미 MODIFIED_CODE_*, MISSING_PEB, PRIVATE_RWX, DISK_MEM_DIFF 또는 HOOK_PROLOGUE로 플래그한 MEM_IMAGE 할당 내부의 주소 |
TSAV_STAGED_PRIVATE_RW | HIGH | MEM_PRIVATE + PAGE_READWRITE — VirtualProtect 호출 전 셸코드 스테이징 |
TSAV_MAPPED_NONPE | MEDIUM | PE 헤더가 없는 MEM_MAPPED(페이지 파일 백업 섹션) — sRDI / 페이지 파일 리플렉티브 로더 |
TSAV_SPOOF_TRAMPOLINE | MEDIUM | 주소가 차단 목록의 트램펄린(LoadLibraryA/W/ExA/W, WinExec, CreateProcessA/W, VirtualAlloc[Ex], RtlExitUserThread, RtlExitUserProcess, NtTerminateProcess, ShellExecuteA/W)과 일치 |
이 방식이 "start_address가 어떤 모듈에 있는지"만 확인하는 기본 검사보다 강력한 이유:
VirtualQueryEx 교차 검사 — 모든 주소는 모듈 목록에 대한 선형 스캔 대신
단일 O(1) 호출로 Type / Protect / AllocationBase를 조회TSAV_MODIFIED_HOST로 승격Win32StartAddress는 NtSetInformationThread를 통해
프로세스에서 쓸 수 있으며 스푸핑 가능한 필드입니다. 일시 중단된 스레드의 라이브 Rip은
로더가 쉽게 다시 쓸 수 없는 값입니다. 둘을 비교하여 의심스러운 영역으로 확인되는
불일치를 플래그합니다.Wow64GetThreadContext로 전환하여 Eip를 읽음QUERY_INFORMATION | GET_CONTEXT →
QUERY_INFORMATION → QUERY_LIMITED_INFORMATION 순으로 폴백하므로
부분 접근 시나리오에서도 유용한 분류를 생성런타임 API 해석(resolution)은 악성코드가 자주 사용하는 기법입니다. Aether 탐지 메커니즘은 힙에서 유효한 모듈 주소와 포인터를 스캔하고, 그 결과를 아래 설명된 필터링 기준과 연관지어 이 동작을 식별합니다:
각 필터는 실제 텔레메트리에서 관찰된 특정 FP(오탐) 클래스를 제거합니다:
| 필터 | 규칙 | 제거되는 FP 클래스 |
|---|---|---|
| F1 | count >= 5 | 무작위 포인터 형태 데이터, NULL, HMODULE |
| F2 | 호스트 EXE만 가리키는 런(run) 거부 | 애플리케이션 클래스 C++ vtable |
| F3 | distinct_modules >= 2 | 단일 DLL 프레임워크 vtable (Qt, MFC, wxWidgets) |
| F4 | capability_modules >= 2 | 단일 OS DLL에 연결되는 브라우저 / CRT vtable (예: iertutil + ucrtbase + shlwapi) |
| F5 (L10) | 확인 가능한 포인터의 >= 80%가 export된 RVA에 위치 | Winsock LSP 디스패치 테이블, 플러그인 콜백 배열, 내부(비 export) 메서드를 가리키는 vtable |
Aether는 현재 스텁 수준의 XOR 탐지 패턴을 지원하며, 메모리 영역 내 바이트 값의 무작위성을 확인하기 위해 Shannon 엔트로피 알고리즘을 채택하여 임계값을 초과하는 모든 항목을 플래그합니다. 높은 오탐(FP) 발생을 해결하기 위해 Aether는 여러 지표를 사용합니다.
GetExtendedTcpTable을 폴링MODIFIED_CODE_* 탐지 항목에
private_pages와 region_pages가 포함되어 트라이애지(triage)에 실제 수치 제공Aether.exe --scan --pid <PID> [OPTIONS]
Aether.exe --scan --lookup "ProcessName.exe"
Aether.exe --hunt <PID> SLEEP_MS PERIOD
Aether.exe --scan-all [OPTIONS]
| 플래그 | 설명 |
|---|---|
--pid, -p <PID> | 스캔할 대상 프로세스 ID |
--lookup, -l <name> | 프로세스 이름과 일치하는 모든 PID 찾기 |
--json, -j | 결과를 JSON으로 출력 (SIEM 통합용) |
--verbose, -v | 영역별 스캔 세부 정보 표시 |
--scan-all, -a | 모든 프로세스 스캔 |
--hunt, -b <PID> [ms] [hits] | 연결 모니터링 — ms 간격(기본값 2000)으로 폴링하고 hits 이상 발생한 엔드포인트 플래그 |
--networking | 네트워크 모니터링 모드 |
--rules, -r <dir> | 규칙 디렉터리 (기본값: rules/) |
--config, -c <file> | 단일 규칙 파일 (레거시 형식) |
--dump, `` | 사용자 지정 크기로 특정 메모리 영역 덤프 |
--read, `` | 터미널에서 메모리 영역 내용 실시간 읽기 |
--help, -h | 도움말 표시 |
git clone https://github.com/0xsp-SRD/aether
cd aether
# Debug build (safety checks enabled)
zig build
# Release build (smaller, faster binary)
zig build -Doptimize=ReleaseSafe
# or
zig build -Doptimize=ReleaseFast
빌드된 실행 파일은 zig-out/bin/Aether.exe에 생성됩니다.
추가 시그니처 스캔을 수행하려면 zig-out/bin/Aether.exe와 rules/ 디렉터리를 대상
Windows 머신에 복사하세요. 대상 프로세스에 관리자 권한이 필요한 경우 Aether.exe를
관리자 권한으로 실행해야 합니다.