free
함수로 청크를 해제하면, ptmalloc2는 이를 tcache나 bins에 추가하여 관리한다.
이후malloc
으로 비슷한 크기의 동적 할당이 발생하면, 이 연결리스트를 탐색하여 청크를 재할당해준다.해커들은
free
로 해제한 청크를free
로 다시 해제했을 때 발생하는 현상에 주목
- free list(tcache, bins) 관점에서
free
는 청크를 추가하는 함수,malloc
은 청크를 꺼내는 함수- 임의의 청크에 대해
free
를 두 번 이상 적용할 수 있다는 것은, 청크를 free list에 여러 번 추가할 수 있음을 의미 (duplicated)- duplicated free list를 이용하면 임의 주소에 청크를 할당할 수 있다.
- 이렇게 할당한 청크의 값을 읽거나 조작함으로써 임의 주소 읽기/쓰기가 가능하다.
같은 청크를 두 번 해제할 수 있는 버그
→ 공격자에게 임의 주소 읽기/쓰기, 임의 코드 실행, 서비스 거부 등의 수단으로 활용
- free list의 각 청크들은
fd
(이후)와bk
(이전)로 연결- 해제된 청크에서
fd
와bk
값을 저장하는 공간은 할당된 청크에서 데이터를 저장하는 데 사용- 어떤 청크가 free list에 중복해서 포함된다면, 첫 번째 재할당에서
fd
와bk
를 조작하여 free list에 임의 주소를 포함시킬 수 있다.- 최근에는 이에 대한 보호 기법이
glibc
에 구현
정적 패치 분석
tcache에 도입된 보호 기법을 분석
tcache_entry
tcache_entry
는 해제된 tcache 청크들이 갖는 구조
double free를 탐지하기 위해key
포인터가tcache_entry
에 추가되었다.
일반 청크의fd
가next
로 대체되고, LIFO 구조이므로bk
에 대응되는 값은 없다.tcache_put
tcache_put
은 해제한 청크를 tcache에 추가하는 함수
해제되는 청크의key
에tcache
라는 값을 대입하도록 변경되었다.
tcache
는tcache_perthread
라는 구조체 변수를 가리킨다.tcache_get
tcache_get
은 tcache에 연결된 청크를 재사용할 때 사용하는 함수
재사용하는 청크의key
값에 NULL을 대입하도록 변경되었다._int_free
_int_free
는 청크를 해제할 때 호출되는 함수
재할당하려는 청크의key
값이tcache
이면 Double Free로 보고 프로그램을 abort 시킨다.동적 분석
- 청크 할당 직후의 heap의 모습
malloc(0x50)
으로 생성된chunk
주소 → 0x555555559290- 청크 해제 직후 청크의 메모리
key
값이 0x555555559010으로 설정되었다. 이를 조회해보면
entry에chunk
의 주소인 0x5555555592a0이 포함되어 있다.- 따라서 abort가 발생한다.
Double Free Bug가 발생하여chunk
가tcache
에 중복 연결되어 연속으로 재할당된다.
원래라면 abort 되어야 하지만, 강제로 key값을 변경하였기 때문에 정상 실행되었다.*(char *)(chunk + 8) = 0xff; // manipulate chunk->key