2
발표자 소개
성균관대학교2학년 재학 중
성균관대학교 정보보호 동아리 HIT 회장
Best of the Best 4기 취약점 분석트랙 수료
2016-08-
15
성균관대학교 H.I.T
3.
3
목차
What isHeap?
Why Heap?
Who Controls Heap?
How2heap?
정리
2016-08-
15
성균관대학교 H.I.T
4.
4
What is Heap?
힙 메모리란?
프로그램에서 사용할 수 있는 자유 메모리. 프로그램 실행 시에 함수로 보
내는 데이터 등을 일시적으로 보관해 두는 소량의 메모리와 필요시 언제
나 사용할 수 있는 대량의 메모리가 있다. 이때, 소량의 메모리를 ‘스택’이
라 하고 대량의 메모리를 ‘힙’이라 한다.
네이버 용어사전 -http://terms.naver.com/entry.nhn?docId=863311&cid=50371&categoryId=50371
malloc을 통해 동적 할당한 메모리들.
성균관대학교 H.I.T
7
Who Controls Heap?
MemoryAllocator라고 불리는 프로그램이 힙 메모리를 관리함
각자 자신들만의 알고리즘을 가지고 최대한 좋은 memory allocator 를 구현
함.
dlmalloc – General purpose allocator
ptmalloc2 – glibc
Jemalloc – FreeBSD and Firefox
tcmalloc – Google
libumem – Solaris
MemGC – Edge Browser
2016-08-
15
성균관대학교 H.I.T
8.
8
Who Controls Heap?
생각보다 malloc은 처리해야 할 것들이 많음.
단편화 (Fragmentation)
Thread Safety
성능 향상
- Byte Align 등등.
2016-08-
15
성균관대학교 H.I.T
10
Who Controls Heap?
Malloc에서 사용되는 자료 구조
Heap --- 큰 메모리 덩어리들을 지칭
Chunk --- 각각 malloc 된 조각들을 지칭
OS에서 Heap이라는 덩어리를 가져다 조금씩 나눠주는 것을 구현한 코드
P.S ) 이해를 돕기 위해 앞으로 나오는 구조체는 실제 구현된 것과는 다를 수 있습니
다. 개념을 설명하는데 중점을 두었고, x86 기준 입니다.
2016-08-
15
성균관대학교 H.I.T
15
Bins ( 126개 )
Free 된 것을 재사용 하기 위해서 모아두는 곳
비슷한 크기끼리 모아 번호를 붙여서 관리함
메모리 단편화를 막기 위해서 사용 됨
Fast bin (exact fit)
Unsorted bin (Bin 1)
Small bin (Bin 2 to Bin 63, exact fit)
Large bin (Bin 64 to Bin 126)
Free된 메모리 주소
성균관대학교 H.I.T
20
Top Chunk?
Chunk Size
(1000 )
User Data
(Top Chunk)
Chunk Size
( 30 )
User Data
Chunk Size
( 970 )
User Data
(Top Chunk)
성균관대학교 H.I.T
21.
21
Who Controls Heap?
malloc동작 방식 요약
1. free된 목록에 비슷한 크기가 있으면 그것을 응용 프로그램에게 줌
2. 재사용 할 것이 없으면 Top 청크를 두 개로 나눠서 하나를 프로그램에
주고 나머지를 다시 Top 청크로 관리함.
성균관대학교 H.I.T
24
Heap Exploit Techniques.
Use After Free
Double free bug ( 막힘 )
Fastbin_dup
House of force
House of spirit
House of lore
Poison Null Byte
등등…
성균관대학교 H.I.T
25.
25
Fastbin_dup
a =1000, b = 2000 일 때
목표 : malloc(8) 을 통해 123456XX번지 받기
Fastbin_dup
성균관대학교 H.I.T
26.
26
Fastbin_dup
원래 정상적인방식
free(a); free(b); free(c); free(d);
malloc() , malloc(), malloc() , malloc()
순서대로 d, c, b, a를 응용 프로그램에 할당
성균관대학교 H.I.T
27.
27
Fastbin_dup
중복 FREE를할 경우
Free(a); free(b); free(a);
Malloc() , malloc(), malloc()
순서대로 a, b, a를 응용 프로그램에 할당
성균관대학교 H.I.T
32
Fastbin_dup
Fastbin_dup
free(a);free(b); free(a);
int *c = malloc(8);
A
Fd = 2000
1000
Size
Fd
Bk
Unused
Size
User
Data
B
Fd = 1000
A
Fd = 2000
성균관대학교 H.I.T
33.
33
Fastbin_dup
Fastbin_dup
free(a);free(b); free(a);
int *c = malloc(8); // 결과값 1000
2000
Size
Fd
Bk
Unused
Size
User
Data
B
Fd = 1000
A
Fd = 2000
성균관대학교 H.I.T
34.
34
Fastbin_dup
Fastbin_dup
free(a);free(b); free(a);
int *c = malloc(8); // 결과값 1000
*c = 0x12345678
2000
Size
Fd
Bk
Unused
Size
User
Data
B
Fd = 1000
A , C
Fd = 2000
성균관대학교 H.I.T
35.
35
Fastbin_dup
Fastbin_dup
free(a);free(b); free(a);
int *c = malloc(8); // 결과값 1000
*c = 0x12345678;
2000
Size
Fd
Bk
Unused
Size
User
Data
B
Fd = 1000
A , C
Fd = 12345678
성균관대학교 H.I.T
36.
36
Fastbin_dup
Fastbin_dup
free(a);free(b); free(a);
int *c = malloc(8); // 결과값 1000
*c = 0x12345678;
Malloc(8); // 2000
Malloc(8); // 1000
Malloc(8); // 12345678
2000
Size
Fd
Bk
Unused
Size
User
Data
B
Fd = 1000
A , C
Fd = 12345678
성균관대학교 H.I.T
37.
37
Fastbin_dup
Fastbin_dup 정리
A 도 1000번지, C 도 1000번지
똑같은 위치를 A, C 두 개가 가리켜서 생김
C에는 사용자의 데이터가, A에는 free list 관련 데이터가 존재.
요구 조건 :
더블 프리가 일어 나야 함 ( a, b, a 처럼 하나 건너서 )
( 12345678 번지에 있는 Size 영역을 맞춰줘야 함 )
( 크기가 작은 청크들 에만 적용이 가능 함 )
Size
Fd
Bk
Unused
Size
User
Data
성균관대학교 H.I.T
38.
38
House of force
top chunk size 조작을 통해서 원하는 위치에 malloc을 할 수 있음
힙에서의 Buffer Overflow 취약점이 선행 되어야 함.
char * string = ( char *) malloc( 10 );
strcpy( a, argv[1] );
Write – What – Where 가능
성균관대학교 H.I.T
39.
39
House of force
ChunkSize
( 1000 )
User Data
(Top Chunk)
성균관대학교 H.I.T
Malloc Size
1000 이하 :
Top 청크가 둘로 나뉨
1000 이상 :
새로운 메모리 덩어리를 OS에 요
청
40.
40
House of force
ChunkSize
( 1000 )
User Data
(Top Chunk)
Chunk Size
( 30 )
User Data
Chunk Size
( 970 )
User Data
(Top Chunk)
Malloc(22);
성균관대학교 H.I.T
41.
41
House of force
ChunkSize
( 970 )
User Data
(Top Chunk)
Chunk Size
( 30 )
AAAAAAAAA
AAAAAAAAA
AAAAAAAAA
AAAAAAAAA
AAAAAAAAA
Buffer Overflow
성균관대학교 H.I.T
42.
42
House of force
ChunkSize
( 970 )
User Data
(Top Chunk)
Chunk Size
( 30 )
AAAAAAAAA
AAAAAAAAA
Chunk Size
( 41414141 )
User Data
(Top Chunk)
Buffer Overflow
성균관대학교 H.I.T
Chunk Size
( 30 )
AAAAAAAAA
AAAAAAAAA
AAAAAAAAA
AAAAAAAAA
AAAAAAAAA
43.
43
House of force
ChunkSize
( 40000000 )
User Data
Chunk Size
( 1414141 )
User Data
(Top Chunk)
Malloc(40000000);
성균관대학교 H.I.T
Chunk Size
( 41414141 )
User Data
(Top Chunk)
Chunk Size
( 30 )
User Data
44.
44
House of force
Malloc(100);
ChunkSize
( 100 )
User Data
Chunk Size
( 1414041 )
User Data
(Top Chunk)
Chunk Size
( 40000000 )
User Data
Chunk Size
( 1414141 )
User Data
(Top Chunk)
성균관대학교 H.I.T
45.
45
House of force
ChunkSize
( 100 )
User Data
성균관대학교 H.I.T
이렇게 만들어진 청크는 기존의 힙 보다 40000000만큼 떨어진 곳에 위치
40000000을 조작하는 것으로 원하는 위치에 malloc이 가능함
※ realloc 등의 함수는 size_t 형태라서 음수를 넣을 경우 위의 조작이 가능함
46.
46
House of force
1. top chunk size 조작 ( 최대한 크게 )
2. (다음에 할당 받고 싶은 주소 – 현재 Top chunk 주소) 만큼 새로 malloc
할당
3. 다음 malloc을 통해서 할당된 메모리에 원하는 값 복사
요구 사항
현재 Top Chunk 주소를 알아내야 함.
Buffer Overflow 버그로 Top Chunk Size를 수정할 수 있어야 함.
원하는 만큼 malloc 할 수 있어야 함
성균관대학교 H.I.T
47.
47
Poison Null Byte
ThisChunk Size의 N , M , P
PREV_INUSE (P)
바로 이전 청크가 할당된 경우
IS_MMAPPED (M)
현재 청크가 mmap을 통해
할당된 경우
NON_MAIN_ARENA (N)
성균관대학교 H.I.T
49
Poison Null Byte
Prev| 101
User
Data
Line 2:
P = 0
Prev | 101
User
Data
Prev | 101
Fd
Bk
100 | 100
User
Data
Prev | 201
Fd
Bk
성균관대학교 H.I.T
Line 3: Line 4:
(Merged)
50.
50
Poison Null Byte
성균관대학교H.I.T
조건 :
널 바이트 하나 Overwrite와, malloc, free 를 원하는 대로 할 수 있어야 함.
다른 취약점에 비해서는 요구 조건이 적고 발생할 수 있을 가능성이 높음
문자열의 끝을 처리하다가 00을 끝에 Overwrite 하는 등..
결과 : 두 개의 청크가 Overlapp 되는 것
A : 1000~2000번지 사용
B : 1500~1600번지 사용
51.
51
Poison Null Byte
성균관대학교H.I.T
Prev | 0x41
A
Prev | 0x171
B
Prev | 0x101
C
A = malloc ( 0x38 ); // chunk size 0x40
B = malloc ( 0x168 ); // chunk size 0x170
C = malloc ( 0x98 ); // chunk size 0x100
※ 한 청크의 Size
Data + sizeof(Prev) + sizeof(Size)
53
Poison Null Byte
성균관대학교H.I.T
A[0x38] = 0;
/*
[0 ~ 0x37] 까지가 범위
Off by One Null Overwrite
Prev | 41
A
Prev | 171
B
freed
170 | 100
C
54.
54
Poison Null Byte
성균관대학교H.I.T
Size가 170 -> 100으로 줄어듬
D = malloc(0x38);
Prev | 100
B
freed
170 | 100
C
Prev | 41
A
55.
55
Poison Null Byte
성균관대학교H.I.T
Prev | C1
B
Freed
C0 | .
170 | 100
C
Chunk 의 사이즈가 줄어버려서
C의 Prev를 업데이트 하지 못함
E = malloc( 0x38 );
Prev | 41
D
Prev | 41
A
57
Poison Null Byte
성균관대학교H.I.T
Prev | 81
B
170 | 100
C
Free(C); << Merge
Prev | 41
D
40 | 41
E
Prev | 41
A
58.
58
Poison Null Byte
성균관대학교H.I.T
Prev | 81
B
170 | 100
C
F = Malloc(0x268);
Prev | 271
40 | 41
E
Prev | 41
A
59.
59
Poison Null Byte
성균관대학교H.I.T
Prev | 81
B
170 | 100
C
F = Malloc(0x268);
Prev | 271
F
Prev | 41
E
Prev | 41
A
60.
60
Poison Null Byte
성균관대학교H.I.T
정리
A, B, C 를 만들고, B를 해제
A를 Overflow 해서 해제된 B의 사이즈를 줄여버림
B를 쪼개서 D와 E를 만듬
D를 Free ( E 만 중간에 할당 되어 있음 )
C를 Free 하면서 맨 처음의 B~C를 합병하게 됨 >> Overlap
61.
61
총 정리
개발자 입장에서(적어도 Heap에 대해 ) 안전한 프로그램 을 만드려면
1. Double-Free 와 같은 취약점을 발생시키지 않는 것.
2. Heap상에서 buffer overflow가 나지 않도록 관리하는 것.
널 바이트 하나도 허용 해서는 안 된다.
공격자 입장에서 Heap을 Exploit 하려면
1. 위에 언급한 취약점을 찾을 수 있어야 하고 ( 널 바이트 하나라도 소중
히! )
2. Heap 근처에 위치한 자료구조에 대해서 잘 알고 있어야 합니다.
성균관대학교 H.I.T
63
Reference
Exploitation Trends:From Potential Risk to Actual Risk –
RSAConference2015,
https://www.rsaconference.com/writable/presentations/file_upload/br-t07-
exploitation-trends-from-potential-risk-to-actual-risk.pdf
Understanding glibc malloc
https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/
Understanding Heap by breaking it
https://www.blackhat.com/presentations/bh-usa-
07/Ferguson/Whitepaper/bh-usa-07-ferguson-WP.pdf
Slideshare – AngelBoy, Heap Exploitation
http://www.slideshare.net/AngelBoy1?utm_campaign=profiletracking&ut
m_medium=sssite&utm_source=ssslideview
2016-08-
15
성균관대학교 H.I.T
Editor's Notes
#2 힙에서의 버퍼 오버플로우를 어떻게 익스플로잇 할 수 있을 지에 대해서 몇가지 방법들을 다뤄 보려고 합니다.
그러기 위해서 힙이 갖고 있는 자료 구조에 대해서 설명 하고 이것을 악용하는 방법에 대해서 설명하는 것이 주요 내용이 될 거 같습니다.
#4 C언어를 모르시거나 포인터에 대한 개념이 약하신 분들은
따라오시기 힘들 수 있는데요, 나중에 좀 더 배우고 나셔서 보시면 더 잘 이해가 되실 것 같습니다.
#6 똑같은 헬로 월드를 지역변수인 스택과 동적 할당인 힙에 따로따로 만들어서 프린트에프를 하는 예제입니다.
아래는 실제로 해당 메모리가 어느 위치인지 찍어본 결과인데. 왼쪽은 스택영역으로 굉장히 큰 숫자인걸 알 수 있고 오른쪽은 힙 영역으로 상대적으로 작은 주소를 갖는 곳에 위치하는 것을 알 수 있습니다. 이건 메모리의 효율성을 위해 스택은 큰 주소에서, 힙은 작은 주소에서 서로 마주보는 방향으로 증가하도록 만들어져 있기 때문입니다.
#7 RSA 2015에서 마이크로소프트가 발표한 내용
2006 ~ 2014 년 스택 오버플로우 줄어들고 힙 관련 취약점인 힙 오버플로와 유즈에프터프리가 거의 80%를 넘는 비중을 보이는 걸 알 수 있습니다.
사실 이렇게 중요하게 생각되는데도, 실제로 한국어로 된 힙 취약점 익스 자료들이 많이 없습니다. 제가 이 조금 딱딱한 주제를 발표 주제로 잡게 된 것도 한국어로 자료를 하나를 더 만들면 좋을 것 같아서 였습니다.
#8 Doug lea 가 만든 dlmalloc 오래되기도 했고 고전적
Ptmalloc2 – dlmalloc + thread 지원, 현재 glibc
Jemalloc – 같은 크기의 여러 개를 Array형식으로 관리해서 효율성을 높임 등등…
MemGC – Use-After-Free 류의 공격을 방어하는데 도움이 되는 힙 관리자.
#10 그중에 서문에 해당되는 부분을 가져와 봤습니다.
속도가 빠르지도, 공간활용성이 좋지도, 이식성이 가장 좋지도 않다.
#12 실제로 프로그램에서 엠얼록을 했을 때 하나의 청크를 프로그램에 할당합니다. 요청한 크기보다 조금 크게 할당되는데 그 이유는 대상 청크의 크기를 담는 필드가 추가되어서 존재하기 때문입니다. 청크에는 사이즈와 여러 정보들이 담겨있지만 실제로 프로그램에 돌려주는 것은 UserData가 들어가는 옆의 그림에서의 mem 위치의 포인터 입니다.
#13 Malloc 의 재사용성에 관한 이야기인데 왼쪽의 뽑기기계로 비유를 해보면
빨간 공을 뽑는 것을 A메모리를 512만큼 사이즈로 할당 받는 것이라 하고, 빨간공을 다시 집어 넣는 것을 A 메모리를 프리하는 것이라고 비유를 해보겠습니다
#14 이 직후에 또 다른 공을 뽑게 되면 보통의 뽑기 기계에서는 원래 다른 랜덤한 공을 돌려주게 되겠지만
Malloc의 경우에는 아까 넣었던 A가 바로 돌아오게 됩니다 이걸 malloc이 메모리를 재활용 하기 때문인데요.
#16 빈스는 프리된 것들을 재사용 하기 위해서 모아두는 곳인데요. 비슷한 크기끼리 모아서 번호를 붙여서 관리합니다 옆에 있는 굴비처럼 메모리가 반환이 될 때마다 하나 하나 줄지어 놓고, 필요할때 그 줄지어 있는 것에서 하나씩 꺼내서 할당을 해주는 것이죠
이런 방식을 택한 이유로는, 어느 특정 크기, 예를 들면 30짜리를 말록을 했다가 프리한 프로그램에서는 다시 30을 할당할 가능성이 높다. 라는 전제하에 그 크기가 다시 사용될 것을 기대하고 재사용하기 위해서 모아두도록 한 것 입니다.
#17 이렇게 재사용을 하기 위해서 FREE 가 된 청크에는 fd, 와 bk라는 정보가 저장되게 됩니다. 링크드 리스트의 형태로 아까 그 굴비 모양 처럼 저장을 하게 되는데 원래 유저의 데이터가 있던 곳이지만, free 된 뒤에는 사용
#18 이렇게 재사용을 하기 위해서 FREE 가 된 청크에는 fd, 와 bk라는 정보가 저장되게 됩니다. 링크드 리스트의 형태로 아까 그 굴비 모양 처럼 저장을 하게 되는데 원래 유저의 데이터가 있던 곳이지만, free 된 뒤에는 사용
#19 이렇게 재사용을 하기 위해서 FREE 가 된 청크에는 fd, 와 bk라는 정보가 저장되게 됩니다. 링크드 리스트의 형태로 아까 그 굴비 모양 처럼 저장을 하게 되는데 원래 유저의 데이터가 있던 곳이지만, free 된 뒤에는 사용
#20 그 다음은 탑 청크에 대한 내용인데요 아까 어떤 힙 을 할당해서 그것을 나누어 주는 것을 하는 것이 엠얼록의 역할이라고 했는데
그 나누는 바탕이 되는 메모리를 탑 청크라고 부릅니다. 이렇게 탑 청크의 size가 1000인 상태에서 26만큼의 엠얼록을 시도하면 다음과 같이 변화 합니다
#21 26을 담기위한 30 크기의 청크가 생성되고, 다시 나머지 970만큼의 메모리 여유븐을 탑 청크로 관리하게 됩니다.
#23 How2heap 이라는 제목은 사실 shellphish라는 팀에서 관리하고 있는 기트허브 레포지터리에서 따온 제목입니다. Shellphish팀은 angr이라는 바이너리 자동화 분석 툴을 만든 것으로 유명한 팀이기도 한데, 자신들의 기술을 발전시키는거에 못지 않게, 이렇게 교육을 위해서 레포지터리를 운영 하는 것을 보고 배워야 할 점이 참 많다고 느꼈습니다. 아무튼 이 How2heap이라는 레퍼지터리에는 여러가지 힙 익스플로잇 기술들을 보여주고 있는데요
#24 아래 써있듯이 git clone, make, 그리고 실행 만 하면 영어긴 하지만 해당 취약점 익스플로잇 기술에 대해서 상세하게 설명을 해주는 예시를 보여주게 됩니다
#25 이 곳에서 다르눈 취약점들에는 유즈애프터 프리, 더블 프리 버그, 패스트 빈 중복 해제, 하우스오브 포스 하우스오브 스피릿 등등의 기법들을 소개하고 있는데요. 저는 이 발표에서 fastbin_dup와 하우스 오브 포스, 포이즌 널 바이트 3가지의 방식을 설명하려고 합니다.
#26 처음으로 다룰 방식은 fastbin_dup 입니다. 해석하면 fastbin 이라는 구조체를 중복시켜서 사용하는 것인데요.
에제 소스 코드를 먼저 읽어 보겠습니다.
#50 합병이 일어남, P = 0 인 것과, Prev Size를 알고 있으니까 이전 프리된 청크와 합병이 가능함.
하지만 Prev Size만 갖고 있지 Next Size를 갖고 있지는 않으니 free(b) free(a) 순의 경우에는 합병이 일어나지 않습니다.