테스트 환경은 ubuntu 14.04 32bit 환경에서 진행했습니다.

 

우선 heap 에 3 chunks 를 할당하고, memset 을 통해 각각의 chunk 를 초기화한다.

p1 : 0x0804b008

p2 : 0x0804b108

p3 : 0x0804b208

 

 

p2 를 free 한다. p2 는 이제 동일한 크기의 새로운 malloc 할당을 대비해 unsorted bin 에 들어가게 된다.

 

 

이제 free 된 chunk 의 크기를 overwrite 할 수 있는 overflow 를 시뮬레이션 하자.

교육용 프로그램에서 size 의 마지막 3bit 는 중요하지 않지만 힙의 안정성을 유지하는 것이 좋다.

이 안정성을 유지하기 위해, 우리는 prev_inuse bit 를 설정함으로써 p1 chunk 가 free chunk 로 오인하지 않음을 보장한다.

우리는 chunk p2 크기를 385 로 셋팅하고, 우리에게 주어진 영역의 크기는 376(385 - chunk header) 이다.

 

*(p2-1) = evil_chunk_size;     // 우리는 chunk p2 의 size 필드를 0x181 의 값으로 overwrite 한다.

 

 

이제 우리가 chunk p2 의 size 필드를 overwrite 했던 0x181 과 같은 크기의 또 다른 chunk 를 할당한다.

이 malloc 은 크기가 변경된 unsorted bin 에 저장되어 있는 이전의 free chunk 로부터 제공받을 것이다.

 

p4 has been allocated at 0x0804b108 and ends at 0x0804b6e8

p3 starts at 0x0804b208 and ends at 0x0804b288

p4 는 p3 과 overlap 된다. 이 경우 p4 는 p3  을 포함한다.

 

 

이제 chunk p4 에 복사된 모든 내용이 chunk p3 의 데이터를 overwrite 할 수 있다.

그리고 마찬가지로, chunk p3 에 쓰여진 값은 chunk p4 에 저장된 값을 덮어쓸 수 있다.

 

예제를 통해 실행보자. 지금 우리는 다음과 같은 값을 가진다.

p4 : 2222222222222222222222222222222...

p3 : 3333333333333333333333333333333...

 

만약 memset(p4, '4', evil_region_size); 를 실행한다면, 우리는 다음과 같은 값을 가진다.

p4 : 4444444444444444444444444444444...

p3 : 4444444444444444444444444444444...

 

만약 memset(p3, '3', 80); 를 실행한다면, 우리는 다음과 같은 값을 가진다.

p4 : 4444444444444444333333333333333...

p3 : 3333333333333333333333333333333...

 

끝.

Posted by woodonggyu

댓글을 달아 주세요