이 공격을 할 수 있기 위해서는
가짜 청크 구조를 만들 수 있어야하고, 임의의 사이즈의 malloc과 free가 가능해야한다.
이 공격으로 스택영역의 주소를 malloc으로 받아서, return 주소를 덮어써서 임의의 코드를 실행해 볼 것이다.
(임의의 코드)
먼저, 스택영역에 가짜 청크의 구조를 만들어야한다.
(가짜청크 영역)
가짜 청크 영역을 잡아둔다.
그 후 우리가 이용할 chunk를 하나 만든다.
(chunk 생성)
알다시피, 정확한 chunk의 주소를 구하기 위해서는 2 WORD를 빼줘야한다.
(진짜 chunk 주소)
header가 2 WORD 이기 때문!이다.!
그 후 우리가 가짜 청크에 설정해주어야할 것이 있다.
이 모든 것은 아래의 small bin corruption check를 우회하기 위한 것이다.
(small bin corruption check)
가짜 청크에 값들을 넣어준다.
(조건 우회)
(메모리 모습)
스택버퍼1 - 스택버퍼2
이렇게 연결되어있다.
스택버퍼1 의 fd : victim
스택버퍼1의 bk : 스택버퍼2
스택버퍼2의 fd : 스택버퍼1
그 후 1000사이즈로 다시 malloc한다.
(malloc)
우리가 이제 victim 청크를 free할 것인데, top chunk와 병합되어버리지 않게 하기 위해
1000 사이즈 ( large bin ) 를 malloc 해주었다.
그리고 free!
(free)
그렇게 되면 아래와 같은 모습이 된다.
(free된 모습)
small bin에 들어가면 fd와 bk가 써져야 되는 거 아닌가??
=> 지금 안써진 이유는 바로 현재는 unsorted bin에 들어가있기 때문이다.
unsorted bin이란 일종의 캐시같은 역할인데, free가 되면 bin에 들어가기 전 unsorted bin에 들어가있는다. 그리고 그 다음 malloc때 같은 사이즈의 malloc이면 들어있던 청크가 반환되고 아니라면 원래 자기의 영역 bin에 들어가게 된다. 즉 한번의 재사용 기회가 주어지는 것이다.
그렇기에 우리는 지금 free 한 청크를 small bin에 넣고 싶기 때문에
이 한번의 재사용기회(?) unsorted bin에 있는 것을 빼주어야한다.
다른 large bin 영역의 사이즈로 다시 malloc 한다.
(malloc)
그리고 다시 victim 청크를 보면
(victim 청크)
아까 위에서
스택버퍼1 - 스택버퍼2 까지 연결했고,
스택버퍼1과 victim 청크를 연결할 것이다.
스택버퍼1의 fd는 아까 victim 청크 주소를 넣었고
이제 victim 청크의 bk주소에 스택버퍼1의 주소를 넣으면 된다.
(bk 조작)
그 후 victim 청크의 모습을 보면
(victim 청크)
이제 small bin의 사이즈 100인 bin에 우리가 만든
victim - 스택버퍼1 - 스택버퍼2
이렇게 주렁주렁 달려있을 것이다.
그러니 그대로 주르륵 꺼내보자.
사이즈는 100으로 malloc 한다.
(malloc)
p3 = victim 청크
그러면 지금 스택버퍼1을 보면?
(스택버퍼1)
이제 그다음 malloc(100)을 하면 우리의 스택버퍼1 차례이다.
(malloc)
p4에 스택버퍼1의 주소가 들어간다.
(결과)
그렇다면 이제 이걸 이용해서 ret 주소를 덮어쓸 것이다.
(ret 덮어쓰기)
직접 확인해보니 return 주소까지 72바이트 떨어진 자리였다.
(확인)
ret 주소에 jackpot 함수 주소가 들어가 있다.
(임의의 코드 실행)
결과적으로 마지막에 jackpot 함수(임의의 코드)가 실행되었다.
'Vulnerability_Tech > About Heap' 카테고리의 다른 글
(how2heap) - overlapping_chunks_2 (0) | 2018.02.27 |
---|---|
(how2heap) - overlapping_chunks (0) | 2018.02.22 |
(how2heap) - poison null byte (0) | 2018.02.20 |
malloc의 사용가능 영역(HEAP) (0) | 2018.02.20 |
(how2heap) - house_of_spirit (0) | 2018.01.17 |