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

이번엔 uaf관련 문제인것 같다. 

코드가 C++로 작성되었다.

우선 중요한 부분은  Human class의 give_shell()과 main문 인것 같다. 해석해보면 1번으로 소개를 하고, 2번으로 원하는 값을 동적할당 할 수 있으며, 3번으로 해제가 가능한 것 같다. 일단 선언되어있는 m과 w를 해제해주고, 2번으로 give_shell()의 주소를 잘 올리면, 1번으로 해당 주소를 실행시켜 쉘을 얻을 수 있을 것 같다.

 

우선 쉘코드를 보기 위해 switch 1번 부분 어셈을 봐준다. 참고로 글이 깨져서 나옴으로 'set print asm-demangle on' 명령어를 써주자.

코드를 보면 0x0000000000400fcd주소에 break를 걸어주면 될꺼같다.

`ni`로 진행을 해주다 rax에 0x8을 더하기 직전에 멈춘다.

현재 rax에 쓰여있는 주소를 봐주고 해당 주소가 가르키는 값을 보면 0x0040117a를 가르킨다. 그럼 0x401578은 0x004012d2를 가르키는 것을 알 수 있다. 각각의 주소를 들여다 보면 0x0040117a에 우리가 원하는 give_shell()의 주소가 써있는 것을 알 수 있다. 

그렇다면 우리는 0x12b4c50에 있는 0x00401570을 0x00401568로 덮어야 한다.

이런식으로 하면 쉘이 따인다.

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

[Toddler's Bottle]-flag  (0) 2019.07.05
[Toddler's Bottle]-bof  (0) 2019.07.05
[Toddler's Bottle]-collision  (0) 2019.07.04
[Toddler's Bottle]-fd  (0) 2019.07.04

오늘도 짱짱아이다로 열어보니 대학교 팀을 고르고 game함수가 있는 조건문으로 뛰어서 스코어가 121209이상이면 조건문 안으로 들어오는 것 같다. 해당 조건문에 들어오면 read함수에서 s크기보다 더 많이 받아주는 것을 볼 수 있다. bof취약점이다. 해당 부분을 맞춰주고, sh같은 문자가 들어있는지 검사한 뒤에 마지막으로 buf가 변조되었는지 봐주고 함수가 종료된다.

우선 game함수를 보면 menu함수에서 menu출력해주고 경기할 값을 입력해주면 해당 값에 따라 gogo함수에서 진행해서 전역면수 score값을 바꿔준다. 7번은 숨겨진 항목!

score은 unsigned int이고, gogo에는 score을  -- 해주는 기능이 있음으로 score값이 -가 되면 엄청 큰 숫자로 바뀌게 된다.

원하는 조건문까지 들어온 것을 확인할 수 있다. 보면 ebp가 0x124만큼 떨어져 있음으로 저만큼 채우고 ret값에 system함수 주소 넣어주고   sh주소 찾아서 인자로 넣어주면 될 것 같다......라고 생각했는데 오류가 떴다

확인해보니 memcmp함수에서 buf와 random_bak을 비교해주더라. s을 덮으면서 buf도 같이 덮어서 그런거 같은데 buf값을 어케 확인해 줄까 고민하다가 4u가 눈에 띄었다. team이름을 정하는 부분에서 printf함수를 보면 %s가 \n이 나올때까지 출력한다 한다. 그 앞에 read함수는 4u만큼 입력값을 받는데 생각해보면 뒤에 atoi로 변환해 v8에 넣어주고 nptr은 출력해주는 것을 볼 수 있다. 그럼 read에서 `1aaa`를 넣어주면 \n도 안들어가니 계속 출력될 것 같다. 

이런식으로 작성해주면 되겠다!....했는데 되지 않는다...

다시 덮은 스택을 보고 있는데 포인터로 선언된 v10이 마음에 걸렸다. 해당 부분을 맞춰줘야 하나 싶어 주소를 찾아 넣어주니 해결 되었다!

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

[practice]-19950320  (0) 2019.07.28
[practice]-daRk_TempLer  (0) 2019.07.23
[practice]-rain_dROP  (0) 2019.07.23
[practice]-catchme  (0) 2019.07.16
[practice]-rop_practice64  (0) 2019.07.15

아....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