Computer Security

#12 SSP 우회 본문

리눅스 커널 해킹

#12 SSP 우회

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

SSP(Stack Smashing Protector)

 

 

make 과정에서 사용되는 gcc의 옵션으로써, stack based buffer overflow를 방지하는 보호 기법이다.

 

스택에 랜덤한 canary값을 배치하여, 이 canary가 오염될 경우 overflow가 발생한 것으로 판단하여 커널 패닉이 발생한다.

 

gcc의 옵션으로써 자동으로 활성화 되기 때문에, 유저 공간의 SSP와 동일한 보호 기법이다.

 

 

 


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

ssp_bypass

start.sh : qemu script

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

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

 

 


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

test.c

 

 

test_read() 함수

 

copy_to_user 함수를 이용해 원하는 크기의 커널 데이터를 유저 공간으로 전달하는 역할을 한다.

 

kbuild에 의해 컴파일 과정에서 SSP(canary) 보호 기법이 자동으로 적용된다.

 

 

 

 

test_write()함수

 

copy_from_user 함수를 이용해 유저로부터 원하는 크기의 데이터를 전달 받은 뒤, 지역변수 arr에 복사하는 역할을 한다.

이로인해 스택버퍼오버플로우 취약점이 터지게된다.

 

SMAP 우회때,  test.c 예제와 동일한 함수이다.

 

 

 

 


2. exp.c 파일을 살펴보자.

exp.c

canary leak

 

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

밑줄을 보면, read()(1)함수를 이용해 test 드라이버의 arr 지역 변수로부터 16byte의 데이터를 읽어 오는것을 알 수 있다.

 

test.c에서 보았듯, arr의 크기는 8byte이므로 8byte 만큼 overflow된 데이터까지 읽어오게 된다.

 

이 overflow된 8byte크기의 데이터가 바로 canary 값이다!!

 


 

kernel ROP

ROP payload는 commit_creds(prepare_kernel_cred(0)) 코드를 실행한 후, /bin/sh 를 실행하는 역할을 한다.

 

ROP payload 중간에 test 드라이버에서 canary가 위치하게 될 16byte 부분에 leak한 canary 데이터를 배치하여 이로인해, 스택버퍼오버플로우는 발생했지만, canary 값은 오염되지 않았기 때문에, kernel panic이 일어나지 않고, SSP를 우회할 수  있게 된다.

 

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

 

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

 

 

 

 

 

 

(1) read(int fd, void* buf, size_t len) :  fd(파일 디스크립터) 가 참조하는 현재 '파일 오프셋'에서 len 바이트 만큼 buf 로 읽어 들인다. 만약, 읽어드릴 데이터가 없는데 read()를 호출한다면 프로그램은 '블럭(Block)'된다.

호출성공 : buf에 쓴 바이트 숫자를 반환한다.

호출실패 : -1을 반환하여 'errno'를 설정한다.

 

 

 


3. start.sh 를 실행해서 살펴보자.

start.sh

start.sh 를 실행한 후, exp를 실행한 결과이다.

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

 

 

 

 

 

canary leak 전체적인 흐름

 

 

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

 

 

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

--> 유저공간 write(fd,canary,sizeof(canary))   --> 커널공간 test_read() 

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

 

 


 

leak 한 canary값을 이용해 권한상승 전체적인 흐름

 

 

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

 

 

커널 공간 copy_to_user(buf,ptr,count)   -->  유저공간 rop[i++] = canary[1] 

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

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

 

 

 


SSP 우회 방법

 

 

지금까지의 실습처럼 OOB등의 information leak 취약점을 이용해 canary 값을 leak하면 된다.

 

canary leak을 하고 난 뒤, ROP payload에 canary 값을 추가하면 우회가 가능하다.

 

반응형

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

#14 ret2usr 기법  (0) 2022.08.22
#13 KPTI 우회  (0) 2022.08.21
#11 KADR 우회  (0) 2022.08.19
#10 SMAP 우회  (0) 2022.08.18
#9 SMEP 우회  (0) 2022.08.17
Comments