JIT 스프레이 공격과 방어 전략
JIT 스프레이는 JIT 컴파일러가 생성한 실행 가능한 코드를 메모리 대량에 분산시켜 DEP와 ASLR을 우회하는 최신 공격 기법이다. 본 논문은 해당 기법의 동작 원리를 설명하고, 안티‑JIT 스프레이 라이브러리를 포함한 여러 차원의 방어 방안을 제시한다.
초록
JIT 스프레이는 JIT 컴파일러가 생성한 실행 가능한 코드를 메모리 대량에 분산시켜 DEP와 ASLR을 우회하는 최신 공격 기법이다. 본 논문은 해당 기법의 동작 원리를 설명하고, 안티‑JIT 스프레이 라이브러리를 포함한 여러 차원의 방어 방안을 제시한다.
상세 요약
JIT 스프레이는 Just‑In‑Time 컴파일러가 런타임에 생성하는 머신 코드 조각을 악용한다. 현대 브라우저와 스크립트 엔진은 성능 향상을 위해 자바스크립트, ActionScript, WebAssembly 등을 JIT 컴파일한다. 이 과정에서 생성된 코드는 일반적인 힙 영역에 위치하며, 메모리 페이지에 실행 권한이 부여된다(DEP 우회). 또한 JIT 엔진은 코드 페이지를 일정한 패턴으로 배치하고, 동일한 함수에 대해 동일한 바이트 시퀀스를 반복 생성하므로, 공격자는 예측 가능한 명령어 시퀀스를 대량으로 스프레이할 수 있다. 이러한 스프레이된 코드 블록은 주소 공간이 무작위화(ASLR)된 환경에서도 충분히 높은 확률로 목표 주소에 도달한다. 공격자는 스프레이된 코드 중 하나에 jump‑or‑call 가젯을 삽입하거나, 기존 가젯을 재구성해 쉘코드를 실행한다.
논문에서는 JIT 스프레이의 두 가지 핵심 특징을 강조한다. 첫째, JIT 엔진이 생성하는 코드가 데이터와 구분되지 않아 메모리 보호 메커니즘이 적용되기 어렵다. 둘째, JIT 컴파일 과정에서 사용되는 상수 풀(constant pool)과 인라인된 리터럴이 동일한 바이트 패턴을 반복함으로써 메모리 내에 고밀도 실행 코드 영역을 만든다. 이러한 특성은 기존의 메모리 스프레이와 달리 작은 메모리 페이지에서도 충분히 공격이 가능하도록 만든다.
방어 측면에서는 여러 차원의 완화책이 논의된다. 첫 번째는 JIT 엔진 자체를 강화하는 방법이다. 예를 들어, JIT 코드 페이지에 W^X(Write‑xor‑Execute) 정책을 적용하고, 코드 생성 직후 페이지 권한을 read‑only로 전환한다. 두 번째는 가젯 최소화 전략으로, 불필요한 연산을 제거하고, 난수 기반 명령어 시퀀스를 삽입해 예측 가능성을 감소시킨다. 세 번째는 실행 시점에 JIT 코드 영역을 모니터링하는 안티‑JIT 스프레이 라이브러리이다. 이 라이브러리는 페이지 할당 시점에 메모리 페이지 속성을 검사하고, 비정상적으로 높은 실행 가능 바이트 패턴 비율을 감지하면 해당 페이지를 quarantine하거나 실행을 차단한다. 또한, 스택 가드와 컨트롤 플로우 인테그리티(CFI)를 결합해 비정상적인 제어 흐름 전이를 차단한다.
실험 결과, 제안된 안티‑JIT 스프레이 라이브러리는 기존 JIT 스프레이 공격을 97% 이상 차단했으며, 정상적인 JIT 컴파일 성능에 미치는 오버헤드는 3% 미만에 머물렀다. 이는 메모리 보호와 성능 사이의 균형을 효과적으로 맞춘 사례로 평가된다.
📜 논문 원문 (영문)
🚀 1TB 저장소에서 고화질 레이아웃을 불러오는 중입니다...