glibc-2.23
#1. 소개
Large bin attack 은 how2heap에 자세히 소개되어있다
https://github.com/shellphish/how2heap/blob/master/glibc_2.26/large_bin_attack.c
들어가기에 앞서 간단히 large bin 에 대해서 설명해보자면
large bin은 0x400 size 이상의 chunk 들을 관리하며 이중 연결리스트로 동작한다
다른 bin들과 다르게 fd, bk 이외에 fd_nextsize 및 bk_nextsize 가 있는데
이 둘은 다음 사이즈의 large bin chunk 를 연결하고 있다
Large bin attack 은 이름 그대로 Large bin의 동작원리를 이해하여
임의 주소에 heap chunk 주소 값을 덮을 수 있다
위 결과를 얻기 위한 조건은 아래와 같다
Large bin 에 들어있는 chunk의 size 값, bk, bk_nextsize 를 조작할 수 있어야 한다
( 기본적으로 UAF가 가능해야한다는 의미이다 )
취약점을 발생시키는 방법은
1. large bin 크기에 해당하는 chunk 3개를 할당한다
( 단, p1의 size는 p2와 p3보다 작아야한다 )
2. p1과 p2를 차례로 free한 뒤 p1보다 작은 크기의 chunk 를 할당함으로써 p2를 large bin으로 보낸다
( 이 때 p1은 unsorted bin에 남아있다 )
3. 이후 p3를 free하여 unsorted bin에서 p1과 p3 가 연결되도록 한다
4. 앞선 전제조건을 바탕으로 p2의 size 값을 p3보다 작게만들고
bk에는 target-0x10, bk_nextsize 에는 target-0x20을 적는다
( 여기서 target은 우리가 덮고싶은 임의의 주소이다 )
5. 이후 줄어든 크기의 p1보다 작은 크기의 chunk 를 할당함으로써 p3를 large bin 으로 보낸다
이후에 target에 p3 청크의 주솟값이 남게된다
#2. 분석하기
* how2heap의 large_bin_attack.c 를 보고나서 작성하였음
( + malloc.c에서 large bin code 를 분석하기보다 직접 메모리를 보면서 확인하였음 )
먼저 왜 저 3가지 값들을 조작해야하는지 이해하기 위해서
how2heap의 playground 에서 뛰어놀아보고자 한다
( https://github.com/shellphish/how2heap/blob/master/malloc_playground.c )
1. 왜 size 값을 바꾸는 것일까?
large bin attack 을 위해서 p2와 p3 chunk 를 생성할 때
p2와 p3 chunk 의 size를 동일하게 만든 뒤
p2 의 size를 UAF 를 통해 p3보다 작도록 수정하는 부분이 있다
만약 p2 의 size를 애초에 p3 보다 작으면 되지 않을까 라는 의문이 생겼고
이를 알아보기 위해 먼저 size 값을 다르게 만든 p2와 p3 를 생성해보았다
malloc 0x90 을 통해 p3 chunk 를 large bin 으로 보내기 전의 메모리 상황은 다음과 같다
p2 는 0x480 크기의 large bin에 관리되어 있다
다음은 malloc 0x90 을 통해 p3 chunk 를 large bin 으로 보낸 후의 메모리 상황이다
p2 와 p3 가 다른 size라 bk 를 통해 연속적으로 연결되어있지 않은 모습이다
이후 이 상황에서 p2의 bk와 bk_nextsize 값을 조작하더라도 취약점 트리거가 되지 않았다
0x90을 통해 p3를 large bin 으로 보내기 전
p3를 large bin 으로 보낸 이후
dl_open_hook 에 heap chunk 주소값을 남기는데 실패했다
아마도 size가 동일한 chunk 들끼리 bk와 bk_next 를 넘겨주는 과정이 필요한 것 같다
따라서 p2와 p3 가 같은 size 의 chunk 로 관리되도록 해야함을 알 수 있다
근데 이후 또다른 의문점이 하나 생긴다
2. 왜 p2의 size 는 p3보다 작아야하는가?
아래는 size 값을 변경하지 않은채 취약점을 트리거하려는 모습이다
먼저 p1,p2,p3 를 셋팅해두고
위 상태에서 p2의 size 값을 변경하지 않은 채 + bk와 bk_nextsize 를 변경하지 않은 채
malloc 0x90 을 통해 p3 를 large bin 으로 보낸 상황이다 ( 매우 정상적인 상황 )
보다시피 large bin 에 들어가있는 순서가
p2->p3 가 아닌 p3->p2 가 되어있는 모습이다
하지만 p2의 size 값을 p3 보다 작게한다면
p2->p3 로 연결되게 된다
따라서 p2 -> p3 순서로 연결되도록 한후
p2 의 bk값과 bk_nextsize 에 target-0x10,-0x20 을 적어둔다면
p3 다음 chunk 가 target chunk 라고 생각하여
p3의 bk와 nextsize은 target-0x10과 target-0x20을 적을 것이고
target의 fd위치에는 p3 chunk 주솟값이 들어갈 것이다
세줄요약
1. p2와 p3 입장에서는 서로가 연결되고 싶은 상황인데 임의의 값 조작을 통해서 p2 bk에는 이상한 값이 있는 상황임
2. p2는 자신의 bk를 p3로 미루기 위해서 p3의 bk에다가 target-0x10을 넘겨줌
3. p3 입장에서는 target-0x10이 p3다음이라는 걸 전달받아서 target-0x10의 fd(즉,target)에는 p3가 적힘
#3. 응용하기
여기 heap chunk 주소값을 덮어쓰기 좋은 함수가 하나 있다
이 함수는 abort() 가 실행될 때 참조되어지는데
dl_open_hook 에 있는 주솟값을 참조하여 jmp 를 실행한다
즉, dl_open_hook 에 0x602020 이라는 주솟값이 들어있으면, 0x602020 에 들어있는 0x41414141 로 jmp 한다
이 함수에 heap chunk 주솟값을 남기면 우리가 원하는 곳으로 jmp 할 수 있겠다
앞서 배운 내용을 바탕으로 p1 과 p2, p3 chunk 를 준비해두고
p2의 size와 bk, bk_nextsize 까지 dl_open_hook 을 target으로 조작해둔다
이후 p3를 large bin 으로 보내면 아래와 같은 상황이 발생한다
원래 NULL 값이 들어있던 dl_open_hook 을 성공적으로 덮은 모습이다
이후 0x604990 에 jmp 하고 싶은 함수들을 적으면 되겠다
'System Hacking > Study Notes' 카테고리의 다른 글
어셈블리어 구구단 만들기 (3) | 2020.07.01 |
---|---|
개인 서버 만들기 (with. GCP) (0) | 2020.06.16 |
About Strtok (0) | 2020.04.29 |
Calloc Flow Control (0) | 2020.04.29 |
내 힙(heap) 어때? (0) | 2020.04.06 |