이번에 분석한 자료는 house_of_spirit이다.
house_of_spirit 공격의 목적은 malloc의 return 결과를 우리가 원하는 청크의 주소로 만드는 것이다.
즉, freelist에 우리가 원하는 위치의 주소가 들어갈 수 있게 하는 것이다.
이 공격을 사용할 수 있는 조건은
우리가 메모리 영역에 가짜 청크를 만들 수 있어야한다는 것이다.
가짜 청크를 2개 만들어주는데 연속적으로 있어야한다.
또, 그 가짜 청크 주소를 free 함수에 넘겨 줄 수 있어야한다.
* free하기 전 malloc 1번은 꼭 필요하다.
하지만 주석처리하고 실행해보고 이해할 수 있었다. 뒤에 우리가 가짜 청크를 만들고 그 주소를 free 시킬 것인데, malloc 할당을 한번도 하지 않고 free를 했기 때문에 에러가 난다.
이것을 막기 위해 malloc을 한번 해준다. 1로 해준 것은 그 값이 어떤 값이어도 상관없고 다만, 이 자료에서는 fastbin의 freelist를 이용할 것이기 때문에 작은 값으로 설정한 것이다.
이제 가짜 청크의 영역이다. 이 자료에서는 stack영역에 가짜 청크를 만들어주었다.
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으로 할당 받을 것이다라는 이야기이다.
이제 다음 청크를 만들어 줘야한다.
INTERNAL_SIZE_T는 size_t이다.
64비트에서는 8바이트 이므로 16바이트(0x10)보다 커야한다는 것이다.
당연한 것이, 청크의 헤더가 0x10이기 때문에 이거보다는 커야한다.
그 다음 조건은
이 구조체에 있는 system_mem은 할당된 메모리라고 나온다.
이 아레나가 할당된 크기를 말한다. 즉, 당연히 이 크기보다는 작아야한다는 것이다.
이런 아주 지극히 정상적인 크기의 값만 넣어주면 어떤 값이든 상관없다.
우리가 첫번째 잡은 청크가 0x40의 크기였고 unsinged long long 크기가 8바이트 이기 때문에 총 배열 8개를 잡아먹고 그 다음 위치가 9이기 때문이다.
이제 우리가 만든 스택영역에 가짜 청크 두개를 만들었다.
house_of_spirit 공격의 목적은 malloc의 return 결과를 우리가 원하는 청크의 주소로 만드는 것이다.
즉, freelist에 우리가 원하는 위치의 주소가 들어갈 수 있게 하는 것이다.
이 공격을 사용할 수 있는 조건은
우리가 메모리 영역에 가짜 청크를 만들 수 있어야한다는 것이다.
가짜 청크를 2개 만들어주는데 연속적으로 있어야한다.
또, 그 가짜 청크 주소를 free 함수에 넘겨 줄 수 있어야한다.
* free하기 전 malloc 1번은 꼭 필요하다.
먼저 malloc을 해준다.
(malloc)
하지만 주석처리하고 실행해보고 이해할 수 있었다. 뒤에 우리가 가짜 청크를 만들고 그 주소를 free 시킬 것인데, malloc 할당을 한번도 하지 않고 free를 했기 때문에 에러가 난다.
이것을 막기 위해 malloc을 한번 해준다. 1로 해준 것은 그 값이 어떤 값이어도 상관없고 다만, 이 자료에서는 fastbin의 freelist를 이용할 것이기 때문에 작은 값으로 설정한 것이다.
이제 free의 인자로 넘길 포인터 변수를 만들어준다.
(포인터 변수 생성)
이제 가짜 청크의 영역이다. 이 자료에서는 stack영역에 가짜 청크를 만들어주었다.
stack영역에는 비교적 우리가 값을 적기 쉽기 때문에 stack영역에 가짜 청크를 만들어 준 것 같다.
(가짜 청크를 위한 메모리 공간 확보)
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_t이다.
64비트에서는 8바이트 이므로 16바이트(0x10)보다 커야한다는 것이다.
당연한 것이, 청크의 헤더가 0x10이기 때문에 이거보다는 커야한다.
그 다음 조건은
av->system_mem 보다 작아야한다는 것
(system_mem)
이 구조체에 있는 system_mem은 할당된 메모리라고 나온다.
이 아레나가 할당된 크기를 말한다. 즉, 당연히 이 크기보다는 작아야한다는 것이다.
이런 아주 지극히 정상적인 크기의 값만 넣어주면 어떤 값이든 상관없다.
이 자료에서는 0x1234라는 값을 넣어주었다.
(두번째 청크 크기 설정)
우리가 첫번째 잡은 청크가 0x40의 크기였고 unsinged long long 크기가 8바이트 이기 때문에 총 배열 8개를 잡아먹고 그 다음 위치가 9이기 때문이다.
이제 우리가 만든 스택영역에 가짜 청크 두개를 만들었다.
이제 이 주소를 free 시키기 위해 포인터 변수에 이 주소를 먼저 넣어야한다.
(주소 입력)
그 후 free 해준다.
(free)
이제 다시 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 |