오늘 분석한 자료는 이전 포스팅에서 다루었던 fastbin_dup을 이용하여
malloc으로 할당받는 주소를 우리가 원하는 주소로 할당받는 것이다.

이번 자료에서는 그 주소를 stack 영역의 주소로 할당받는 것이 목적이다.

fastbin_dup과 같이, free list가 a -> b -> a 이러한 상황을 만들어야한다.
같은 chunck를 free 2번 시킨 후 하나를 다시 malloc으로 받은 후 그 주소에 접근할 수 있으므로 다음 chunk를 가리키는 포인터를 조작하는 방법이다.

이 기술을 직접 사용하기 위해서는
free 3번(같은 chunk로 2번), malloc으로 double free한 chunk를 받아오거나 double free한 chunk에 접근 할 수 있는 상황과 그 조작한 chunk를 malloc 시킬 수 있는 상황이어야한다.
그렇다면 stack 주소뿐 아니라 다른 주소로도 malloc을 이용해 받을 수 있다.
(단, chunk의 구조체중 size 멤버가 적절해야한다.)

fastbin_dup_into_stack 자료를 분석해보자.

먼저 주소로 받을 위치는 stack_var의 주소이다.



(우리의 목적 주소)


여기서 +8을 해준 주소를 목적이라고 한 것은 heap의 chunk 구조를 보면 앞의 8바이트가 chunk size정보가 들어있는 위치이기 때문이다. 

먼저, fastbin_dup과 같이 3개의 malloc을 해준다.



(3개의 malloc)


fastbin을 이용할 것이기에 8바이트를 할당한다.
최소 16바이트이기 때문에 16바이트의 user data 영역이 생기고 8바이트의 size, 8바이트의 prev_size영역으로 총 32바이트, 총 chunk의 크기는 0x20일 것이다.

첫번째 free 해준다.



(첫번째 free)


그 후 바로 a를 free를 하면 free list 맨 위에 있는 a가 같으면 에러가 나므로

b를 free해준 뒤 a를 free해준다.



(free)


지금 까지의 상황은
free list의 top에는 a 주소가 들어있고,
a는 b를 가리키고 b는 a를 가리키는 a->b->a 의 상황이다.

여기서 malloc을 해주어 a의 주소를 d에 넣고, 다시 malloc을 해준다.




(malloc)


위의 코드까지 진행이 된다면
d의 주소에는 기존 a의 주소가 들어있고, 현재 free list의 top에는 이전 a의 주소(현재 d의 주소)가 들어있을 것이다.

free chunk list에 있는 chunk에 접근할 수 있다.
-> 이전 a의 주소(현재 d의 주소)가 free chunk list에 있고, d로 접근할 수 있기 때문에!

그렇다면 이제 우리가 할당받을 주소는 stack주소이기 때문에
stack 영역에 chunk라고 속일 수 있게 흉내를 내야한다.
우리가 malloc(8)을 사용하여 받을 것이기 때문에 총 청크 사이즈는 0x20이다.(위에 설명)

그렇기에 stack_var주소 위치에 0x20을 넣는다.




(chunk 총 크기)


그 후 chunk size영역의 크기는 8바이트 이전의 주소를 적어줘야한다.

그렇기에 d의 sizeof의 값이 8바이트이기에 sizeof(d)를 해주었다.



(fd 포인터 조작)


위의 과정까지 진행이 되면

메모리의 상황은 다음과 같다.



(메모리 상황)



위와 같이 fd 포인터 위치에 stack 주소가 들어가게 된다.

그 후 malloc을 해주게 되면 a의 주소가 할당 되고,
fd 포인터에 적혀있는 stack 주소로 넘어가 chunk size를 확인해보고 우리가 0x20으로 적어주었으므로 fastbin list에 들어가게 된다.

그러므로 free list의 top에는 이제 우리가 정한 stack 주소가 들어가게 되고

이번에 다시 malloc을 하게 되면 stack 주소가 반환되는 것이다.



(stack 주소 malloc)



(stack 주소 반환)


(* 위의 캡쳐 사진은 따로따로 찍은 것으로 gdb메모리 상황과 stack 주소 반환 결과가 같지 않다.)

'Vulnerability_Tech > About Heap' 카테고리의 다른 글

malloc의 사용가능 영역(HEAP)  (0) 2018.02.20
(how2heap) - house_of_spirit  (0) 2018.01.17
(how2heap) - unsafe_unlink  (0) 2018.01.13
(how2heap) - fastbin_dup  (0) 2018.01.04
(how2heap) - first_fit  (0) 2017.12.14
오늘 분석한 자료는 fastbin_dup 이다.

분석에 앞서 fastbin을 알아보았다.
glibc의 heap 초기 할당은 Top Chunck에서 이루어진다. 

Top Chunk에서 필요한 양을 잘라서 할당해준다. 그 후 사용이 끝난 후에 free를 해주는데
이 free된 chunk들을 그냥 내비두면 엄청난 낭비일 것이다.

그렇기에 free된 chunk를 재사용하기 위해 bin구조로 관리를 하여 재할당 해준다.
bin 구조는 사이즈에 따라 small bin과 large bin으로 나뉜다.
그리고 특수한 목적에 따라 unsorted bin, fastbin 으로 더 나뉜다.

small bin은 512바이트 미만의 chunk들을 관리하는 bin이다. 최소 바이트 16바이트 부터 8바이트 단위로 분류한다.
이 small bin안에 fastbin이 있다.
small bin안에서 72바이트 미만의 chunk들을 fastbin으로 관리한다.
fastbin은 다른 bin들과 달리 single-linked list로 관리된다. 다른 bin들은 doubled-linked list로 관리된다.

fastbin의 특징은 이름과 같이 빠르게 재할당할 수 있다는 것이다. 원리는 다른 bin의 chunk들은 인접한 chunk가 free되면 병합하는 작업이 있는데 fastbin은 이러한 작업이 없다. 그렇기에 다른 bin과 달리 fd와 bk를 가지지 않는 single-linked list의 구조이다. 이러한 구조는 Internal Fragment를 발생시키지만 속도는 빠르다는 장점이 있다.




(fast bin 구조)


how2heap의 fastbin_dup은 fastbin의 특징을 이용해 double free 공격을 보여준다.

먼저 3개의 chunk를 할당한다.


(3개의 malloc 할당)


그 후 a를 free해준다.



(a chunk free)


double-free 공격이란 free를 같은 chunk를 2번 하는 것이다. 같은 chunk를 2번 free한 다는 것은 말이 안되고 가능하게 되면 free list에 같은 chunk가 중첩된것 2개 들어가게 되는 것이고 그렇게 되면 malloc으로 같은 주소를 여러번 받을 수 있다는 것이다.

그렇기에 바로 free(a)를 하게 되면 free-list의 top에 a의 주소가 있으므로 에러가 날 것이다.

대신 b를 free해준다.



(b chunk free)


그렇게 되면
free-list에 b -> a 이렇게 single linked list에 들어가있는 상황이다.

그러면 우리는 a를 다시 free시킬 수 있게 된다.



(a chunk 두번째 free)

지금 이 상황의 메모리를 보자



(메모리 상황)


fastbin에는 a -> b -> a 이렇게 들어있다. 그렇기에 a의 주소(6000)에 b의 주소(6020)가 들어있고,
b의 주소인 6020의 다음 노드는 6000 으로 설정되어 있는 것이다.

여기서 다시 3개의 malloc을 해보면 결과는 아래와 같이 a, b, a의 주소가 나오고 결과적으로 a의 주소가 두번 malloc이 되는 상황이 나온다.




(결과)

'Vulnerability_Tech > About Heap' 카테고리의 다른 글

malloc의 사용가능 영역(HEAP)  (0) 2018.02.20
(how2heap) - house_of_spirit  (0) 2018.01.17
(how2heap) - unsafe_unlink  (0) 2018.01.13
(how2heap) - fastbin_dup_into_stack  (0) 2018.01.11
(how2heap) - first_fit  (0) 2017.12.14

how2heap의 첫번째 분석 자료는 first_fit 이다.
first fit이란 메모리 할당 전략 중 하나이다.

대표적으로 3가지가 있는데
first fit, best fit, worst fit 이 있다.

기본적으로 리눅스에서 heap 할당 관련해서는 first fit전략을 취하고 있다.

first fit이란 할당 가능한 메모리 영역을 발견하면 바로 할당하는 방식이다.
best fit은 internal fragment가 최대한 작게  딱 맞는 크기의 영역을 할당하는 방식이고
worst fit은 정반대로 최대한 널널한 영역을 할당하는 방식이다.

first fit 프로그램은 취약점을 보여주는 프로그램은 아니고
리눅스의 메모리 할당방식을 직접 보여주는 프로그램이다.

과정을 따라가며 분석해보겠다.



(메모리 할당)


 처음에 malloc을 통해 heap영역을 2개 할당한다.

a와 b에 할당을 해준다.



(메모리 할당 확인)



프로그램 실행시 확인해 볼 수 있다.
첫번째로 할당한 영역의 주소는 46010 이고 (뒷자리만 부를것이다.)

두번째로 할당한 영역의 주소는 46220 이었다.



(할당된 메모리 사용)


그리고 할당된 주소를 사용한다. a라는 주소에 문자열을 입력해준다.



(메모리 해제)



그리고, 메모리 할당을 free를 이용해 해제해준다.
그렇게 되면 현재 a에 할당된 주소인 46010 주소는 free된 상태이며 사용가능한 주소로
bin 구조에 들어가게 된다. 
리눅스에서는 haep영역의 메로리 할당과 해제를 bin을 통해 관리한다. 
나중에 heap영역 메모리 요청이 들어오면 이 bin 구조를 탐색한 후 메모리 할당을 해줄 것이다.

이 bin 구조는 사이즈에 따라 fast bin, small bin, unsorted bin 여러가지 종류로 구분되고
구조도 조금씩 다르다. 이에 대한 설명과 분석은 해당 취약점 분석때 자세히 하겠다.
이번 자료에서는 first fit에 초점을 맞춰보겠다.

다시 이어서 malloc을 해준다.



(malloc)


malloc을 통해 얻은 주소를 c에 넣어준다.

자 그렇게 되면 아까 해제(free) 되었던 주소가 c에 들어갈 것이다.
bin 구조에서 탐색하다가 사용가능한 영역을 발견하고 바로 아까 해제해주었던 영역을 할당해 주는 것이다.

확인을 위해 이번엔 방금 할당된 주소를 사용해본다.



(메모리 사용)



방금 할당 받은 주소에 C라는 문자열을 적는다.

그리고 a변수 처음에 할당되었던 주소가 담긴 변수와

c변수 방금 할당했던 주소가 담긴 변수를 주소값과 안에 담긴 문자열을 출력해본다.



(같은 주소)


결과는 처음 할당했던 주소가 46010이었는데 해제(free)해준 뒤 다시 malloc을 통해 받은 주소가 똑같은 46010이다. 그리고 그 안에 있는 문자열은 thist is C! 로 정확히 같은 주소라는 것을 보여준다.


'Vulnerability_Tech > About Heap' 카테고리의 다른 글

malloc의 사용가능 영역(HEAP)  (0) 2018.02.20
(how2heap) - house_of_spirit  (0) 2018.01.17
(how2heap) - unsafe_unlink  (0) 2018.01.13
(how2heap) - fastbin_dup_into_stack  (0) 2018.01.11
(how2heap) - fastbin_dup  (0) 2018.01.04

+ Recent posts