uaf관련 ctf문제가 처음이여서 굉장히 많이 삽질했다.

 

우선 main문을 보면 6개 정도의 case가 존재하는 것 같다.

create_pet_recode함수를 보면 pet recode를 생성하는 함수인 것 같다. 

PET은 구조체이고, 이런식으로 되어있는 것 같다.(char *name, char *kind, int age)

edit_pet_record함수는 이미 존재하는 record의 id를 가져와 내용을 변경해주는 함수인 것 같다. 그런데 마지막 조건문을 보면 'n'일 경우 `::ptr`(전역변수)을 free해준다. 하지만 `::ptr`=NULL; 하는 부분이 없음으로 `::ptr`은 여전히 free된 chunk주소를 가르키고 있다. 여기서 uaf가 발생한다.

 

heap구조를 분석해보자.

`gdb -q Cat`을 입력하고 `r`을 한 뒤,

이런식으로 입력하고, `control+c`를 하면 프로그램이 멈추면서 디버깅을 할 수 있다.

`heapinfo`를 이용해 fastbin구조를 볼 수 있다.

free된 chunk 주소가 `0x603000`근처임으로 해당 주소를 보면 heap구조를 볼 수 있다.

heap구조

----------------

&AAAA, &BBBB

----------------

AAAA

----------------

BBBB

----------------

0

----------------

&0x603060

----------------

&0x603080

----------------

top chunk

----------------

이제 create_pet_recode함수를 이용해 다시 `malloc`을 불러오면 어떻게 구조가 변하는지 보자.

이런식으로 입력한 뒤

heap구조를 보면

heap구조

----------------

&AAAA, &BBBB

----------------

AAAA

----------------

BBBB

----------------

DDDD

----------------

CCCC

----------------

&CCCC, &DDDD

----------------

top chunk

----------------

이런식으로 값이 들어간다. (fastbin은 LIFO구조임으로.)

여기서 다시 edit_pet_record함수를 접근하면 `::ptr`은 아까와 똑같은 chunk구조를 가지고 있다고 생각하며 동작한다.(heap구조 맨 위 &AAAA, &BBBB를 생각하며 이해) 그 결과 값 `DDDD`를 주소로 인식해 `&DDDD`로 접근해 값을 대입하고, 그 뒤로 텅 비어있음으로 &0000에 접근해 값을 대입하려다 실패하고 `Segmentation fault (core dumped)`를 띄운다.

이제 모든 분석이 끝났다. 공격 시나리오는 두번째 create_pet_recode함수호출에서 kind위치에 PET[3](id = 2)의 주소+bss공간 주소를 넣은 뒤, edit_pet_record함수를 호출해 name위치에 bss공간주소를 넣고, kind위치에 잘 안쓰이는 puts함수 got주소를 넣어주자.

그 후 print_record함수를 호출해(case 3) id에 2을 입력하면 name에 puts_got실제주소가 출력되 leak이 가능하다.

다시 create_pet_recode함수를 호출하고 kind위치에 atoi함수의 got주소를 넣고, 모양을 맞춰주기 위해 대충 bss공간 주소를 넣어준 뒤, edit_pet_record함수를 호출해 name위치에 leak한 system_got값을 넣고, bss공간주소를 대충 넣어주면 될 것같다.

 

IDA를 보면 0x6020A0에 PET배열이 들어가는 것을 볼 수 있다. 

보면 id = 2의 주소가 0x6020b0인 것을 알 수 있다.

이런식으로 payload를 작성했다....

+ Recent posts