Computer Security

#10 SMAP 우회 본문

리눅스 커널 해킹

#10 SMAP 우회

쿠리 Kuri 2022. 8. 18. 18:30
반응형

SMAP(Supervisor Mode Access Prevention)

 

 

 커널 공간에서 유저 공간에 대한 읽기/쓰기 권한도 제한하는 보호기법이다.

실행 권한만 제한하는 SMEP에서 더 강화된 보호 기법이며, 유저 공간으로의 엑세스 자체를 제한한다.

SMEP와 마찬가지로 cr4레지스터에 SMAP를 on/off 하는 제어 비트가 있다.

kernel ROP만으로 우회할 수 있는 SMEP와 달리 우회 방법이 다양하며, 다소 복잡한 편이다.

 


우리는 아래의 파일들로 실습 할 것이다.

smap_bypass

 

nosmap.sh : SMAP를 적용하지 않은 qemu script

smap.sh : SMAP을 적용한 qemu script

test.c : 간단한 취약점이 터지는 디바이스 드라이버 예제

exp.c : 취약점을 이용해 권한 상승을 일으키는 exploit code

 

 


1. 커널의 흐름을 원하는 대로 조작할 수 있는 디바이스 드라이버 예제인 test.c 를 살펴보자.

test.c

BOF 취약점을 이용해 커널의 흐름을 원하는 대로 조작할 수 있는 디바이스 드라이버 예제이다.

test_write() 함수에서 copy_from_user 함수를 이용해 유저로부터 원하는 크기의 데이터를 전달 받은 뒤, 지역 변수 arr에 복사하는 것을 볼 수 있다.

kbuild 옵션을  통해 스택버퍼오버플로우를 방지하는  SSP(canary) 보호 기법을 제외한 뒤에 컴파일 했기 때문에, BOF가 발생해도 kernel panic이 일어나지 않는 예제 드라이버이다.

 

 

 


2.test 드라이버에서 터지는 취약점을 이용해 권한 상승을 일으키는 exploit code 인 exp.c 코드를 분석 해보자.

exp.c

test 드라이버에서 터지는 취약점을 이용해 권한 상승을 일으키는 exploit code이다.

write()함수를 이용해 test 드라이버에 ROP payload(1)를 전달한다.

 

전체적인 흐름은 kernel ROP 기법을 이용한다.

 

 

 

(1)  payload함수:  commit_ceds(prepare_kernel_cred(0)) 코드를 실행한 후, /bin/sh 를 실행하는 역할이다.

 

 

 


3. nosmap.sh 실행을 하여 실습 해보도록 하자.

./nosmap.sh

SMAP 보호 기법을 적용하지 않은 nosmap.sh를 실행한 후, exp를 실행한 결과이다.

 

test 드라이버의 취약점을 이용해 user 권한에서 root권한을 획득 한 것을 볼 수 있다.

 

 

 

전체적인 흐름

 

 

커널공간 : test.c     ,      유저공간 : exp.c

 

 

커널 공간 misc_register(&test_driver)   -->  유저공간 fd=open("/dev/test", O_RDWR) 

--> 유저공간 write(fd,&rop,sizeof(rop))   --> 커널공간 test_write() 

--> 커널공간 copy_from_user(ptr,buf,count)  -->  커널공간 memcpy(arr,ptr,count)

 

 

 


4. SMAP 기법이 적용된 smap.sh를 실행 해보자.

./smap.sh

SMAP 보호기법을 적용한 smap.sh를 실행한 후, exp를 실행한 결과이다.

 

이전 nosmap.sh의 경우와 마찬가지로 user 권한에서 root 권한을 획득 한 것을 볼 수 있다.

 

stack based BOF 취약점을 통해 kernel ROP를 작성하는 경우, 익스플로잇이 진행될 때 유저 공간에 대한 엑세스가 일어나지 않기 때문이다.

 

test_write()함수에서 BOF가 터져서 ROP payload를 실행하게 됐는데, ROP payload자체가 위치한 것도 kernel 영역의 스택이며,  ROP payload의 멤버들도 kernel 영역의 코드들 이기 때문에, 유저 공간의 엑세스가 전혀 일어나지 않았다.

 

따라서, nosmap와 마찬가지로 root권한을 얻게 된 것이다!

 

 

 


5. SMAP 우회방법 

 

SMAP를 쉽게 우회할 수 있는 상황은 두가지 정도가 있다.

 

1. 방금 실습한 것과 같이 stack based BOF 취약점이 터지는 경우, SMEP를 우회하는 것과 마찬가지로 단순히 kernel ROP만 작성해도, 익스플로잇이 진행되는 과정에서 유저 공간에 대한 엑세스가 없기 때문에 SMAP우회가 가능하다.

 

2. 원하는 slab 객체 크기의 UAF(1) control이 가능할 경우, 유저 공간에서 forkl()를 호출 시 커널 힙에 할당되는 cred 구조체의 멤버를 수정할 수 있으며, 이를 통해 SMEP와 SMAP 우회가 가능하다.

 

3.만약 커널에 kernel heap pointer(slab pointer)를 leak 할 수 있는 취약점이 있다면, kernel heap spray 기법과 연계해서 수 많은 공격 시나리오를 짤 수 있다.

 

 

 

 

 

 

(1) UAF

 

Memory Corruption (메모리 오염)

  • 메모리를 참조하는 부분에서 오류가 발생해 생기는 취약점이다.
  • 공격자는 메모리가 Corruption 되는 부분을 이용해 공격자가 원하는 명령어를 참조하도록 수행 가능하다.

이제 Memory Corruption의 정의를 알았다면 한 가지 더 메모리 구조에 대해 이해가 필요하다.

UAF는 Heap 영역에서 일어나는 취약점이며 Heap은 메모리 영역 중 하나이기에 메모리 구조를 알아야 한다.

 

 

간단하게 설명하자면, 일단 프로그램이 실행되면 실행에 필요한 정보들이 Memory 영역에 올라가게 되는데, 크게는 Code 영역, Data 영역, Stack영역, Heap 영역이 있다.

 

Code 영역 : 프로그램의 코드가 올라가는 곳이다. 코드란, 컴파일된 기계어 코드이다.

 

Data 영역 : Global Variable과 Static Variable이 할당되는 곳이다. 
                ( 초기화 된 Data -> Data 영역 , 초기화되지 않은 데이터 -> bss 영역에 구분되어서 저장된다. )

 

Stack 영역 : Local Variable과 Parameter가 저장되는 곳이다. 함수가 시작되면 해당 함수의 Local Variable이 스택에 저장되었다가 함수가 종료되면 해당 영역을 해제시킨다.

 

Heap 영역 : 빈 공간이다. 필요에 따라 동적으로 메모리를 할당하기도 하고 해제하기도 한다.


Heap 영역은 Stack에서 관리하는 이외의 데이터 형태를 사용하며, 컴파일 시 크기를 알지 못하다가, 프로그램이 실행되었을 때 크기가 결정되는 동적 할당 메모리를 받는 데 사용된다.

 

 

 

 

Use After Free (UAF) 

  • 줄여서 UAF라 부른다.
  • Heap 영역에서 할당된 (malloc  ) 공간을 free로 영역을 해제하고, 메모리를 다시 할당 시 같은 공간을 재사용 하면서 생기는 취약점이다.

 

 

 

 

반응형

'리눅스 커널 해킹' 카테고리의 다른 글

#12 SSP 우회  (0) 2022.08.20
#11 KADR 우회  (0) 2022.08.19
#9 SMEP 우회  (0) 2022.08.17
#8 KASLR 우회  (0) 2022.08.16
#7 리눅스 커널 보호 기법  (0) 2022.08.15
Comments