heap공부를 하던 중 해당 사이트를 알았다.

https://github.com/scwuaptx/HITCON-Training

 

scwuaptx/HITCON-Training

For Linux binary Exploitation. Contribute to scwuaptx/HITCON-Training development by creating an account on GitHub.

github.com

위 사이트를 clone하면 터미널에 설치할 수 있다.

$ cd ~
$ git clone https://github.com/scwuaptx/HITCON-Training.git 
$ cd HITCON-Training && chmod u+x ./env_setup.sh && ./env_setup.sh

위 처럼 명령어를 치자.

$ apt-get install docker docker.io

docker을 이용해야 함으로 docker도 설치.

$  cd HITCON-Training
$ ./docker.sh

docker.sh를 실행시켜주자.
참고로 생각보다 좀 오래걸리는듯하다.

$ Got permission denied while trying to connect to the Docker daemon socket at unix......

docker.sh를 실행했을 때, 이런식으로 에러가 뜨는 경우가 있는데

$ sudo usermod -a -G docker $USER
$ sudo service docker restart

이런 식으로 명령어를 쳐주고 다시 실행해보자.
그래도 에러가 뜰 경우 우분트를 껏다 켜보면 된다.

참고

http://www.kwangsiklee.com/2017/05/%ED%95%B4%EA%B2%B0%EB%B0%A9%EB%B2%95-solving-docker-permission-denied-while-trying-to-connect-to-the-docker-daemon-socket/

불러오는 중입니다...

 

아...정말로 이 문제 풀다가 pwnable과 손절할뻔 했다....

우선 main문은 별게 없다. 그냥 buf에 보고싶은 값을 10진수로 입력받으면 해당 값을 주소로 변환해서 출력해주고, src에 값을 입력해주면 print_message에서 출력해준다음 끝나는 문제이다.

print_message함수를 자세히 보면 dest에 데이터를 넘겨주고 출력하는데 아까 main문에서 본 read함수의 입력값보다 dest의 값이 훨씬 작음으로 bof가 일어난다. 해당 함수의 ret를 잘 덮어 system함수값을 입력해주면 끝날 것 같다......라고 생각했는데 libc의 sh를 사용하지 않고 풀어야했다.(문제 난이도 급상승...)

일단 sh를 적을 공간이 필요했는데, bss에 적기에는 여분의 공간이 너무 적었다....해서, 스택을 이용해 문제를 풀기로 했다.

스택에 "sh"를 넣고 슥 풀면 문제가 해결된다. (절대 쓰기 귀찮아서 안쓰는게 아님)

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

[practice]-2015410208  (0) 2019.08.17
[practice]-2015410212  (0) 2019.08.12
[practice]-19950320  (0) 2019.07.28
[practice]-daRk_TempLer  (0) 2019.07.23
[practice]-rain_dROP  (0) 2019.07.23

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

+ Recent posts