티스토리 뷰



124번 째 줄의 get_buffer() 함수는 입력 버퍼를 할당 받은 header 힙에 저장합니다. 


만약 current_track에 0x8000000보다 큰 값을 넣고 부호 있는 정수형으로 반환한다면 current_track 값은 음수가 될 것입니다. 

그리고 if문은 false를 반환할 것 입니다. 그리고 178번째 부터 181까지의 쓰기 작업으로 총 4번의 NULL 포인터 역참조가 발생합니다. 


정상적인 흐름 


1. fourxm -> tracks 가 null로 초기화됩니다. 

2. 만약 strk 청크를 포함하고 있다면(160번째 줄) 헤더로부터 정수를 추출해서 current track에 넣습니다. 

3. track_count보다 current_track+1 이 크면 fourxm->tracks를 가리키는 메모리 할당이 이루어집니다. 

4. 마지막으로 할당된 메모리에 current_track을 기준으로 데이터가 채워집니다. 


버그가 발생했을 때 흐름


1. fourxm->tracks 가 NULL로 초기화된다. 

2. 만약 strk 청크를 포함하고 있다면(160번째 줄) 헤더로부터 정수를 추출해서 current track에 넣습니다. 

이 current track은 5번에서 사용되므로 이 부분을 적절히 조작하면 원하는 부분에 write 가능 

3. 만약 current_track+1 이 0보다 작으면 힙 버퍼가 할당되지 않습니다. 

4. fourxm->tracks 는 NULL을 가리키게 됩니다. 

5. 이러한 NULL 포인터는 current_track 의 사용자 지정 값에 의해 역참조되고 32비트 값이 역참조된 값에 할당됩니다. 


익스플로잇


1. strk 청크 값이 정상인 동영상 샘플을 구한다. 

2. strk 청크의 레이아웃을 파악한다. 



이 취약점을 exploit 하기 위해서는 &header[i+8] 부분과 &header[i+12] 를 변경해야한다. 이 값들을 적절히 설정하면 audio type 값이 null+track number의 메모리 위치에 쓰여질 수 있다. 


이를 이용해서 GOT 를 덮어쓰는 방식을 사용한다. GOT는 무엇보다 예측 가능하다는 점이 장점이다. 이번 경우 다음에 실행되는 라이브러리 함수는 memalign 이었다. GOT 엔트리 주소는 objdump를 사용해서 얻을 수 있는데 objdump -R 파일명 | grep memalign 을 사용한다. 


이 것을 통해 덮어 쓸 주소를 얻어낸다. 그렇다면 넣을 값을 어떻게 얻어내야할까
첫 번째 방법은 브루트 포스 방식이다. 0x80000000 부터 0xffffffff 까지 값을 모두 넣어본다. (음수로 해석되어야하기 때문이다.)

이 곳에는 따로 언급을 안했지만 어셈블리 상에서 edx + (ebx * 20) + 0x10 형식으로 계산합니다. 여기서 ebx가 current_track 부분이됩니다. 


그리고 이렇게 해서 구한 값을 currnet_track에 넣어주면 GOT가 변조되면서 EIP를 얻어낼 수가 있습니다. 


RELRO 예방 이라는 것이 있는데 이것은 GOT를 읽기 전용으로 만들어서 사전에 GOT overwrite를 예방할 수 있습니다. 

'시스템 보안 > 취약점' 카테고리의 다른 글

off by one 에러  (0) 2016.09.26
SEH overwrite 공격  (0) 2016.09.26
버퍼 오버 플로우란?  (0) 2016.09.26
Internet Explorer epm(Enhanced Protected Mode) 이란?  (0) 2016.09.25
1 취약점 발견 방법  (0) 2016.09.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함