trash houz
[Linux Kernel] CSAW-CTF 2015 stringIPC 본문
CSAW CTF 2015에서 출제된 stringIPC라는 Kernel Exploitation 문제이다.
로드되어있는 모듈은 IPC를 통하여 통신할 수 있는 기능을 제공하며 새로운 IPC 채널을 생성, 찾기, 크기 변경 등이 가능하다.
각 채널은 생성 시 채널 ID 와 버퍼가 커널 메모리에 할당되고, 버퍼에 내용을 쓰거나 수정, 버퍼크기 변경 등이 가능하다.
문제 출제시 소스코드를 제공했으므로 IDA로 분석하는 참극은 일어나지 않도록 하자.
https://github.com/mncoppola/StringIPC/blob/master/main.c
CSAW_ALLOC_CHANNEL
CSAW_OPEN_CHANNEL
CSAW_GROW_CHANNEL
CSAW_SHRINK_CHANNEL
CSAW_READ_CHANNEL
CSAW_WRITE_CHANNEL
CSAW_SEEK_CHANNEL
CSAW_CLOSE_CHANNEL
이러한 기능들이 있는데, 취약점은 GROW, SHRINK에서 터진다.
일단 하나씩 알아보도록 하자.
CSAW_ALLOC_CHANNEL
특별한 것은 없고 ipc 채널을 새로 생성해주는 동작을 한다.
mutex를 사용해 lock, unlock 해주는 과정이 코드 전후반에 있지만, 문제에 큰 영향을 주지는 않는다.
alloc_new_ipc_channel이라는 함수를 다시 호출해 실제 채널 생성을 하는데, 한번 살펴보자.
채널 정보에 관한 구조체를 위한 공간을 kzalloc()으로 동적 할당하고,
실제 data 를 담을 공간을 인자로 넘겨받은 buf_size 만큼 동적 할당한다.
마지막으로 idr_alloc() 을 통해서 id 번호를 생성한다.
CSAW_OPEN_CHANNEL
이미 생성된 채널을 오픈하는 파트인데, 이 문제에서 별로 중요하진 않다.
간단하니 넘어가도록 하겟당.
CSAW_GROW_CHANNEL, CSAW_SHRINK_CHANNEL
이 부분에서 취약점이 터지게 된다.
정확하게 말하면 이 파트에서 호출하는 realloc_ipc_channel에서 문제가 터진다.
GROW는 말 그대로 늘려주는 애고, SHRINK는 줄여주는 애다.
동작을 보면 일단 id로 채널 정보를 불러온 뒤에, grow 값이 있으면 size 만큼 늘리고 값이 없다면 줄여 버린다.
이런 과정들을 krealloc() 이 처리해주는데, 사용자가 입력한 값만큼 더해서 재 할당을 하고 기존 공간은 free 한 뒤에
새로 할당된곳의 주소를 리턴해준다.
만약 할당에 실패를 하면 기존 공간을 free 하지 않고 NULL을 리턴하게 된다.
이 때문에 코드에서는 NULL로 에러 처리를 한 것 같은데, krealloc() 은 특정 조건으로 실패할 경우 NULL을 리턴하지 않는다.
그렇다... 리턴 값이 무조건 NULL 이 아니라 ZERO_SIZE_PTR(16)을 리턴할 수도 있다.
이렇게 되면 data의 주소를 16으로 바꿔 메모리를 읽어 온 뒤 comm을 찾아 cred를 바꾸는 짓이 가능해진다.
위 내용에 관한 자세한 설명은 아래 링크를 참조해보도록 하자.
https://applemasterz17.tistory.com/222
'Writeup' 카테고리의 다른 글
[Linux Kernel] 0CTF 2018 FINAL BABY (0) | 2019.08.23 |
---|---|
[Linux Kernel] CISCN 2017 babydriver (0) | 2019.08.20 |
[Linux Kernel] STARCTF 2019 hackme (0) | 2019.08.02 |