BOF 원정대의 giant를 잡아보자!

* 소스코드


(giant.c)


중간에 복잡해보이는 코드가 있는데 친절하게 주석으로 설명이 되어있다.
ret주소에 execve 함수 주소가 들어가있는지 체크하기 위한 부분이다. 그렇기에 ret 주소에 execve를 넣어 execve 함수를 사용해서 문제를 해결하라는 의도같다.

그렇다면 execve를 어떻게 써야하나 구성인자를 살펴보자!



(execve 함수)



execve 함수의 인자
1. 파일이름(실행할파일)
2. 인자 주소(파일이름 문자열의 주소)
3. Null 문자열

예를 들기위해 C언어로 표현하여 실행해 보겠다



(execve c 코드)



(실행화면)



위와 같이 인자를 넘겨주니 execve 함수가 잘 실행되었다.

자 이제 이대로 인자를 만들어주어야한다.



(ret 주소)



ret 주소는 0x400a9d48 (execve 함수 주소) 를 넣었다.
이제 이 뒤에는 더미(4바이트) 를 넣은 후 그 뒤부터 인자가 들어가게된다.

execve 함수로 실행할 파일은 /bin/sh이다. 이 문자열을 직접 써주어도 되지만 그렇게 되면 문자열 주소를 넘겨주는 두번째 인자를 구성할 때 어려워진다. 왜냐하면 두번째 인자는 포인터 배열이기 때문에 주소와 널문자(4바이트)로 이루어져야하기 때문이다.

그렇기에 이미 로딩된 라이브러리에서 /bin/sh 문자열을 찾아 사용할 것이다.
system 함수 근처에 /bin/sh 문자열이 존재한다는 것을 알고 있기에 간단히 c코드를 만들어 /bin/sh 문자열 위치를 찾아낼 것이다.




(/bin/sh 주소찾기)



(/bin/sh 주소)



직접 gdb를 열어 해당 주소를 검색해보자.



(/bin/sh)



해당 주소에 /bin/sh 문자열이 들어있는 것을 확인 했다.

이제 첫번째 인자로 우리가 찾은 주소를 넣을 것이다.
두번째 인자를 구성해야한다. 일단 지금까지 만든 것을 토대로 메모리를 확인해보자.

A*44 + execve함수주소 + A*4(더미) + "/bin/sh주소" + "/bin/sh주소가 적힌 포인터배열 주소" + NULL

포인터배열을 만들계획이다. 일단 포인터배열 주소를 C*4 로 대체하고 메모리를 확인해보자!



(gdb 실행)


두번째 인자를 만들어줄 위치를 살펴보니 적당한 위치가 나왔다.



(4바이트 NULL)


포인터배열이기 때문에 주소뒤에 Null(4바이트)가 나와야하는데 우리가 입력은 못한다. 그렇기에 이미 존재하는걸 이용해야하는데 0xbffffae8 에 널 4바이트가 있다. 그러므로 그 앞에 문자열 주소를 입력한 후 해당 위치를 두번째 인자로 넘겨줄 것이다.

세번째 인자 Null은 0xbffffae8을 넘겨줄 것이다. 해당 주소가 이미 Null이기 때문에



(포인터배열)



위와 같이 포인터 주소배열을 만들 수 있다.



(포인터 배열)


0xbffffad4 위치에 정확히 포인터 배열이 들어갔다.
이제 두번째 인자로는 0xbffffad4를 
세번째 인자로는 0xbffffad8을 넣어줄 것이다.

마지막으로 확인 해보자.



(최종 확인)



해당 인자에 알맞은 값이 들어갔는지 체크!

공격!
0x10 바이트 앞뒤로 왔다갔다 하면서 올바른 위치를 잡았다.



(공격 성공)



쉘 획득!



bof 원정대의 troll을 잡아보자!

*소스코드 분석


(troll.c)



소스코드를 보면 우리가 늘 사용하던 인자영역이 초기화 되는 코드가 추가된 것을 확인 할 수 있다.
하지만 argv[0]은 초기화가 안되는데 이점을 이용해서 전 문제에서 풀던것 처럼 풀수가 있다.

실제로 사용할 메모리 주소먼저 확인해본다.



(gdb를 통한 실행)




(초기화된 부분)



늘 사용하던 argv[1] 영역이 0으로 초기화 된것을 확인 할 수 있다.

하 지만!



(argv[0] 영역)


argv[0]영역을 보면 뭔가가 있다. 바로 프로그램명(경로) 이다! 확인해보면


(프로그램명)



프로그램 이름(경로)인 것을 확인 할 수 있다.
그러면 전에 문제처럼 링크를 걸어서!

경로 먼저 생성해준다. \x2f가 경로의 구분자로 사용되기 때문에


(경로 생성)


그 후 링크!


(링크 생성)



Nop이 200개 정도니 충분하겠지? 바로 공격해본다.



(Segmentation Fault)


Segmentation Fault가 난다.. 이런.. 확인해봐야겠다. tromy 라고 내가 복사시킨 복사본을 가지고 링크를 똑같이 생성한 후 메모리를 확인해본다.



(링크생성(복사본에게))



(메모리 모습)



아하 조금 달랐다. 프로그램 이름이 길어져서 메모리 주소가 조금 바뀌었나보다.

다시 원본에 링크를 걸어주고!



(링크 생성(원본))



(공격)



공격! 은.. 또 실패!
Segmentation Fault...
뭐지!!!! 다시 복사본으로 링크를 만든 후 core 파일을 열어보았다. ( 복사본 링크과정은 똑같아서 생략했다.)



(core 파일)



음... 위치가 또 다르네..
어쨋건 nop영역의 주소를 하나 가져다가 공격!



(공격 성공)



쉘 획득!

'WarGame > 500 Project' 카테고리의 다른 글

(26/500) Lord of the BOF - skeleton  (0) 2017.06.20
(25/500) Lord of the BOF - vampire  (0) 2017.06.20
(23/500) Lord of the BOF - orge  (0) 2017.06.20
(22/500) Lord of the BOF - darkelf  (0) 2017.06.20
(21/500) Lord of the BOF - wolfman  (0) 2017.06.20


17번째 풀이 문제이다!

요즘 시스템공부를 하는 겸 BOF 원정대 문제를 풀어 나갈것이다. :)

BOF 원정대 메인 화면



(메인 화면)



첫 계정은 gate : gate 이다.

들어가보게 되면 파일이 2개 있다.




(바이너리 파일)



mygremlin은 gdb 분석을 위해 내가 cp명령을 이용해 복사한 파일이다.

먼저 C코드를 확인해보자 :)



(C코드)



C코드를 보면 프로그램실행시 인자를 넘겨주어 동작하게 되어있다.
넘겨준 인자를 버퍼에 strcpy를 이용해 복사한다. 
버퍼의 크기는 256바이트. strcpy를 이용하기에 bof 취약점이 존재한다.

gdb로 분석을 해보면.



(AAA인자 전달)



먼저 입력이 어떻게 들어가는지 확인하기 위하여
AAA를 전달하였다.



(저장된 값 확인)



strcpy 함수 명령이 지난후 메모리를 덤프해 확인해보니 AAA가 들어가있는 것을 확인 할 수 있다.

사용할 쉘코드는 
\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x54\x24\x04\x52\x31\xc0\xb0\x0b\x8b\x1c\x24\x89\xe1\x31\xd2\xcd\x80
이며 32바이트이다.

총 256바이트(버퍼) + 4바이트(Saved EBP) + 4바이트(RET) 까지 덮어쓰면된다.
즉 우리 쉘코드
쉘코드(32바이트) + 패딩(228바이트) + RET주소(4바이트) 이렇게 맞출 수 있다.



(메모리 주소 확인)



코드가 올라갔을 때의 메모리 주소를 확인한다.

0xbffff918 에 우리의 쉘코드가 올라가게된다. 그러니 RET주소를 

0xbffff918로 덮어쓰면 된다.!



(덮어쓰기)



문제풀이를 위해 캡쳐하는 과정에서 오타가 나서 여러번 다시 찍고는 했다. 위 캡쳐에서 적혀있는 RET 주소는 잘못된 RET 주소이다. 하지만 과정상의 사진으로 보고 이해하면된다. 실제로 RET주소는 위에 우리가 구한 주소를 적어주면 된다.

아래는 주소부분에 C4개를 넣어 과연 주소부분을 잘 덮을지 실제 주소를 넣기 전에 테스트 해보고 있는 사진이다.



(RET주소)



RET주소에 C4개가 들어간 것을 확인 할 수 있다. 
이제 이 자리에 우리가 아까 구한 쉘코드의 위치 주소를 넣어주면 된다.

이제 우리의 gremlin을 실행시켜 인자를 전달해보자.



(인자 전달)



실행시 bof가 발생하여 쉘이 떨어지는 것을 확인 할 수 있다.
SETUID가 설정되어있기 때문에 gremlin의 비밀번호를 확인 할 수 있다.



(문제 해결)


'WarGame > 500 Project' 카테고리의 다른 글

(19/500) Lord of the BOF - goblin  (0) 2017.05.07
(18/500) Lord of the BOF - cobolt  (0) 2017.05.05
(16/500) Wargame.kr - ip log table  (0) 2017.04.20
(15/500) Wargame.kr - lonely guys  (0) 2017.04.18
(14/500) Wargame.kr - strcmp  (0) 2017.04.16

+ Recent posts