이번에 분석한 자료는 house_of_spirit이다.

house_of_spirit 공격의 목적은 malloc의 return 결과를 우리가 원하는 청크의 주소로 만드는 것이다.
즉, freelist에 우리가 원하는 위치의 주소가 들어갈 수 있게 하는 것이다.

이 공격을 사용할 수 있는 조건은
우리가 메모리 영역에 가짜 청크를 만들 수 있어야한다는 것이다.
가짜 청크를 2개 만들어주는데 연속적으로 있어야한다.
또, 그 가짜 청크 주소를 free 함수에 넘겨 줄 수 있어야한다.
* free하기 전 malloc 1번은 꼭 필요하다.

먼저 malloc을 해준다.



(malloc)


 이 이유에 대해서 이해가 잘 가지 않았었다.
하지만 주석처리하고 실행해보고 이해할 수 있었다. 뒤에 우리가 가짜 청크를 만들고 그 주소를 free 시킬 것인데, malloc 할당을 한번도 하지 않고 free를 했기 때문에 에러가 난다.
이것을 막기 위해 malloc을 한번 해준다. 1로 해준 것은 그 값이 어떤 값이어도 상관없고 다만, 이 자료에서는 fastbin의 freelist를 이용할 것이기 때문에 작은 값으로 설정한 것이다.

이제 free의 인자로 넘길 포인터 변수를 만들어준다.



(포인터 변수 생성)


a 변수에 우리가 만든 가짜 청크의 주소를 쓸것이다.

이제 가짜 청크의 영역이다. 이 자료에서는 stack영역에 가짜 청크를 만들어주었다.

stack영역에는 비교적 우리가 값을 적기 쉽기 때문에 stack영역에 가짜 청크를 만들어 준 것 같다.



(가짜 청크를 위한 메모리 공간 확보)


위에 __attribute__는 컴파일러에게 특정한 방향으로 컴파일을 해달라고 부탁하는 명령이다.
aligned 16에 의해 16바이트로 정렬되게 컴파일 시킨다. 
64비트에서 unsigned long long은 8바이트이고 16바이트보다 작기 때문에 저 명령을 안써도 상관 없었다. (자료에서는 적혀있었다. 앞으로 64비트 이상의 컴퓨터가 나오게 되면 저 명령어가 필요할 수도 있을 것이다.)

그 다음으로 가짜 청크를 만들어주는 작업이다.



(가짜 청크 생성)


위 설명을 요약하자면
이 자료에서는 fastbin을 쓸것이기 대문에 PREV_INUSE는 무시해도 되지만, 다른 flag비트는 문제가 된다는 말로 모든 flag를 0으로 세팅하였다.
그리고 malloc 구현에 있어서 내부 internal size로 반올림 되기 때문에 0x30~0x38크기의 malloc 결과의 청크 사이즈는 0x40이 될것이기 때문에 우리는 0x40으로 만들어 줄 것이고
다음에 우리가 malloc할 때 0x30으로 할당 받을 것이다라는 이야기이다.

이제 다음 청크를 만들어 줘야한다.

free시 청크 뒤에 있는 청크의 사이즈를 검사한다. 그렇기에 정상적인 사이즈를 넣어야한다.



(검사 조건)


검사 조건은 이렇다.

SIZE_SZ란



(SIZE_SZ)


INTERNAL_SIZE_T의 크기가 SIZE_SZ 이고,
INTERNAL_SIZE_T는 size_t이다.
64비트에서는 8바이트 이므로 16바이트(0x10)보다 커야한다는 것이다.
당연한 것이, 청크의 헤더가 0x10이기 때문에 이거보다는 커야한다.

그 다음 조건은

av->system_mem 보다 작아야한다는 것




(system_mem)


av란 mstate로 정의 되어있고, mstate는 malloc_state 구조체이다.

이 구조체에 있는 system_mem은 할당된 메모리라고 나온다.
이 아레나가 할당된 크기를 말한다. 즉, 당연히 이 크기보다는 작아야한다는 것이다.

이런 아주 지극히 정상적인 크기의 값만 넣어주면 어떤 값이든 상관없다.

이 자료에서는 0x1234라는 값을 넣어주었다.



(두번째 청크 크기 설정)


여기서 배열 인덱스 9번에 적어주었는데, 그 이유는
우리가 첫번째 잡은 청크가 0x40의 크기였고 unsinged long long 크기가 8바이트 이기 때문에 총 배열 8개를 잡아먹고 그 다음 위치가 9이기 때문이다.

이제 우리가 만든 스택영역에 가짜 청크 두개를 만들었다.

이제 이 주소를 free 시키기 위해 포인터 변수에 이 주소를 먼저 넣어야한다.



(주소 입력)


인덱스가 2인 이유는 처음 0, 1은 헤더이다. free시킬 때는 user data영역의 주소를 가지고 free시키기 때문이다.

그 후 free 해준다.



(free)


그렇게 되면 지금 fastbin의 0x40의 리스트에 우리가 만든 가짜 청크의 주소 a의 주소가 들어있다.

이제 다시 malloc(0x30)을 하면 fastbin리스트에서 0x40의 주소를 찾아가 현재 있는 a의 주소를 return하게 되는 것이다.



(malloc)


공격 결과를 확인해보면 다음과 같다.



(공격 성공)

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

(how2heap) - poison null byte  (0) 2018.02.20
malloc의 사용가능 영역(HEAP)  (0) 2018.02.20
(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