IDA는 이런식으로 Structures 창이 있다. 해당 창에서 구조체를 선언하면 code를 좀더 편하게 볼 수 있다.

구조체를 선언하는 방법은 insert key를 누르는 것이다. 그런데 mac은 자판에 insert key가 없다... 대체로 `Insert -> fn+Enter`라고 했는데 아무리 눌러도 되지를 않는다... 해서 알아보니 mac은 단축키가 따로 존재하더라.

바로 `i`다. 

`i`를 누르면 이런식으로 create할 수 있는 창이 생긴다. 해당 창에서 내가 원하는 구조체 명을 적고 `ok`를 누르면 된다.

이런식으로 구조체의 ends를 누르고 `d`key를 누르면 변수가 선언된다.

선언된 변수에서 `n`key를 누르면 변수 명을 바꿀 수 있다.

선언된 변수에서 `d`key를 누르면 변수 크기를 바꿀 수 있다.

선언된 변수에서 `fn+u`key를 누르면 변수를 삭제할 수 있다.

 

구조체를 다 만들었으면 코드에 삽입해주면 된다.

변경하고 싶은 부분을 클릭하고 `y`를 누르면 해당 부분을 재정의 할 수 있다. 이런식으로 재정의해주면 된다.

'hacking > tool' 카테고리의 다른 글

How to use pwntools  (0) 2019.08.08

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를 작성했다....

아....64bit rop는 거의 처음이였는데 삽질만 100만번 한 것 같다....

우선 짱짱 아이다로 문제를 열어보면 사용할 수 있는 함수가 puts, read함수 두개이다.  (32bit rop에서 wirte함수로만 풀어봐서 puts는 처음이라 당황했다.)

 

조사해보니 64bit rop는 인자를 받는 피연산자가 굉장히 중요하다더라. 인자 받는 순서는 rdi, rsi, rdx순서이다.

그럼 우선 rop를 하기위해 gadget를 찾아보자.

이런식으로 ROPgadget 명령어를 입력하면 찾을 수 있다.

pead를 이용해서도 찾을 수 있다. gadget을 확인해보니 'pop rdx'가 없어서 libc에서 찾아보도록했다. 

rp를 이용해서 찾으면 저런식으로 libc에서 해당 gadget의 offset을 구할 수 있다. 나중에 libc base를 leak해서 더해주면 사용할 수 있다.(rp는 그냥 사이트에서 다운받으면 되지만, 난 mac이여서 chmod도 해줘야했다. 삽질..ㅎ)

 

이제 plt의 주소를 구해줘야 하는데 난 귀찮아서 ELF를 이용해 구했지만 직접 구할 수도 있다.

 

짱짱 아이다 functions window라던가

gdb-peda p 명령어 라던가.

 

이제 plt도 구했으니 offset을 구해보자.

우선 gdb peda에서 info proc map으로 libc base주소를 찾아주고,(b*main 같은거 하고 r 해주고 해야한다.)

이런 식으로 함수의 offset을 구해주면 기본적인 준비는 다 끝났다.

 

이제 pwntools이용해서 페이로드만 잘 써주면 되는데 여기서도 엄청나게 삽질을 했다.

우선 gadget rdx를 쓰려면 offset만 구한 것 임으로 libc base leak를 해줘야 한다. 그런데 입력은 read로 한번만 받으니 답이 안나왔다.

페이로드를 두번 보낼 수도 없고...........(?) 라고생각하면서 생각해보니 처음 페이로드로 leak을 하고, 그 뒤에 ret에 main주소를 넣어서 다시 돌아오면 두번 쓸 수 있을 것 같았다.

main주소 구해주고,

 

이런식으로 leak해줬다. 여기서도 보면 raw_input('AA')는 페이로드 중간에 멈추게 해서 다른 창으로 pid를 입력하면 디버거 할 수 있게 해줘 주소가 잘 들어갔는지 확인 할 수 있고, recv(1024)는 계속 인자를 받아봤는데 쓰레기값이 들어가는 것 같아 덮인게 잘못 들어갔나 싶어 넣어줬더니 되었다.(아직 잘 모른단 소리)

저런 식으로 libc 주소를 leak하고, read_addr에도 실 주소를 저장해서 다음 페이로드 때 system_offset에서만 더해서 계산하면 system주소를 read_got에 덮을 수 있다.

마지막으로 다시한번 페이로드를 보내면 해결 되었다.

아 추가로 삽질 한게 있는데 rdx gadget을 보면 pop rdx; pop rsi; ret이다. 따라서 인자 순서를 반대로 넣어줘야한다,...(이거로도 몇시간,,,)

 

최종 페이로드...ㅎ

'war game > game' 카테고리의 다른 글

[practice]-19950320  (0) 2019.07.28
[practice]-daRk_TempLer  (0) 2019.07.23
[practice]-rain_dROP  (0) 2019.07.23
[practice]-derby  (0) 2019.07.17
[practice]-catchme  (0) 2019.07.16

+ Recent posts