trash houz
[Linux Kernel] CISCN 2017 babydriver 본문
- 분석
device 파일 open() 시에 실행되는 함수.
전역 변수. bss영역에 babydev_struct라는 구조체가 있고, 구조체 변수중 device_buf에 64바이트만큼 동적 할당해준다.
이후 구조체 변수 device_buf_len에 크기까지 저장.
여기까지 open() 완료
close() 통해 디바이스를 종료하면 실행되는 babyrelease() 함수.
babydev_struct 구조체의 device_buf를 참조하여 kfree() 해버린다.
다만 따로 전역변수 .bss 영역을 초기화하지는 않는다.
만약 디바이스를 두개 열게 되면 두 개의 디바이스는 똑같은 babydev_struct 구조체를 가리킨다.
이렇게 된다면 free() 후에도 참조할 수 있는 UAF 취약점이 발생하게 된다.
babyopen()에서 동적 할당했던 공간을 babyioctl()을 통해 원하는 크기로 재할당 할 수 있다.
재 할당만 해주고 별다른 동작은 하지 않는다.
- 공격전 필요한 지식
UAF 취약점을 어떻게 활용해서 권한상승을 노릴것인가 ...
babyioctl() 을 통해 원하는 크기로 재할당 할수 있다는점을 이용해야한다.
또한 fork(), kmem_cache 등에 대한 지식도 있어야한다.
리눅스 에서 fork() 를 호출하면 시스템콜 clone() 을 사용하여 처리가 된다.
다시 clone() 내부에서는 do_fork() 를 호출한다.
이는 kernel/fork.c 에 정의되어있다.
do_fork() 내부를 보게되면 copy_process() 를 사용하여 복사를 진행한다.
다시 copy_process() 내부를 살펴보자.
copy_process( ) 내부를 살펴보면 task_struct 를 인자로 copy_creds() 를 호출한다
따라가 copy_creds() 를 살펴보자.
copy_creds() 내부에서는 prepare_creds() 를 호출한다....
그만 알아보고 싶지만 계속 따라가보자....
prepare_creds() 는 kmem_cache_alloc() 을 호출한다.
여기까지 쭈욱 따라온 결과
fork() -> clone() -> do_fork() -> copy_process() -> copy_creds() -> prepare_creds() -> kmem_cache_alloc()
이렇게 이어져 온다는걸 알수있따.
아무튼 fork() 를 호출하면 기존 cred 를 복사할 공간이 필요할것이다.
그래서 내부에서는 kmem_cache_alloc() 통해 이미 잘려진 메모리를 가져온다.
cred 구조체의 총 크기는 168 바이트이다.
만약 위에서 babyioctl() 을 통해 168 바이트 만큼을 재 할당한뒤 kfree() 를 한 상태라면, 이 메모리를 가져와 저장할것이다.
UAF 취약점까지 있어 그곳을 참조하여 write() 까지 할수 있으니 권한 상승이 가능하다 !
'Writeup' 카테고리의 다른 글
[Linux Kernel] 0CTF 2018 FINAL BABY (0) | 2019.08.23 |
---|---|
[Linux Kernel] CSAW-CTF 2015 stringIPC (0) | 2019.08.05 |
[Linux Kernel] STARCTF 2019 hackme (0) | 2019.08.02 |