LIBC in Ubuntu 18.04

juuun0·2022년 1월 24일
1
post-thumbnail

Overview

Ubuntu 18.04에서 발생하는 매우 특이한 현상과 이 글을 쓰게 된 이유에 대해 간략하게 정리하였습니다. 어디까지나 기록용으로 작성한 것이기에 정확한 내용은 아닐 수 있습니다.


Tcache

glibc 2.27 중에서도 다룰 세부 내용은 tcache와 관련된 내용입니다. Tcache는 glibc 2.26에서 추가된 새로운 heap 관리 방식으로 관리 속도에 있어서 큰 이점이 있습니다.

해제된 heap 공간을 관리하기 위해 tcache_entry 라는 구조체를 사용하며 구조는 아래와 같습니다.

typedef struct tcache_entry
{
  struct tcache_entry *next;
} tcache_entry;

특별히 double free를 check 하기 위한 구문이 없고 Self-Referential Structure만 존재하는 것을 확인할 수 있습니다. 이를 방지하기 위한 내용은 glibc 2.29에서 패치되었으며 그 내용은 다음과 같습니다.

typedef struct tcache_entry
{
  struct tcache_entry *next;
  /* This field exists to detect double frees.  */
  struct tcache_perthread_struct *key;
} tcache_entry;

기존 tcache_entry 구조체에서 struct tcache_perthread_struct *key; 항목이 추가되었으며, 만약 해제하고자 하는 heap이 이 값을 가지고 있다면 error handleing을 통해 프로그램을 종료합니다.

여기까지의 내용을 종합하자면 glibc 2.26 ~ 2.28에서는 아주 쉽게 double free가 가능하며 glibc 2.29 이후부터는 조건을 만족할 필요가 있다는 것이 됩니다.


Patch

그러나 이론대로 완벽했다면 이 글을 쓰고 있을 이유가 없듯 한 가지 변수가 발생했습니다.

 typedef struct tcache_entry
 {
   struct tcache_entry *next;
+  /* This field exists to detect double frees.  */
+  struct tcache_perthread_struct *key;
 } tcache_entry;

위 내용은 Link의 내용 중 tcache_entry 부분을 발췌한 것 입니다. 요약하자면 기존엔 glibc 2.29 이상 버전에 존재하였던 double free check 구문이 glibc 2.27 이후 버전에도 추가되었다는 것 입니다.

이로 인해 Link와 같은 상황이 발생할 수 있었습니다. 이를 해결하기 위해서는 먼저 사용하는 libc의 동작을 확인한 뒤 libc의 수정 혹은 Double Free Check를 우회하는 payload의 구성이 있을 것 같습니다.


Reference

profile
To be

0개의 댓글