SlideShare una empresa de Scribd logo
1 de 7
Descargar para leer sin conexión
Windows-Kernel-Exploit
1. 개요
1.1. 왜 터널인가.
난이도가 높다.
DEP, ASLR, UAC, Heap checks, Protected Mode, Sandboxes 등을 유저 모드에 도입하여 유저 모드와 난이도가 비슷하
거나 오히려 더 쉬울 수도 있다.
유저 모드 보안과 병행한 많은 OS 기능이 커널로 이동하여 새로운 사용자 - 커널 인터페이스가 도입된 후 커널의 공격
영역이 크게 증가했다.
1.2. 무엇이 다른 가
잘못하면 블루스크린이나 시스템 재부팅으로 이어질 수 있다.
사용 권한에 대해 걱정할 필요가 없다.
더 많은 지식이 필요하다.
프로세스 경계가 없으므로 더 많은 것을 해볼 수 있다.
1.3. 필요 배경지식
Kernel APIs
Memory Layout
Interrupts, IRQLs, DPCs, IRPs
Synchronization: Events, Spinlocks, Mutexes, Timers, Semaphores, Resources
Paging mechanism
Intel System Architecture
Device Driver structure, MJ functions, IOCTLs
1.4. 취약점 연구
먼저 하이 레벨 접근법부터 시작하자
복잡한 로직을 찾는다.
서로 다른 팀의 협력이 필요한 인터페이스가 취약하다(예를 들어 사용자와 커널 간의 상호 작용이 필요한 부분)
Remote 취약점보다 권한 상승이 더 쉽다.
여러 약한 공격이 하나의 강력한 공격으로 구성될 수 있다.
2. 본론
2.1. 취약점 발견을 위한 세 가지 접근법
1. 하이 레벨 접근법
전체 시스템의 동작 과정을 이해하고 취약한 부분을 찾는다.
2. 로우 레벨 접근법
복잡해보이는 함수를 찾고 분해하며 버그를 찾는다.
3. 퍼징 접근법(블랙 박스 / 무차별 대입)
가능한 모든 유형의 값을 삽입하여 충돌을 유발시키고 충돌 정보를 살펴본다.
2.1.1. 하이 레벨 접근법
사용자 가이드, 레퍼런스 문서, 버그 리포트 등 분석 대상에 대해서 알 수 있는 정보들을 숙지한다. “이 기능을 개발하려면 어
떻게 해야할 까”를 고민하며 발생 가능한 보안 위협에 대한 항목을 설정하고 해당 코드를 검색한다.
2.1.2. 로우 레벨 접근법
코드에서 논리적으로, 기술적으로 복잡한 기능이나 연산을 분류한다. 분류한 기능의 코드 분석 혹은 역공학을 통해 버그를 찾
는다. 버그가 발견되면 공격 가능한 방법이 있는 지 파악한다.
2.1.3. 퍼징 접근법(블랙박스/무차별 대입)
모든 코드 내 존재하는 입력 필드를 분류한다. 분류된 입력 필드에서 CRC, Length와 같은 계산된 데이터를 포함하는 구조를
찾는다. 입력 테스트를 진행한다.
잘못 다뤘을 가능성이 있는 입력 사항을 생각
입력을 생성하는 스크립트 작성
퍼징 스크립트 수행
2.2. 버그
2.2.1. Common bugs
Buffer overflows (stack and pool)
NULL dereference
Faulty input validation
2.2.2. Less common bugs
Use-after-free
Direct calling to User code
Logical bugs
2.2.3 Exploit 개발
Exploit 개발을 위해서는 다음에 대한 지식이 필요하다
Constant memory addresses
Memory layouts
Heaps, Pools, Stacks
APIs, Objects
CPU
Assembly
커널 모드에서는 프로세스 영역이 없으므로 모든 곳을 할 수 있다.
2.3. Example
2.3.1 User-after-free
이미 해제된 오브젝트를 엑티브 오브젝트 링크드 리스트에 유지하는 버그.
오브젝트들이 접근하기 전, 해제된 버퍼에 임의의 데이터를 삽입.
1. 드라이버 버그를 이용하여 CPU 기아현상을(기아현상 : 시스템 부하가 많아서 준비 큐에 낮은 등급 프로세스가 무한정 대기
하는 현상) 발생시켜 다른 오브젝트가 버퍼를 가로채지 못하게 한다.
2. 적절한 크기의 버퍼를 할당하고 데이터를 복사하는 두 번째 드라이브에서 DPC(Deffrred Procedure Call) 코드를 사용한다.
3. 해제된 오브젝트를 사용하는 티켓 드라이버의 코드를 활성화하여 쉘 코드가 실행되도록 한다.
2.3.2 DRM
커널 Exploit은 아니지만 커널과 유저 간 인터페이스 사용의 좋은 예가 된다.
- 유저와 커널 사이의 안전하지 못한 인터페이스(서로 다른 팀의 협력이 필요한 인터페이스가 취약하다)
2.3.2.1. 영화 복사 방지 DRM 예시
지정된 컴퓨터 외 다른 컴퓨터에서는 재생되지 않게 하는 DRM 시스템을 예로 알아보자.
조건
모든 영화는 암호화되어 있다.
복호화 코드는 영화 내부에 내장되어 있다.
하드웨어를 기반으로 컴퓨터 별 라이센스가 부여된다. 하드웨어에 접근하기 위해서는 커널 코드가 필요하므로
영화 내 복호화 코드가 드라이버를 호출한 후 사용자 코드를 다시 호출하게 된다.
Hook DeviceloControl
1. try … catch 문에서 드라이버 호출 대신 유저 모드 코드를 호출하게 한다.
2. BIOS를 읽거나 하드웨어에 접근하는 경우 예외를 발생시키는 데, 특정 파일에서 내용을 읽어들이는 것으로 예외
처리를 한다. 이를 이용하여 모든 컴퓨터에서 동일한 하드웨어를 인식하도록 속여 동일한 라이센스를 다른 컴퓨
터에서 이용할 수 있게 한다.
2.4. Tip
임의의 데이터 삽입 : 덮어쓰기 좋은 위치
고정 주소가 있는 일반 장소(OS 빌드 별)
콜백 함수 포인터
데이터 세그먼트 변수
GDT / LDT 표 (http://j00ru.vexillium.org/?p=290)
Dispatch Table (새로운 OS에서는 차단됨)
우리는 BIOS / 하드웨어 대신 파일에서 데이터를 읽어오는 것으로 예외를 처리 하므로 동일한 하드웨어로 인식
하도록 속여 동일한 라이센스를 사용할 수 있다.
비 고정 주소 추출
Windows Handle Table은 유저 주소 공간에 매핑되어 함수 포인터가 있는 객체에 대한 커널 포인터를 포
함한다. (http://www.mista.nu/research/mandt- win32k-paper.pdf)
1. Kernel window 생성 (win32k가 생성하고 등록한 window 클래스로 커널 안에 window 프로시저가
Menus 및 Tooltips과 같이 있음)
2. Handle Table에서 Kernel window 객체에 대한 포인터를 가져온다.
3. WndProc 포인터를 덮어쓴다.
4. WndProc 포인터를 트리거하는 메시지를 window에 보낸다.
유저 공간으로 전달되는 다른 커널 포인터.
일부 win32k.sys 시스템 호출은 VOID 또는 USHORT로 정의되고 반환 값에서 전체 또는 일부의 커
널 포인트를 노출한다. (http://j00ru.vexillium.org/?p=762)
블루스크린은 끝이 아니다.
Exception 이후에 실행되는 많은 코드가 있으며 그 중에는 덮어쓸 수 있는 콜백 함수를 호출하는 경우가 많다. 특
히 ACCESS_VIOLATIONS의 경우 page-fault handler로 먼저 이동하므로 많은 공격 옵션이 존재한다.
KeBugCheck 내부에도 덮어 쓸 수 있는 콜백이 존재한다. 컨텍스트를 수정하고 정상 실행를 하는 것은 까다로운
일이지만, 할 수 있습니다.
WOW64 processes
64비트 시스템에서 32비트 프로세스를 실행할 때, NtQuerySystemInformation을 호출하려고 하면 리턴된 모든
포인터가 32비트로 잘린다. 내장된 call gate를 사용하여 일시적으로 64비트로 전환하여
NtQuerySystemInformation을 호출 한 다음 32 비트 코드로 돌아와 극복 할 수 있습니다. (자세한 내용은
http://vxheavens.com/lib/vrg02.html 참조) 64 비트 TEB는 gs : 0에 매핑되어 있기 때문에 64 비트를 모두
switching하지 않고 직접 액세스 할 수 있다.
2.5. 커널에서 사용자까지
많은 경우 커널 Exploit은 유저 모드 페이로드 설치 나 유저모드 코드의 실행이 필요하다. 하지만 시스템 권한으로 실행되는
커널에서 유저 모드 코드를 실행한다는 것은 매우 어려운 일이다. 이제 몇 가지 기법과 각 기법의 장단점을 살펴보자.
Changing the process token
방법 : 이미 제어하고 있는 프로세스 토큰을 시스템 토큰으로 변경한다. (예를 들어 Exploit을 시작한 프로세스)
장점 : 구현 방법이 쉽고 안정적이다.
단점 : 유저 모드 코드로 모든 까다로운 작업을 수행해야하므로(예를 들어 시스템 프로세스에 코드 삽입) 사용자
API를 후킹하는 백신 프로그램 혹은 보안 프로그램에 취약하다.
User-mode APCs
방법 : 시스템 프로세스의 스레드를 대상으로 유저 모드 APC를 준비시킨다.
장점 : 원하는 위치로 바로 이동이 가능하며, 시스템의 모든 프로세스에 삽입이 가능하다.
단점 : Alertable 상태에 있는 스레드만 대상으로 지정할 수 있으며 이를 찾을 수 있는 일반적인 방법은 없다. 스레
드를 Alertable 상태로 강제하는 방법이 있지만, 대기 상태가 중단되고 대기 함수가 중간에 리턴되어 시스템이 불
안정해지거나 충돌을 일으킬 수 있다. 관련 구조에 대한 문서화가 아직 이루어지지 않았으며 OS 버전 마다 차이
가 있다. 그러므로 잘 알고 있는 스레드를 댓ㅇ으로 하지 않는 한, 스레드가 대기 상태(예를 들어 LoaderLock)로
들어갈 때 스레드가 일부 Lock을 holding하고 있으면 이 방법을 사용 시 교착 상태가 발생할 수 있다.
Thread Hijacking
방법 : 시스템 프로세스에서 기존 스레드의 컨텍스트를 변경하여 삽입한 코드를 실행한다.
장점 : 원하는 위치로 바로 이동이 가능하며, 시스템의 모든 프로세스에 삽입이 가능하다.
단점 : 컨텍스트 복원이 매우 어려울 수 있다. 임의의 스레드를 Hijacking하는 것은 교착 상태, 불안정성 또는 충
돌을 일으킬 수 있다.
Creating a new thread
방법 : 시스템 프로세스에 새로운 유저 모드 스레드를 생성한다.
장점 : 거의 완벽한 해결책으로 어떤 위험이나 컨텍스트 문제 없이 원하는 위치로 정확하게 이동할 수 있으며, 시
스템의 모든 프로세스에 삽입이 가능하다.
단점 : 구현하기가 매우 어렵다. 새 스레드가 작동하려면 CSRSS에 등록해야 한다. API와 구조가 복잡하고 문서
화되어 있지 않으며 Windows 업데이트로 끊임없이 변경되고 있다.
API hooking
방법 : 호출될 것임을 알고 있는 유저 모드 API 또는 시스템 프로세스 내에서 호출되도록 할 수 있는 유저 모드
API hooking.
장점 : 시스템 프로세스에 직접 삽입 가능하며 매우 안정적이다.
단점 : 적절한 API를 찾아내는 것이 어렵다. 이 방법은 일반적이지 않고 대상 API를 자주 호출하는 시스템 프로세
스에서만 적합하다.
간단한 커널 Exploit 예제 - AFD.SYS
AfdGetRemoteAddress를 살펴보자. 어떤 문제가 존재하는 가.
// Attacker controls OutputBuffer and OutputBufferLength
void IOCTL_handler(...) {
[...]
try {
ProbeForWrite (OutputBuffer,
OutputBufferLength,
sizeof (UCHAR));
RtlCopyMemory(
OutputBuffer,
(PUCHAR)context+endpoint->Common.VcConnecting.RemoteSocketAddressOffset,
endpoint->Common.VcConnecting.RemoteSocketAddressLength
);
} except( AFD_EXCEPTION_FILTER(&status) ) {
}
[...]
}
힌트 : 실제 포인터와 무관하게 길이가 0인 경우에 대해 ProbeForWrite에서 예외(throw) 처리를 하지 않는다.
우리는 커널 주소를 포함한 원하는 주소에 우리가 원하는 값을 쓸 수 있지만 실제로 제어할 수는 없다. 작성된 데이터는 다음
과 같다.
- 02 00 XX XX YY YY YY, 여기서 XXXX는 포트, YYYYYYYY는 IP이다.
함수가 동작하려면 활성 TCP 연결이 있어야한다. 무엇을 해야 하는가? 데이터를 완전히 제어 할 필요가 없는 것은 아닐까.
우리는 127.0.0.1, 즉 7F 00 00 01에 연결할 수 있다. Port 445(01 BD)는 Windows 컴퓨터에서 항상 열려 있다. 01 BD 7F 00 00 01?
인텔은 Little Endian이므로 0x00007FBD가 된다. 이제 덮어 쓸 포인터가 필요하다. 이것은 XP에서만 작동하는 오래된 버그이
므로 Dispatch Table을 사용할 수 있다.
Exploit
1. 0x7fb0에 페이지를 할당하고 쉘코드를 복사한다.
2. HookAddress = ZwQueryIntervalProfile에 대한 Dispatch Table entry
3. 127.0.0.1:445에 연결(connect()).
4. DeviceIoControl(HANDLE)sock, 0x1203F, NULL, 0, (PVOID)(HookAddress - 3), 0, &Result, NULL)
5. ZwQueryIntervalProfile()
Background
Window Class를 등록할 때, OS에게 윈도우 객체와 함께 Extra Bytes를 저장하도록 요청할 수 있다. Extra Bytes는 커널
의 WND Struct에 추가된다.
​ |WND Struct|Extra Bytes|
일부 window types(Menus, Tooltips)는 커널에서만 접근할 수 있는 private data가 있다.
​ |WND Struct|PrivateData|Extra Bytes|
Extra bytes의 데이터를 변경하기 위해서 value와 Extra Bytes index와 함께 SetWindowLongPtr 함수를 호출한다.
함수는 제공된 index가 private data 또는 user extra bytes에 속하는 지 확인한다. 만약 private bytes에 속한다면 함수
가 실패하므로, private 커널 데이터를 변경할 수 없다.
​​ |WND Struct|(X)PrivateData|Extra Bytes|
SetWindowLongPtr 함수는 전체 allocated bytes size(WND struct + private)가 있는 window types Table을 사용하여
private data 내에 속하는 지 확인한다. “Window type”은 하드 코딩된 값 목록(해당 클래스가 아닌)에서 window type
의 실제 식별자인 FNID를 나타낸다. 확인을 위한 pseudo code는 다음과 같다.
if (index < (int)(window_class_alloc_sizes[fnid]-sizeof(WND)))) FAIL;
Window Type(FNID) allocated bytes
Menu 0xa4 (WND size) + 4 (private bytes) == 0xa8
Tooltip 0xa4 (WND size) +4 (private bytes) == 0xa8
The bug.part1
문서화되지 않은 unexported 함수인 RegisterClassExWOWW에 internal window type과 extra bytes에 대해 음수를 사용하면
테이블을 임의의 값으로 덮어쓰는 것이 가능하다. 이 버그는 extra bytes 값을 검증하지 않아서 발생한다.
​Window Type(FNID) allocated bytes
Menu 0xa4 (WND size) + (-0xa8) (private bytes) == -4
Tooltip 0xa4 (WND size) +4 (private bytes) == 0xa8
할당된 바이트 수를 음수로 덮어쓴 테이블을 사용하면 검증 로직 우회가 가능하다.
(index < (int)(window_class_alloc_sizes[fnid]-sizeof(WND)))) == always FALSE
우리는 이를 이용하여 인덱스를 0으로 설정하고 SetWindowLongPtr함수를 호출하여 window private kernel data를 수정할
수 있다.
|WND Struct|(V)Private Data|Extra Bytes|
The bug.part2
이제 private kernel data에서 덮어썼을 때 유용하게 사용할 수 있는 window type을 찾아야 한다. Menu window type은
구조체에 대한 포인터를 저장하고 window가 제거된 동안 해당 구조체의 포인터가 NULL로 설정되어 시스템의 32/64
비트 값을 NULL로 지정할 수 있습니다. (Bingo!)
Menu window private 구조는 윈도우즈 버전에 따라 변경되므로 우리는 Exploit을 두번 수행한다.
포인터가 non-NULL인 배열의 포인터를 가진 구조체에 처음 덮어 쓰므로 NULL이 있는 offset을 찾을 수 있다.
두 번째로 NULL에 삽입할 주소를 가진 포인터와 첫 번째 단계에서 발견 된 offset을 뺀다.
이제 쉘 코드를 페이지 0에 할당하고 함수 포인터를 덮어 쓴 후 호출한다.
Flow
1. Find the address of RegisterClassExWOWW using diStorm
2. RegisterClassExWOWW() passing the FNID for a Menu and a WNDCLASSEX structure with a negative number
for the extra bytes
3. CreateWindow()
4. SetWindowLongPtr() with a non-NULL array
5. DestroyWindow()
6. Find offset
7. Repeat steps 3-5, this time passing the actual address to overwrite minus the offset
8. Get the overwritten pointer to be called
2.6. Windows8 특징
Null-dereference is blocked – first 64k can’t be allocated
New integrity checks to the kernel pool memory allocator (see
http://blogs.msdn.com/b/b8/archive/2011/09/15/protecting-you-from-malware.aspx)
Improved Linked-Lists security to protect against corrupted/dangling list pointers (see http://www.alex-
ionescu.com/?p=69)
본문에서 사용된 Kernel Exploit POC Code : ExploitDB

Más contenido relacionado

La actualidad más candente

Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumerChang Yoon Oh
 
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것흥배 최
 
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?내훈 정
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback흥배 최
 
Linux 강의자료 ed10
Linux 강의자료 ed10Linux 강의자료 ed10
Linux 강의자료 ed10hungrok
 

La actualidad más candente (6)

Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumer
 
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
multi-thread 어플리케이션에 대해 모든 개발자가 알아 두지 않으면 안 되는 것
 
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
 
Linux 강의자료 ed10
Linux 강의자료 ed10Linux 강의자료 ed10
Linux 강의자료 ed10
 
Linux tutorial
Linux tutorialLinux tutorial
Linux tutorial
 

Similar a 윈도우 커널 익스플로잇

운영체제 Sig2
운영체제 Sig2운영체제 Sig2
운영체제 Sig2YoungGun Na
 
2. windows system과 file format
2. windows system과 file format2. windows system과 file format
2. windows system과 file formatYoungjun Chang
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드KwangSeob Jeong
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍Yong Joon Moon
 
클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기YoungSu Son
 
[slideshare]k8s.pptx
[slideshare]k8s.pptx[slideshare]k8s.pptx
[slideshare]k8s.pptxssuserb8551e
 
150625 마이크로커널 운영체제 김지은
150625 마이크로커널 운영체제 김지은150625 마이크로커널 운영체제 김지은
150625 마이크로커널 운영체제 김지은jieun kim
 
caanoo Device driver
caanoo Device drivercaanoo Device driver
caanoo Device driverjumiss
 
UNIX 시스템 2014-2018년 기말시험 기출문제
UNIX 시스템 2014-2018년 기말시험 기출문제UNIX 시스템 2014-2018년 기말시험 기출문제
UNIX 시스템 2014-2018년 기말시험 기출문제Lee Sang-Ho
 
Packet tracer 설치 및 사용법
Packet tracer 설치 및 사용법Packet tracer 설치 및 사용법
Packet tracer 설치 및 사용법Sehan Lee
 
Why OpenStack is Operating System?
Why OpenStack is Operating System?Why OpenStack is Operating System?
Why OpenStack is Operating System?유명환 FunFun Yoo
 
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 APINAVER Engineering
 
샌드박스
샌드박스샌드박스
샌드박스Baekjoon Choi
 
Exynos4210 beginnerrev10
Exynos4210 beginnerrev10Exynos4210 beginnerrev10
Exynos4210 beginnerrev10mimul
 
Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016perillamint
 
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...Taekyu Lim
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리Seungyong Lee
 
안드로이드 플랫폼 설명
안드로이드 플랫폼 설명안드로이드 플랫폼 설명
안드로이드 플랫폼 설명Peter YoungSik Yun
 
오픈스택: 구석구석 파헤쳐보기
오픈스택: 구석구석 파헤쳐보기오픈스택: 구석구석 파헤쳐보기
오픈스택: 구석구석 파헤쳐보기Jaehwa Park
 
Net debugging 3_전한별
Net debugging 3_전한별Net debugging 3_전한별
Net debugging 3_전한별Han-Byul Jeon
 

Similar a 윈도우 커널 익스플로잇 (20)

운영체제 Sig2
운영체제 Sig2운영체제 Sig2
운영체제 Sig2
 
2. windows system과 file format
2. windows system과 file format2. windows system과 file format
2. windows system과 file format
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍
 
클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기
 
[slideshare]k8s.pptx
[slideshare]k8s.pptx[slideshare]k8s.pptx
[slideshare]k8s.pptx
 
150625 마이크로커널 운영체제 김지은
150625 마이크로커널 운영체제 김지은150625 마이크로커널 운영체제 김지은
150625 마이크로커널 운영체제 김지은
 
caanoo Device driver
caanoo Device drivercaanoo Device driver
caanoo Device driver
 
UNIX 시스템 2014-2018년 기말시험 기출문제
UNIX 시스템 2014-2018년 기말시험 기출문제UNIX 시스템 2014-2018년 기말시험 기출문제
UNIX 시스템 2014-2018년 기말시험 기출문제
 
Packet tracer 설치 및 사용법
Packet tracer 설치 및 사용법Packet tracer 설치 및 사용법
Packet tracer 설치 및 사용법
 
Why OpenStack is Operating System?
Why OpenStack is Operating System?Why OpenStack is Operating System?
Why OpenStack is Operating System?
 
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
 
샌드박스
샌드박스샌드박스
샌드박스
 
Exynos4210 beginnerrev10
Exynos4210 beginnerrev10Exynos4210 beginnerrev10
Exynos4210 beginnerrev10
 
Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016
 
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리
 
안드로이드 플랫폼 설명
안드로이드 플랫폼 설명안드로이드 플랫폼 설명
안드로이드 플랫폼 설명
 
오픈스택: 구석구석 파헤쳐보기
오픈스택: 구석구석 파헤쳐보기오픈스택: 구석구석 파헤쳐보기
오픈스택: 구석구석 파헤쳐보기
 
Net debugging 3_전한별
Net debugging 3_전한별Net debugging 3_전한별
Net debugging 3_전한별
 

Más de Seungyong Lee

Secure coding-c-dcl-1
Secure coding-c-dcl-1Secure coding-c-dcl-1
Secure coding-c-dcl-1Seungyong Lee
 
Secure coding-c-preprocessor-3
Secure coding-c-preprocessor-3Secure coding-c-preprocessor-3
Secure coding-c-preprocessor-3Seungyong Lee
 
Secure coding-c-preprocessor-2
Secure coding-c-preprocessor-2Secure coding-c-preprocessor-2
Secure coding-c-preprocessor-2Seungyong Lee
 
Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1Seungyong Lee
 
Linux blue borne-vulnerabilities
Linux blue borne-vulnerabilitiesLinux blue borne-vulnerabilities
Linux blue borne-vulnerabilitiesSeungyong Lee
 
Sha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSeungyong Lee
 
화이트 박스 암호기법
화이트 박스 암호기법화이트 박스 암호기법
화이트 박스 암호기법Seungyong Lee
 
C 프로그램 메모리 구조
C 프로그램 메모리 구조C 프로그램 메모리 구조
C 프로그램 메모리 구조Seungyong Lee
 
암호 기법의 소개
암호 기법의 소개암호 기법의 소개
암호 기법의 소개Seungyong Lee
 
문자열이란 무엇인가
문자열이란 무엇인가문자열이란 무엇인가
문자열이란 무엇인가Seungyong Lee
 

Más de Seungyong Lee (12)

Secure coding-c-dcl-1
Secure coding-c-dcl-1Secure coding-c-dcl-1
Secure coding-c-dcl-1
 
Secure coding-c-preprocessor-3
Secure coding-c-preprocessor-3Secure coding-c-preprocessor-3
Secure coding-c-preprocessor-3
 
Secure coding-c-preprocessor-2
Secure coding-c-preprocessor-2Secure coding-c-preprocessor-2
Secure coding-c-preprocessor-2
 
Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1
 
Linux blue borne-vulnerabilities
Linux blue borne-vulnerabilitiesLinux blue borne-vulnerabilities
Linux blue borne-vulnerabilities
 
Sha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeup
 
화이트 박스 암호기법
화이트 박스 암호기법화이트 박스 암호기법
화이트 박스 암호기법
 
Dll 하이재킹
Dll 하이재킹Dll 하이재킹
Dll 하이재킹
 
Frida tutorial 1
Frida tutorial 1Frida tutorial 1
Frida tutorial 1
 
C 프로그램 메모리 구조
C 프로그램 메모리 구조C 프로그램 메모리 구조
C 프로그램 메모리 구조
 
암호 기법의 소개
암호 기법의 소개암호 기법의 소개
암호 기법의 소개
 
문자열이란 무엇인가
문자열이란 무엇인가문자열이란 무엇인가
문자열이란 무엇인가
 

윈도우 커널 익스플로잇

  • 1. Windows-Kernel-Exploit 1. 개요 1.1. 왜 터널인가. 난이도가 높다. DEP, ASLR, UAC, Heap checks, Protected Mode, Sandboxes 등을 유저 모드에 도입하여 유저 모드와 난이도가 비슷하 거나 오히려 더 쉬울 수도 있다. 유저 모드 보안과 병행한 많은 OS 기능이 커널로 이동하여 새로운 사용자 - 커널 인터페이스가 도입된 후 커널의 공격 영역이 크게 증가했다. 1.2. 무엇이 다른 가 잘못하면 블루스크린이나 시스템 재부팅으로 이어질 수 있다. 사용 권한에 대해 걱정할 필요가 없다. 더 많은 지식이 필요하다. 프로세스 경계가 없으므로 더 많은 것을 해볼 수 있다. 1.3. 필요 배경지식 Kernel APIs Memory Layout Interrupts, IRQLs, DPCs, IRPs Synchronization: Events, Spinlocks, Mutexes, Timers, Semaphores, Resources Paging mechanism Intel System Architecture Device Driver structure, MJ functions, IOCTLs 1.4. 취약점 연구 먼저 하이 레벨 접근법부터 시작하자 복잡한 로직을 찾는다. 서로 다른 팀의 협력이 필요한 인터페이스가 취약하다(예를 들어 사용자와 커널 간의 상호 작용이 필요한 부분) Remote 취약점보다 권한 상승이 더 쉽다. 여러 약한 공격이 하나의 강력한 공격으로 구성될 수 있다. 2. 본론 2.1. 취약점 발견을 위한 세 가지 접근법
  • 2. 1. 하이 레벨 접근법 전체 시스템의 동작 과정을 이해하고 취약한 부분을 찾는다. 2. 로우 레벨 접근법 복잡해보이는 함수를 찾고 분해하며 버그를 찾는다. 3. 퍼징 접근법(블랙 박스 / 무차별 대입) 가능한 모든 유형의 값을 삽입하여 충돌을 유발시키고 충돌 정보를 살펴본다. 2.1.1. 하이 레벨 접근법 사용자 가이드, 레퍼런스 문서, 버그 리포트 등 분석 대상에 대해서 알 수 있는 정보들을 숙지한다. “이 기능을 개발하려면 어 떻게 해야할 까”를 고민하며 발생 가능한 보안 위협에 대한 항목을 설정하고 해당 코드를 검색한다. 2.1.2. 로우 레벨 접근법 코드에서 논리적으로, 기술적으로 복잡한 기능이나 연산을 분류한다. 분류한 기능의 코드 분석 혹은 역공학을 통해 버그를 찾 는다. 버그가 발견되면 공격 가능한 방법이 있는 지 파악한다. 2.1.3. 퍼징 접근법(블랙박스/무차별 대입) 모든 코드 내 존재하는 입력 필드를 분류한다. 분류된 입력 필드에서 CRC, Length와 같은 계산된 데이터를 포함하는 구조를 찾는다. 입력 테스트를 진행한다. 잘못 다뤘을 가능성이 있는 입력 사항을 생각 입력을 생성하는 스크립트 작성 퍼징 스크립트 수행 2.2. 버그 2.2.1. Common bugs Buffer overflows (stack and pool) NULL dereference Faulty input validation 2.2.2. Less common bugs Use-after-free Direct calling to User code Logical bugs 2.2.3 Exploit 개발 Exploit 개발을 위해서는 다음에 대한 지식이 필요하다 Constant memory addresses Memory layouts Heaps, Pools, Stacks APIs, Objects CPU
  • 3. Assembly 커널 모드에서는 프로세스 영역이 없으므로 모든 곳을 할 수 있다. 2.3. Example 2.3.1 User-after-free 이미 해제된 오브젝트를 엑티브 오브젝트 링크드 리스트에 유지하는 버그. 오브젝트들이 접근하기 전, 해제된 버퍼에 임의의 데이터를 삽입. 1. 드라이버 버그를 이용하여 CPU 기아현상을(기아현상 : 시스템 부하가 많아서 준비 큐에 낮은 등급 프로세스가 무한정 대기 하는 현상) 발생시켜 다른 오브젝트가 버퍼를 가로채지 못하게 한다. 2. 적절한 크기의 버퍼를 할당하고 데이터를 복사하는 두 번째 드라이브에서 DPC(Deffrred Procedure Call) 코드를 사용한다. 3. 해제된 오브젝트를 사용하는 티켓 드라이버의 코드를 활성화하여 쉘 코드가 실행되도록 한다. 2.3.2 DRM 커널 Exploit은 아니지만 커널과 유저 간 인터페이스 사용의 좋은 예가 된다. - 유저와 커널 사이의 안전하지 못한 인터페이스(서로 다른 팀의 협력이 필요한 인터페이스가 취약하다) 2.3.2.1. 영화 복사 방지 DRM 예시 지정된 컴퓨터 외 다른 컴퓨터에서는 재생되지 않게 하는 DRM 시스템을 예로 알아보자. 조건 모든 영화는 암호화되어 있다. 복호화 코드는 영화 내부에 내장되어 있다. 하드웨어를 기반으로 컴퓨터 별 라이센스가 부여된다. 하드웨어에 접근하기 위해서는 커널 코드가 필요하므로 영화 내 복호화 코드가 드라이버를 호출한 후 사용자 코드를 다시 호출하게 된다. Hook DeviceloControl 1. try … catch 문에서 드라이버 호출 대신 유저 모드 코드를 호출하게 한다. 2. BIOS를 읽거나 하드웨어에 접근하는 경우 예외를 발생시키는 데, 특정 파일에서 내용을 읽어들이는 것으로 예외 처리를 한다. 이를 이용하여 모든 컴퓨터에서 동일한 하드웨어를 인식하도록 속여 동일한 라이센스를 다른 컴퓨 터에서 이용할 수 있게 한다. 2.4. Tip 임의의 데이터 삽입 : 덮어쓰기 좋은 위치 고정 주소가 있는 일반 장소(OS 빌드 별) 콜백 함수 포인터 데이터 세그먼트 변수 GDT / LDT 표 (http://j00ru.vexillium.org/?p=290) Dispatch Table (새로운 OS에서는 차단됨) 우리는 BIOS / 하드웨어 대신 파일에서 데이터를 읽어오는 것으로 예외를 처리 하므로 동일한 하드웨어로 인식 하도록 속여 동일한 라이센스를 사용할 수 있다. 비 고정 주소 추출 Windows Handle Table은 유저 주소 공간에 매핑되어 함수 포인터가 있는 객체에 대한 커널 포인터를 포 함한다. (http://www.mista.nu/research/mandt- win32k-paper.pdf)
  • 4. 1. Kernel window 생성 (win32k가 생성하고 등록한 window 클래스로 커널 안에 window 프로시저가 Menus 및 Tooltips과 같이 있음) 2. Handle Table에서 Kernel window 객체에 대한 포인터를 가져온다. 3. WndProc 포인터를 덮어쓴다. 4. WndProc 포인터를 트리거하는 메시지를 window에 보낸다. 유저 공간으로 전달되는 다른 커널 포인터. 일부 win32k.sys 시스템 호출은 VOID 또는 USHORT로 정의되고 반환 값에서 전체 또는 일부의 커 널 포인트를 노출한다. (http://j00ru.vexillium.org/?p=762) 블루스크린은 끝이 아니다. Exception 이후에 실행되는 많은 코드가 있으며 그 중에는 덮어쓸 수 있는 콜백 함수를 호출하는 경우가 많다. 특 히 ACCESS_VIOLATIONS의 경우 page-fault handler로 먼저 이동하므로 많은 공격 옵션이 존재한다. KeBugCheck 내부에도 덮어 쓸 수 있는 콜백이 존재한다. 컨텍스트를 수정하고 정상 실행를 하는 것은 까다로운 일이지만, 할 수 있습니다. WOW64 processes 64비트 시스템에서 32비트 프로세스를 실행할 때, NtQuerySystemInformation을 호출하려고 하면 리턴된 모든 포인터가 32비트로 잘린다. 내장된 call gate를 사용하여 일시적으로 64비트로 전환하여 NtQuerySystemInformation을 호출 한 다음 32 비트 코드로 돌아와 극복 할 수 있습니다. (자세한 내용은 http://vxheavens.com/lib/vrg02.html 참조) 64 비트 TEB는 gs : 0에 매핑되어 있기 때문에 64 비트를 모두 switching하지 않고 직접 액세스 할 수 있다. 2.5. 커널에서 사용자까지 많은 경우 커널 Exploit은 유저 모드 페이로드 설치 나 유저모드 코드의 실행이 필요하다. 하지만 시스템 권한으로 실행되는 커널에서 유저 모드 코드를 실행한다는 것은 매우 어려운 일이다. 이제 몇 가지 기법과 각 기법의 장단점을 살펴보자. Changing the process token 방법 : 이미 제어하고 있는 프로세스 토큰을 시스템 토큰으로 변경한다. (예를 들어 Exploit을 시작한 프로세스) 장점 : 구현 방법이 쉽고 안정적이다. 단점 : 유저 모드 코드로 모든 까다로운 작업을 수행해야하므로(예를 들어 시스템 프로세스에 코드 삽입) 사용자 API를 후킹하는 백신 프로그램 혹은 보안 프로그램에 취약하다. User-mode APCs 방법 : 시스템 프로세스의 스레드를 대상으로 유저 모드 APC를 준비시킨다. 장점 : 원하는 위치로 바로 이동이 가능하며, 시스템의 모든 프로세스에 삽입이 가능하다. 단점 : Alertable 상태에 있는 스레드만 대상으로 지정할 수 있으며 이를 찾을 수 있는 일반적인 방법은 없다. 스레 드를 Alertable 상태로 강제하는 방법이 있지만, 대기 상태가 중단되고 대기 함수가 중간에 리턴되어 시스템이 불 안정해지거나 충돌을 일으킬 수 있다. 관련 구조에 대한 문서화가 아직 이루어지지 않았으며 OS 버전 마다 차이 가 있다. 그러므로 잘 알고 있는 스레드를 댓ㅇ으로 하지 않는 한, 스레드가 대기 상태(예를 들어 LoaderLock)로 들어갈 때 스레드가 일부 Lock을 holding하고 있으면 이 방법을 사용 시 교착 상태가 발생할 수 있다. Thread Hijacking 방법 : 시스템 프로세스에서 기존 스레드의 컨텍스트를 변경하여 삽입한 코드를 실행한다. 장점 : 원하는 위치로 바로 이동이 가능하며, 시스템의 모든 프로세스에 삽입이 가능하다. 단점 : 컨텍스트 복원이 매우 어려울 수 있다. 임의의 스레드를 Hijacking하는 것은 교착 상태, 불안정성 또는 충 돌을 일으킬 수 있다. Creating a new thread 방법 : 시스템 프로세스에 새로운 유저 모드 스레드를 생성한다. 장점 : 거의 완벽한 해결책으로 어떤 위험이나 컨텍스트 문제 없이 원하는 위치로 정확하게 이동할 수 있으며, 시 스템의 모든 프로세스에 삽입이 가능하다. 단점 : 구현하기가 매우 어렵다. 새 스레드가 작동하려면 CSRSS에 등록해야 한다. API와 구조가 복잡하고 문서 화되어 있지 않으며 Windows 업데이트로 끊임없이 변경되고 있다.
  • 5. API hooking 방법 : 호출될 것임을 알고 있는 유저 모드 API 또는 시스템 프로세스 내에서 호출되도록 할 수 있는 유저 모드 API hooking. 장점 : 시스템 프로세스에 직접 삽입 가능하며 매우 안정적이다. 단점 : 적절한 API를 찾아내는 것이 어렵다. 이 방법은 일반적이지 않고 대상 API를 자주 호출하는 시스템 프로세 스에서만 적합하다. 간단한 커널 Exploit 예제 - AFD.SYS AfdGetRemoteAddress를 살펴보자. 어떤 문제가 존재하는 가. // Attacker controls OutputBuffer and OutputBufferLength void IOCTL_handler(...) { [...] try { ProbeForWrite (OutputBuffer, OutputBufferLength, sizeof (UCHAR)); RtlCopyMemory( OutputBuffer, (PUCHAR)context+endpoint->Common.VcConnecting.RemoteSocketAddressOffset, endpoint->Common.VcConnecting.RemoteSocketAddressLength ); } except( AFD_EXCEPTION_FILTER(&status) ) { } [...] } 힌트 : 실제 포인터와 무관하게 길이가 0인 경우에 대해 ProbeForWrite에서 예외(throw) 처리를 하지 않는다. 우리는 커널 주소를 포함한 원하는 주소에 우리가 원하는 값을 쓸 수 있지만 실제로 제어할 수는 없다. 작성된 데이터는 다음 과 같다. - 02 00 XX XX YY YY YY, 여기서 XXXX는 포트, YYYYYYYY는 IP이다. 함수가 동작하려면 활성 TCP 연결이 있어야한다. 무엇을 해야 하는가? 데이터를 완전히 제어 할 필요가 없는 것은 아닐까. 우리는 127.0.0.1, 즉 7F 00 00 01에 연결할 수 있다. Port 445(01 BD)는 Windows 컴퓨터에서 항상 열려 있다. 01 BD 7F 00 00 01? 인텔은 Little Endian이므로 0x00007FBD가 된다. 이제 덮어 쓸 포인터가 필요하다. 이것은 XP에서만 작동하는 오래된 버그이 므로 Dispatch Table을 사용할 수 있다. Exploit 1. 0x7fb0에 페이지를 할당하고 쉘코드를 복사한다. 2. HookAddress = ZwQueryIntervalProfile에 대한 Dispatch Table entry 3. 127.0.0.1:445에 연결(connect()). 4. DeviceIoControl(HANDLE)sock, 0x1203F, NULL, 0, (PVOID)(HookAddress - 3), 0, &Result, NULL) 5. ZwQueryIntervalProfile() Background Window Class를 등록할 때, OS에게 윈도우 객체와 함께 Extra Bytes를 저장하도록 요청할 수 있다. Extra Bytes는 커널 의 WND Struct에 추가된다. ​ |WND Struct|Extra Bytes| 일부 window types(Menus, Tooltips)는 커널에서만 접근할 수 있는 private data가 있다. ​ |WND Struct|PrivateData|Extra Bytes| Extra bytes의 데이터를 변경하기 위해서 value와 Extra Bytes index와 함께 SetWindowLongPtr 함수를 호출한다. 함수는 제공된 index가 private data 또는 user extra bytes에 속하는 지 확인한다. 만약 private bytes에 속한다면 함수
  • 6. 가 실패하므로, private 커널 데이터를 변경할 수 없다. ​​ |WND Struct|(X)PrivateData|Extra Bytes| SetWindowLongPtr 함수는 전체 allocated bytes size(WND struct + private)가 있는 window types Table을 사용하여 private data 내에 속하는 지 확인한다. “Window type”은 하드 코딩된 값 목록(해당 클래스가 아닌)에서 window type 의 실제 식별자인 FNID를 나타낸다. 확인을 위한 pseudo code는 다음과 같다. if (index < (int)(window_class_alloc_sizes[fnid]-sizeof(WND)))) FAIL; Window Type(FNID) allocated bytes Menu 0xa4 (WND size) + 4 (private bytes) == 0xa8 Tooltip 0xa4 (WND size) +4 (private bytes) == 0xa8 The bug.part1 문서화되지 않은 unexported 함수인 RegisterClassExWOWW에 internal window type과 extra bytes에 대해 음수를 사용하면 테이블을 임의의 값으로 덮어쓰는 것이 가능하다. 이 버그는 extra bytes 값을 검증하지 않아서 발생한다. ​Window Type(FNID) allocated bytes Menu 0xa4 (WND size) + (-0xa8) (private bytes) == -4 Tooltip 0xa4 (WND size) +4 (private bytes) == 0xa8 할당된 바이트 수를 음수로 덮어쓴 테이블을 사용하면 검증 로직 우회가 가능하다. (index < (int)(window_class_alloc_sizes[fnid]-sizeof(WND)))) == always FALSE 우리는 이를 이용하여 인덱스를 0으로 설정하고 SetWindowLongPtr함수를 호출하여 window private kernel data를 수정할 수 있다. |WND Struct|(V)Private Data|Extra Bytes| The bug.part2 이제 private kernel data에서 덮어썼을 때 유용하게 사용할 수 있는 window type을 찾아야 한다. Menu window type은 구조체에 대한 포인터를 저장하고 window가 제거된 동안 해당 구조체의 포인터가 NULL로 설정되어 시스템의 32/64 비트 값을 NULL로 지정할 수 있습니다. (Bingo!) Menu window private 구조는 윈도우즈 버전에 따라 변경되므로 우리는 Exploit을 두번 수행한다. 포인터가 non-NULL인 배열의 포인터를 가진 구조체에 처음 덮어 쓰므로 NULL이 있는 offset을 찾을 수 있다. 두 번째로 NULL에 삽입할 주소를 가진 포인터와 첫 번째 단계에서 발견 된 offset을 뺀다. 이제 쉘 코드를 페이지 0에 할당하고 함수 포인터를 덮어 쓴 후 호출한다. Flow 1. Find the address of RegisterClassExWOWW using diStorm 2. RegisterClassExWOWW() passing the FNID for a Menu and a WNDCLASSEX structure with a negative number for the extra bytes 3. CreateWindow() 4. SetWindowLongPtr() with a non-NULL array 5. DestroyWindow() 6. Find offset 7. Repeat steps 3-5, this time passing the actual address to overwrite minus the offset 8. Get the overwritten pointer to be called 2.6. Windows8 특징
  • 7. Null-dereference is blocked – first 64k can’t be allocated New integrity checks to the kernel pool memory allocator (see http://blogs.msdn.com/b/b8/archive/2011/09/15/protecting-you-from-malware.aspx) Improved Linked-Lists security to protect against corrupted/dangling list pointers (see http://www.alex- ionescu.com/?p=69) 본문에서 사용된 Kernel Exploit POC Code : ExploitDB