2022. 8. 19. 02:20ㆍPWN
Ubuntu 22.04 (glibc-2.36)까지 업데이트가 되면서 tcache에 관한 취약점들을 보완하기 위해 여러코드가 추가되었다.
지난주에 있었던 corCTF의 cshell2문제를 푸는 과정에서, 문제에 사용된 libc가 22.04버전에서 사용되는 libc였기때문에 tcache에 관해 공부를 해야했다. 구글에서는 찾기가 어려워서 직접 코드를 통해 알아보았다.
(보호기법 명칭을 알고나니 검색되는 글이 있어서 슬펐다... 어쨌든 삽질은 좋은거야 좋은거)
알아낸 최신 tcache 보호기법을 라이트업에 함께 적으려고하니 너무 길어지기도 했고, 최신 tcache에 대해 정리된 글이 아직 많지 않은것같아서 블로그에 따로 어설프게나마 정리를 해보려고한다.
우선 문제 해결 과정에서 알아낸 것들만 정리해두었는데, 이후 새롭게 더 알게되는것이 있으면 추가할 예정이다.
참고된 코드는 아래 링크에서 확인할 수 있다.
버전별로 코드가 약간씩 다르지만 가장 최신버전인 2.36으로 분석을 진행하였다.
https://github.com/bminor/glibc/blob/glibc-2.36/malloc/malloc.c#L3191
tcache_key
(cshell2 문제를 푸는데 사용하진 않았다. 랜덤바이트가 tcache next주소 뒤에 들어가있어서 궁금해서 찾아보았다.)
보호기법 중 스택쿠키, canary와 비슷하게 생겨서 코드를 보고 정확한 명칭을 알기 전까지는 tcache cookie라고 불렀었는데, 공부를 하고 보니 key개념에 가깝긴하다.
glibc-2.33에서 double free를 막기 위해 처음 추가된 보호기법이다.
주석을 통해 동일 스레드에 더블프리가 발생했는지 예외처리를 하는, 프로세스 전체에 작용하는 키라는 것을 알 수 있다.
tcache_entry라는 구조체에 key가 들어가고, key는 key_initialize함수를 통해 랜덤비트가 생성된다.
키 초기화함수에서는 random_bits함수가 4바이트 랜덤비트를 생성한다. 이때 64비트일 경우 앞서 생성된 4바이트짜리 랜덤비트를 left shift로 8자리 밀고, or 연산자로 다시 random_bits함수로 생성된 새로운 4바이트 랜덤비트를 연결한다.
아래는 tcache에 2개가 free되어있을 때 본 메모리 상태이다. 0번 tcache에는 다음 tcache의 주소 (빨간색 상자)와 tcache key (노란색 상자) 가 들어있다.
위에서 생성된 key는 아래와 같이 사용된다.
tcache_put함수에서는 chunk를 free시켰을 때 chunk의 key자리에 tcache_key값을 넣는다.
tcache_get함수에서는 free되어 tcache에 있는 chunk를 재사용할 때 key값을 0으로 변경시킨다.
위 소스코드는 chunk를 free할 때 사용된다. free하려는 chunk의 key 자리있는 값이 tcache_key와 같으면 double free detected 에러를 반환하고 프로그램을 중단한다.
tcache_put함수로 인해 tcache로 free된 청크에는 tcache key값이 있기때문에 double free를 감지한다.
정리하면, double free를 막기 위한 보호기법은 tcache key값을 덮어 변경할 수 있다면 우회가 가능하다. (UAF, heap overwrite 등)
다른 보호기법도 한번에 적으려고했는데 너무 길어져서 글을 분리하기로했다.
'PWN' 카테고리의 다른 글
System Hacking) Safe Linking - tcache 암호화 / tcache align (0) | 2022.08.19 |
---|