티스토리 뷰

HackerSchool FTZ WARGAME Solution

 

Start : 15.07.03

 

LEVEL11

 

[그림 1]

 

hint 파일을 열어 attackme 프로그램의 소스를 확인 해 보면 main 함수에서 argv 값을 전달받아 str 배열에 복사하는 것을 확인할 수 있다.

 

[그림 2]

 

gdb를 이용해 attackme를 열어보면 sub esp, 0x108 즉 264byte 만큼 메모리 공간을 할당한다. 그리고 strcpy 함수 부분을 보면 [ebp-264]를 인자로 전달을 하는데 이게 곳 str 배열의 시작 주소라는 것을 확인할 수 있다.

 

 

[그림 3]

 

call strcpy를 하기 직전 stack을 간단하게 그려보면 [그림 3]과 같이 나타내지는데 strcpy 함수로 전달되는 인자값 중에 [ebp+12] + 4를 한 값을 push 하는데 [ebp+12]에는 main 함수의 argv 값인데 argv로 전달되는 문자열은 문자열이 복사되는게 아니라 문자열이 위치한 메모리의 주소값이 전달된다. 따라서 [ebp+12] 는 주소값이 있고 이 주소값에 4만큼 더한 값을 strcpy 로 전달한다. 그 이유에 대해서 생각해보면 c언어의 main 함수가 인자를 전달받을 때 프로그램 명도 하나의 인자값으로 받기 때문에 실제 프로그램에 전달되는 인자값은 argv[1]에 저장이 된다. 따라서 우리가 원하는 인자값을 strcpy에 전달하기 위해서는 [ebp+12]에서 4만큼 더한 곳의 값을 push 해야한다.

 

여기서 우선 쉘 코드를 메모리에 저장하고, strcpy를 이용해 버퍼 오버플로우를 발생시켜서 RET 값을 쉘 코드가 저장된 곳의 주소값으로 덮어 쓰는 방식으로 공격을 진행하려 한다.

 

[그림 4]

 

우리가 공격에 사용하는 쉘 코드를 우선 환경 변수에 저장을 한다. [그림 4]를 보면 그 명령어와 과정이 나와있는데 우선 바이너리로 전달하기 위해 perl을 사용했다. 특이한점은 \x90 (NOP)를 쉘 코드 앞에 100개 만큼 넣은 다음, 쉘 코드를 이어서 저장하는데 이 이유는 환경 변수의 주소는 파일명이나 실행하는 경로 등에 의해 약간씩 변하게 된다. 그렇기 때문에 우리는 공격을 확실하게 성공하기 위해 쉘 코드 앞에 "\x90"x100을 입력해 주었다.

 

[그림 5]

 

export를 입력해 환경 변수가 정상적으로 입력이 되었는지 확인할 수 있다.

 

[그림 6]

 

그리고 간단하게 환경 변수의 주소를 출력하는 프로그램을 [그림 6]과 같이 작성을 하고, 컴파일러를 한다.

 

[그림 7]

 

그리고 만들어진 프로그램으로 우리가 추가한 한경 변수의 주소가 [그림 7]과 같이 출력이 된다.

 

[그림 8]

 

그리고 이어서 attackme 프로그램에 공격 코드를 전달하면 되는데 여기서도 마찬가지로 바이너리 값을 전달하기 위해 perl을 사용했다. 코드를 분석해 보면 A를 268개를 프로그램에 전달해서 EBP 값까지 다 덮은 다음, RET 값을 앞에서 봤던 shellcode 의 주소값으로 전달하면 공격에 성공한다.

 

이 때 주의점은 cpu가 리틀엔디언 방식으로 데이터를 읽기 때문에 1byte 단위로 거꾸로 전달해야 한다.

 

 

신고
댓글
댓글쓰기 폼