본문 바로가기

Security/Pwnable

[FTZ] level 9 문제풀이

 

 

 

먼저 ls를 해보면!

 

 

힌트가 있다!!

 

 

 

힌트를 먼저 봐보자!

 

 

힌트를 보니 소스 코드는 /usr/bin 폴더 안에 있는 bof의 소스코드이고

buf2에 go라는 문자열이 있다면 쉘을 얻어올 수 있으니

buf2에 go를 집어넣으면 된다라는 것을 알 수 있었다.

 

 

그렇다면 고것을 어떻게 할까..?

 

 

그걸 알아보기 위해 gdb를 이용해보기로 하자!

 

/*

gdb란? Linux에서 사용되는 디버깅 툴로 프로그램 내부에서 무슨 일이 일어나고 있는지 보여주거나 프로그램이 

            잘못 실행되었을 때 무슨 일이 일어나고 있는지 보여준다.

 

******************level 9를 풀기 전 알아야 할 gdb 명령어**************************

- gcc -o a a.c : a.c라는 소스코드를 컴파일 하여 a라는 프로그램 제작 

- gdb a : a라는 파일을 gdb로 연다.
- set disassembly-flavor intel : intel 문법으로 변환
- disas main : main을 disassemble 한다.

************************************************************************

*/

 

/*

어셈블리어란?  기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어

                      ex)    mov        ebx,          eax

                          operator operand1, operand2

 

어셈블리어 문법

 

1. Intel

 

 - 윈도우에서 사용한다.

 

-  목적지(destination)가 왼쪽, 원본(source)이 오른쪽에 위치한다.

    ex) mov ebx, eax : eax에서 ebx로 데이터를 복사한다.

 

2. AT&T

 

- 리눅스에서 사용한다.

 

- 모든 레지스터 이름 앞에 %가 붙는다. 

 

- operand 의 크기를 지정할 때 크기에 따라 b (byte), w (word), l (long) 접미사를 명령어에 붙인다.

 

-  원본(source)이 왼쪽, 목적지(destination)가 오른쪽에 위치한다.

   ex) movl %eax, %ebx : eax에서 ebx로 데이터를 복사한다.

*/

 

gdb로 /usr/bin/bof 를 열면!

 

Permission denied가 뜬다.

 

하지만 우린 bof의 소스코드(hint)를 알고 있으므로 hint를 복사하여 tmp에 bof.c라는 이름으로 저장하고 이를 컴파일 해보자!

 

 

그러면 이처럼 bof, bof.c 두 파일이 생기고 gdb를 이용할 수 있게 된다.

 

 

이제 분석해보자!

 

빨간색 박스를 보면 fgets와 strncmp 함수가 실행되기 전에 모두 3개씩 스택에 push하는데 이 값들은 각각

buf, 40, stdin / buf2, "go", 2를 의미한다. 

 

이때, cdecl이라는 함수 호출 규약을 사용하기 때문에 스택에 왼쪽 인자가 아닌 오른쪽 인자부터 들어가게 된다.

 

그러므로, 3번째로 push된 eax 값이 buf와 buf2의 주소라 할 수 있다.

 

/*

함수 호출 규약 (Calling Convention) 이란?

함수를 호출하는 방식에 대한 약속으로, 인자 전달 방법, 인자 전달 순서, 인자 정리 방법 등에 의해 종류가 나뉘어진다.

1. CDECL (C declaration)

-  x86 아키텍처용의 수많은 C 컴파일러가 사용하는 호출규약 

- 인자 전달 방법 : 스택프레임을 사용하여 인자를 전달한다.

 

- 인자 전달 순서 : 오른쪽에서 왼쪽 순으로 스택에 저장한다.

- 인자 정리 방법 : Caller(함수를 호출한 쪽)에서 스택에 저장된 인자를 정리한다.

- 가변인자 함수를 지원해준다.

* 가변인자 함수 : 인수의 개수와 타입이 미리 정해져 있지 않는 함수 (printf, scanf 등)

 

2. stdcall

3. fastcall

*/

 

고렇다면 스택의 모습은 다음과 같을 것이다.

 


 

이때, buf와 buf2의 주소는 16바이트만큼 차이나므로 buf에 16개 문자(1byte)를 입력해주고 go를 입력해주면 buf2에 go가 들어가게 된다.

 

bof 파일을 실행하고 aaaaaaaaaaaaaaaago를 입력해주면!

 

 

level 10의 비밀번호를 얻을 수 있다!

 

 

 

'Security > Pwnable' 카테고리의 다른 글

[FTZ] level 11 문제풀이  (0) 2020.02.25
함수의 프롤로그와 에필로그  (2) 2020.02.09
해쿨 핸드북 정리  (0) 2020.01.02