overlapping chunk 두번째 자료이다.
이 문서에는 Heap overlapping에 관해서 3가지 정도의 방법을 제시했다.
Heap Overlapping에 관해 조금씩 다른 방법들을 제시했는데,
다들 비슷비슷한 느낌이었다. 그래도 많은 방법들을 봐두는 것이 좋은 것 같다.
지금까지 Heap Overlapping에 관련된 공격들을 정리하면서 깨달은 점이 있다.
그건
전부 Chunk 구조체의 SIZE 필드를 조작하므로써 공격을 한다는 것이었다.
PREV_SIZE라 던가, SIZE 필드라던가 chunk의 사이즈를 Allocator에게 솎여서 잘못된 할당과 해제를 유발하므로써 기존에 있던 chunk에 중첩되는 chunk를 만들게 하는 방식이었다.
그렇기에 최신 glibc에서는 PREV_SIZE 체크 라던가 SIZE 체크 부분이 추가되었고
이 부분을 우회하는 것을 최근 how2heap에서 본 기억이 난다.
무튼,
malloc 사이즈는 1000으로 16진수로는 3E8이다.
왜 굳이 p4일까?
-> p4를 free해주면 top청크와 병합되지 않는다. 이유는 top청크와 인접한 p5가 존재하기 때문에 병합되지 않는다. 그리고 공격의 개략적인 시나리오를 말하자면 p1 청크에서 off-by-one으로 p2의 청크 사이즈를 조작할 것이고, p3의 영역을 포함하고 있는 중첩된 heap영역을 할당받는 것이 우리의 목적이다.
p2 청크의 사이즈 + p3 청크의 사이즈 + PREV_IN_USE + sizeof(size_t)
조작할 사이즈는 p2와 p3를 합한 청크 사이즈로 만들 것이다.
뒤에 prev_in_use 값은 0x1 로써, 이전 청크가 사용중이라는 것을 알려주기 위해 설정한다. 그렇지 않으면 이전 청크와의 병합도 시도할 것이다.
sizeof 값이 더해지는 이유는 p2, p3의 헤더 크기를 추가해주는 것이다.
그렇게 되면 다음과 같은 일이 일어난다.
1. allocator는 p2를 free하려고 한다.
2. p2의 PREV_IN_USE 비트를 보니 이전 청크를 사용하는 군!
3. next chunk를 검사한다. (p2 주소 + p2의 사이즈 = p4) = next chunk는 p4
=> 왜 다음 청크가 p3이 아닌지? 방금 우리는 p2의 사이즈를 p2,p3을 합한 덩어리로 조작했다. 그렇기에 p2 주소 + (조작된)p2의 사이즈 = p4의 주소 이고 p4가 next chunk가 된다.
4. p4(next chunk)를 확인해보니, free 되어있네???
5. p4랑 병합해야지~, p2는 결론적으로 p2,p3,p4를 포함한 커다란 free chunk가 되버린다.
이 자료 또한 어떠한 문서를 참조했다고 나와있었다.
(참조 문서)
이 문서에는 Heap overlapping에 관해서 3가지 정도의 방법을 제시했다.
Heap Overlapping에 관해 조금씩 다른 방법들을 제시했는데,
다들 비슷비슷한 느낌이었다. 그래도 많은 방법들을 봐두는 것이 좋은 것 같다.
지금까지 Heap Overlapping에 관련된 공격들을 정리하면서 깨달은 점이 있다.
그건
전부 Chunk 구조체의 SIZE 필드를 조작하므로써 공격을 한다는 것이었다.
PREV_SIZE라 던가, SIZE 필드라던가 chunk의 사이즈를 Allocator에게 솎여서 잘못된 할당과 해제를 유발하므로써 기존에 있던 chunk에 중첩되는 chunk를 만들게 하는 방식이었다.
그렇기에 최신 glibc에서는 PREV_SIZE 체크 라던가 SIZE 체크 부분이 추가되었고
이 부분을 우회하는 것을 최근 how2heap에서 본 기억이 난다.
무튼,
heap overlapping 2번째 분석을 시작하자!
(5개의 힙)
malloc 사이즈는 1000으로 16진수로는 3E8이다.
뒷자리가 8인 것을 보면 눈치 채겠지만, off-by-one에 취약할 것이다.
(각 힙영역의 범위)
각 힙영역을 표시하기 위해 해당 영역에 문자들을 넣어주었다.
(문자 입력)
왜 굳이 p4일까?
-> p4를 free해주면 top청크와 병합되지 않는다. 이유는 top청크와 인접한 p5가 존재하기 때문에 병합되지 않는다. 그리고 공격의 개략적인 시나리오를 말하자면 p1 청크에서 off-by-one으로 p2의 청크 사이즈를 조작할 것이고, p3의 영역을 포함하고 있는 중첩된 heap영역을 할당받는 것이 우리의 목적이다.
: 그렇기에 p4를 free해준 것이다.
(free)
p1을 이용해 p2의 청크 사이즈를 조작한다.
(청크 사이즈 조작)
p2 청크의 사이즈 + p3 청크의 사이즈 + PREV_IN_USE + sizeof(size_t)
조작할 사이즈는 p2와 p3를 합한 청크 사이즈로 만들 것이다.
뒤에 prev_in_use 값은 0x1 로써, 이전 청크가 사용중이라는 것을 알려주기 위해 설정한다. 그렇지 않으면 이전 청크와의 병합도 시도할 것이다.
sizeof 값이 더해지는 이유는 p2, p3의 헤더 크기를 추가해주는 것이다.
(p2 free)
그렇게 되면 다음과 같은 일이 일어난다.
1. allocator는 p2를 free하려고 한다.
2. p2의 PREV_IN_USE 비트를 보니 이전 청크를 사용하는 군!
3. next chunk를 검사한다. (p2 주소 + p2의 사이즈 = p4) = next chunk는 p4
=> 왜 다음 청크가 p3이 아닌지? 방금 우리는 p2의 사이즈를 p2,p3을 합한 덩어리로 조작했다. 그렇기에 p2 주소 + (조작된)p2의 사이즈 = p4의 주소 이고 p4가 next chunk가 된다.
4. p4(next chunk)를 확인해보니, free 되어있네???
5. p4랑 병합해야지~, p2는 결론적으로 p2,p3,p4를 포함한 커다란 free chunk가 되버린다.
그 후 malloc을 통해 p3을 포함할만큼 커다란 영역을 할당받는다면?
(큰 영역 할당)
그렇게 되면 p3영역이 포함된 영역을 할당해준다.
(할당된 영역)
현재 p3에 들어있는 데이터
(p3의 데이터)
그 후 p6을 F로 1500 글자 채워준다.
(F로 채우기)
그렇게 되면 500자가 p3영역을 침범하게 되어 p3 데이터 앞부분이 F로 채워지게 된다.
(확인)
확인을 통해 p3가 중첩된 영역을 할당받은 것을 확인 할 수 있다.
'Vulnerability_Tech > About Heap' 카테고리의 다른 글
(how2heap) - overlapping_chunks (0) | 2018.02.22 |
---|---|
(how2heap) - house of lore (0) | 2018.02.21 |
(how2heap) - poison null byte (0) | 2018.02.20 |
malloc의 사용가능 영역(HEAP) (0) | 2018.02.20 |
(how2heap) - house_of_spirit (0) | 2018.01.17 |