Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
MOEW — 백서 | Kitploit
도구/GitHubGitHub/harryeetsource/moew
Defensive ToolsExploitationReverse EngineeringDebuggersMalware AnalysisLearning & EducationBinary Exploitation
GitHubharryeetsource/moew

MOEW

백서

저장소 보기
1628개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

보이지 않는 위협, 가시적인 해결책.

정렬이 어긋난 Opcode 예외 폭포 (MOEW)

3단계 SEH 폭포 PoC (무해, x86/Wow64)

TL;DR: 이 PoC는 의도적인 정렬이 어긋난 실행이 0으로 나누는 div reg 명령어가 첫 번째 유효 명령어인 원시 바이트 블롭으로 이어져 발생하는 3단계 구조적 예외 처리(SEH) 연쇄를 보여줍니다.
각 예외 단계는 다음 SEH 핸들러를 설치하고, 새로운 정렬이 어긋난 0으로 나누기를 트리거하며, 무해한 관찰 가능 페이로드를 실행한 후 원래 SEH 체인을 복원하고 깔끔하게 종료됩니다.


1. 개요

MOEW(Misaligned Opcode Exception Waterfall)는 x86/Wow64 Windows에서 제어된 예외 기반 다단계 실행을 선보이는 방어 연구 샘플입니다. 다음을 시연합니다:

  • fs:[0]을 통한 수동 SEH 체인 조작
  • 수제 바이트 시퀀스(blob1, blob2, blob3)로의 의도적인 정렬 어긋남
  • 단계별 연결된 SEH 핸들러
  • 다음을 통한 다중 오류 재귀:
    • KiUserExceptionDispatcher
    • RtlDispatchException
    • 사용자 정의 사용자 모드 핸들러
  • 원래 SEH 체인을 복원하는 깔끔한 종료 경로

모든 페이로드는 무해합니다:

  • 1단계: 메모장 실행
  • 2단계: %TEMP%에 마커 파일 생성
  • 최종 단계: 계산기 실행

PoC는 의도적으로 무력화되었습니다. 어떤 데이터도 암호화, 수정 또는 파괴되지 않습니다.


2. 기능

  • 3개의 단계별 핸들러를 통한 완전히 결정론적인 SEH 재귀
  • 여러 유효한 디코드 경로를 가진 네이키드 x86 바이트 블롭
  • 제어된 오프셋(ECX/EDX/EBX = 0)에서의 정렬이 어긋난 div
  • 로깅 및 추적을 위한 단계별 전역 카운터
  • 원래 SEH 헤드(ORIGINAL_SEH)의 완전한 복원
  • Rust nightly + 인라인 어셈블리 + 네이키드 함수
  • 무해하지만 가시적인 "페이로드" (원격 측정 및 디버거 테스트용)

3. 환경 요구사항

3.1 아키텍처

  • x86(32비트) 전용
  • MSVC 툴체인으로 컴파일
  • WoW64 하의 64비트 Windows에서도 실행 가능

3.2 Rust Nightly

PoC는 nightly 전용 기능을 사용합니다:

root@kitploit:~
#![feature(asm_experimental_arch)]
#![feature(naked_functions)]

필요한 구성 요소를 설치하세요:

root@kitploit:~
rustup toolchain install nightly
rustup target add i686-pc-windows-msvc --toolchain nightly

3.3 SAFESEH 비활성화

PoC는 SAFESEH 테이블에 없는 사용자 정의 SEH 핸들러를 설치하므로, 링커에 SAFESEH 검증을 비활성화하도록 지시해야 합니다.

.cargo/config.toml을 생성하세요:

root@kitploit:~
[target.i686-pc-windows-msvc]
rustflags = [
  "-C", "link-arg=/SAFESEH:NO",
]

4. 빌드 지침

바이너리 빌드:

root@kitploit:~
cargo +nightly build --target i686-pc-windows-msvc --release

출력 위치:

root@kitploit:~
target\i686-pc-windows-msvc\release\seh_waterfall.exe

5. PoC 실행

실행:

root@kitploit:~
seh_waterfall.exe

예상 제어 흐름:

root@kitploit:~
Stage 0 → 잘못 정렬된 blob1 → Stage 1 핸들러
Stage 1 → 잘못 정렬된 blob2 → Stage 2 핸들러
Stage 2 → 잘못 정렬된 blob3 → 최종 핸들러
최종 → SEH 복원 → 종료

가시적인 아티팩트:

  • notepad.exe 실행 (1단계)
  • %TEMP%\moew_stage2.txt 생성 (2단계)
  • calc.exe 실행 (최종 핸들러)

6. 기술 분석

6.1 SEH 레코드 레이아웃

32비트 Windows에서 SEH 레코드는 fs:[0]에 저장된 연결 리스트를 형성합니다:

root@kitploit:~
#[repr(C)]
struct SehRec {
    next: *mut SehRec,
    handler: usize,
}

각 핸들러는 표준 SEH 시그니처를 사용합니다:

root@kitploit:~
extern "system" fn handler(
    record: *mut u8,
    frame: *mut u8,
    context: *mut u8,
    dispatcher: *mut u8,
) -> i32

6.2 전역 상태

root@kitploit:~
static STAGE_COUNTER: AtomicU32 = AtomicU32::new(0);
static mut ORIGINAL_SEH: *mut SehRec = std::ptr::null_mut();

용도:

  • 핸들러 재귀 깊이 계산
  • 폭포 끝에서 원래 SEH 헤드 복원

7. 단계 로직

Stage 0 — 초기 프레임 설정

  1. fs:[0]을 ORIGINAL_SEH로 저장합니다.
  2. 1단계 핸들러를 가리키는 SEH 레코드를 빌드합니다.
  3. 이 새 레코드로 fs:[0]을 덮어씁니다.
  4. blob1 + 5로 잘못 정렬하여 ECX = 0 설정 후 div ecx로 디코드됩니다.

Stage 1 — 첫 번째 SEH 핸들러

  1. notepad.exe를 실행합니다.
  2. 2단계 핸들러에 대한 SEH 레코드를 빌드하고 상단에 연결합니다.
  3. blob2 + 3으로 잘못 정렬 → div edx (EDX = 0).

Stage 2 — 두 번째 SEH 핸들러

  1. %TEMP%\moew_stage2.txt를 작성합니다.
  2. SEH 체인에 최종 핸들러를 설치합니다.
  3. blob3 + 3으로 잘못 정렬 → div ebx (EBX = 0).

최종 핸들러 — 종료

  1. calc.exe를 실행합니다.
  2. ORIGINAL_SEH를 fs:[0]으로 복원합니다.
  3. process::exit(0)을 통해 프로세스를 깔끔하게 종료합니다.

8. 잘못 정렬된 오류 블롭

8.1 blob1

root@kitploit:~
#[unsafe(naked)]
pub extern "C" fn blob1() {
    naked_asm! {
        ".byte 0xB8, 0x10, 0x00, 0x00, 0x00", // mov eax, 0x10
        ".byte 0xF7, 0xF1",                   // div ecx
        ".byte 0xC3",                         // ret
        ".byte 0x90, 0x90, 0x90",             // nop padding
    }
}
  • 올바른 디코드: mov eax, 0x10; div ecx; ret
  • +5에서 잘못 정렬: div ecx (ECX = 0 → #DE)

8.2 blob2

root@kitploit:~
#[unsafe(naked)]
pub extern "C" fn blob2() {
    naked_asm! {
        ".byte 0x55",                         // push ebp
        ".byte 0x8B, 0xEC",                   // mov ebp, esp
        ".byte 0xF7, 0xF2",                   // div edx
        ".byte 0xC3",                         // ret
        ".byte 0x90, 0x90, 0x90",             // nop padding
    }
}
  • 올바른 디코드: push ebp; mov ebp, esp; div edx; ret
  • +3에서 잘못 정렬: div edx (EDX = 0 → #DE)

8.3 blob3

root@kitploit:~
#[unsafe(naked)]
pub extern "C" fn blob3() {
    naked_asm! {
        ".byte 0x53",                         // push ebx
        ".byte 0x8B, 0xD8",                   // mov ebx, eax
        ".byte 0xF7, 0xF3",                   // div ebx
        ".byte 0xC3",                         // ret
        ".byte 0x90, 0x90, 0x90",             // nop padding
    }
}
  • 올바른 디코드: push ebx; mov ebx, eax; div ebx; ret
  • +3에서 잘못 정렬: div ebx (EBX = 0 → #DE)

9. 예외 파이프라인

각 오류 단계는 Windows 사용자 모드 예외 파이프라인에 다시 진입합니다:

root@kitploit:~
KiUserExceptionDispatcher
    → RtlDispatchException
        → SEH 체인 워크 (fs:[0])
            → MOEW 핸들러

일반적인 디버거 보기:

root@kitploit:~
seh_waterfall!blobX+offset
ntdll!KiUserExceptionDispatcher
ntdll!RtlDispatchException
seh_waterfall!stageN_handler

폭포는 전적으로 실제 하드웨어 오류와 SEH 디스패치에 의해 구동되며, 합성 또는 가짜 예외는 사용되지 않습니다.


10. 마커 파일 출력

2단계에서 작성된 파일은 다음과 같습니다:

root@kitploit:~
MOEW Stage 2 Marker
-------------------
This file was written by the Stage 2 SEH handler
as a benign demonstration payload.

%TEMP%에 이 파일이 존재하는 것은 2단계가 SEH 체인을 통해 실행되었다는 간단하고 관찰 가능한 증거로 사용됩니다.


11. 안전 참고 사항

  • PoC는 무해하며 방어 연구 전용입니다.
  • 지속성, 레지스트리 수정 또는 암호화가 없습니다.
  • 모든 예외는 포착되어 처리됩니다.
  • 종료 전에 원래 SEH 체인이 복원됩니다.

12. 향후 개선 사항

잠재적인 확장:

  • SEH 폭포 및 재귀 예외 패턴에 대한 YARA 및 동작 규칙
  • 단계별 하드웨어 오류에 대한 ETW/EDR 신호 매핑
  • 시간에 따른 SEH 체인 진화의 그래픽 다이어그램
  • 실제 악성코드 예외 체인과의 비교

13. 전체 소스 코드

완전한 PoC 구현은 이 저장소에서 확인할 수 있습니다(src/main.rs 참조).


14. 라이선스

이 프로젝트는 방어 연구 및 교육을 목적으로 합니다. Copyright <2025>

본 소프트웨어 및 관련 문서 파일("소프트웨어")의 사본을 취득하는 모든 사람에게는 다음 조건에 따라 소프트웨어를 제한 없이 다룰 수 있는 권한이 무료로 부여됩니다. 여기에는 소프트웨어의 사용, 복사, 수정, 병합, 게시, 배포, 서브라이선스 및/또는 판매 권리와 소프트웨어를 제공받은 사람이 그렇게 할 수 있도록 허용하는 것이 포함됩니다.

위 저작권 고지 및 이 허가 고지는 소프트웨어의 모든 사본 또는 중요 부분에 포함되어야 합니다.

소프트웨어는 "있는 그대로" 제공되며, 상품성, 특정 목적에의 적합성 및 비침해에 대한 보증을 포함하되 이에 국한되지 않는 어떠한 명시적 또는 묵시적 보증 없이 제공됩니다. 어떠한 경우에도 저자 또는 저작권 소유자는 계약 행위, 불법 행위 또는 기타에 관계없이 소프트웨어 또는 소프트웨어의 사용 또는 기타 거래로 인해 발생하는 모든 청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다.


15. 실제 샘플 대 PoC: SEH 손상, 폭포 동작 및 원격 측정 영향

15.1 실제 샘플의 동작: 의도적인 SEH 손상

이 PoC에 영감을 준 실제 MOEW 샘플은 실행 종료 시 fs:[0]을 복원하지 않았습니다.
대신 최종 단계에서 다음을 수행했습니다:

  1. SEH 헤드(fs:[0])를 NULL 또는 유효하지 않은 메모리를 가리키는 포인터로 덮어썼습니다.
  2. 마지막으로 잘못 정렬된 예외를 트리거하여 하드웨어 오류를 보장했습니다.
  3. Windows가 유효하지 않거나 잘린 SEH 체인을 탐색하도록 강제했습니다.
  4. RtlDispatchException이 유효하지 않은 핸들러 포인터를 만나게 했습니다.
  5. 다음과 같은 충돌이 발생했습니다:
    • EIP/RIP가 이미지 메모리가 아닌 위치(힙, 스택 또는 익명 영역)를 가리킴.
    • 오류 모듈을 확인할 수 없어 unknown으로 나타남.
    • 오류 경로도 unknown으로 나타남.
  6. 로드된 모듈에 귀속될 수 없는 Windows 오류 보고(WER) 서명을 생성했습니다.
  7. 의미 없는 오류 오프셋이 포함된 이벤트 뷰어 Application Error 이벤트를 기록했습니다.
  8. 다음과 같은 EDR 원격 측정이 지배적이었습니다:
    • 반복된 KiUserExceptionDispatcher 호출,
    • 재귀적 SEH 전환,
    • 모듈 귀속이 부족한 최종 비정상적 충돌.

이 파괴적인 SEH 손상 단계는 샘플의 주요 안티포렌식 목적을 수행합니다:
인과 관계 체인을 지우고 귀속 불가능한 종료 충돌을 생성하는 것.


15.2 PoC의 동작: 종료 충돌 없이 SEH를 깔끔하게 복원

실제 샘플과 달리 이 PoC는:

  • Stage 0에서 원래 SEH 헤드를 캡처합니다:

    root@kitploit:~
    asm!("mov {old}, fs:[0]", old = out(reg) old_head);
    ORIGINAL_SEH = old_head;
    
  • 최종 핸들러에서 원래 SEH 헤드를 복원합니다:

    root@kitploit:~
    asm!("mov fs:[0], {p}", p = in(reg) ORIGINAL_SEH);
    
  • 처리되지 않은 오류를 트리거하는 대신 process::exit(0)을 통해 깔끔하게 종료합니다.

따라서 PoC는:

  • 손상된 SEH 체인을 남기지 않습니다.
  • 최종 처리되지 않은 예외를 생성하지 않습니다.
  • 다음을 생성하지 않습니다:
    • WER 충돌 보고서,
    • 이벤트 뷰어 Application Error 1000 항목,
    • "faulting module: unknown" 서명,
    • 유효하지 않은 예외 처리,
    • 또는 매달린 SEH 레코드.

그러나 중요하게도, PoC는 MOEW의 예외 기반 원격 측정 성능 저하 동작을 제거하지 않습니다.


15.3 실제 샘플과 PoC가 공유하는 원격 측정 성능 저하

PoC는 동일한 기본 방식으로 원격 측정을 확실히 저하시킵니다:

  • 의도적으로 여러 개의 정렬이 어긋난 하드웨어 오류를 트리거합니다.

  • 빠른 연속으로 여러 개의 first-chance 예외를 생성합니다.

  • Windows가 다음을 반복적으로 실행하도록 강제합니다:

    root@kitploit:~
    KiUserExceptionDispatcher
    RtlDispatchException
        → 사용자 정의 핸들러
        → 잘못 정렬된 블롭
        → 하드웨어 오류
    
  • 비선형적이고 예외가 지배적인 호출 스택을 생성합니다.

  • 디버거 및 EDR에서 제어 흐름 재구성을 왜곡하여 실행을 다음을 통해 라우팅합니다:

    • 재귀적 SEH 핸들러,
    • 잘못 정렬된 디코드 경로,
    • 함수 정렬되지 않은 주소,
    • 부분 명령어 경계.

따라서 PoC는 다음을 충실히 재현합니다:

  • 재귀적 폭포 패턴,
  • 예외 기반 상태 머신,
  • 잘못 정렬된 opcode 진입 동작,
  • 제어 흐름 난독화,

…단, 파괴적인 최종 충돌은 피합니다.

따라서 PoC는 전체 안티포렌식 페이로드를 호출하지 않고 계측 및 연구에 이상적입니다.


15.4 PoC가 방어 연구에 적합한 이유

PoC는 SEH 손상 충돌을 제외한 MOEW의 전반적인 동작을 보존하기 때문에:

  • 실험실 환경에서 반복적으로 실행해도 안전합니다.
  • 결정론적이고 안정적입니다.
  • 다음에 적합합니다:
    • EDR 파이프라인 분석,
    • 원격 측정 연구,
    • 침해 대응 훈련,
    • 디버거 동작 테스트,
    • 실제 악성 샘플과의 비교.

PoC는 최종 파괴적 서명을 제거하면서 예외 폭포(MOEW의 핵심)를 모델링합니다.
원격 측정 성능 저하가 SEH 손상뿐만 아니라 예외 기반 제어 흐름 모델 자체에서 발생함을 보여줍니다.


15.5 요약

이 섹션은 PoC의 목적을 명확히 하면서 동작 차이를 공식화합니다:
안티포렌식 최종 충돌 없이 안전하고 연구 친화적인 형태로 MOEW 폭포를 시연하는 것.

도구 다운로드
동작실제 MOEW 샘플PoC 구현
잘못 정렬된 opcode 폭포✔✔
재귀적 SEH 기반 상태 머신✔✔
예외 디스패치 호출 스택이 지배적✔✔
원격 측정 / 스택 추적 성능 저하✔✔
의도적인 SEH 손상✔❌
매달린 또는 유효하지 않은 SEH 포인터✔❌
최종 처리되지 않은 예외✔❌
WER "알 수 없는 모듈" 충돌✔❌
fs:[0]의 깔끔한 복원❌✔
깔끔한 종료❌✔