Lord of BOF_3_Goblin

소스코드의 내용은 다음과 같다.

핵심 알고리즘은 다음과 같다.
- main함수 인자를 받는다.
- environ 전역변수가 가리키는 주소에 저장된 주소가 가리키는 곳의 데이터를 0으로 바꾼다.
argv[1]의 48번째 글자가\xbf가 아니면 종료한다.- strcpy로 스택에 main함수의
argv[1]를 복사한다.
주목할 점은 memset을 하는 부분이다. environ이 어떤 주소를 가리키는 지 알아볼 필요가 있다.
gdb를 이용하여 알아보았다.

빨간 네모에 속한 부분이 environ 변수를 이용해 memset하는 루틴이다.
반복적으로 사용되는 0x8049750 주소가 바로 environ 변수의 주소임을 알 수 있다.

0x8049750 주소에 무엇이 저장되어 있는지 보았다.
environ 변수는 더블 포인터 변수이므로, 0x8049750 주소가 가리키는 위치에는 또 다른 주소가 저장되어 있다.
environ 변수가 저장하고 있는 주소는 0xbffffb8c이다.
다시 0xbffffb8c 주소에 무엇이 저장되어 있는지 살펴보자.

0xbffffb8c 주소에는 또 다른 주소가 저장되어 있다. (environ가 더블 포인터임을 기억하자)
다시 0xbffffc88 주소에 무엇이 저장되어 있는지 확인해 보자.

이 주소는 바로 환경변수 문자열의 주소이다.


다시 같은 주소부터 시작하여 많은 수의 문자열을 뽑아보았다.
environ 변수가 가리키는 배열은 환경변수 문자열의 주소를 가지고 있는 배열이라는 것을 알 수 있다.
사실 외부에서 가져온(extern 키워드를 통해 알 수 있다) 전역변수인 environ 변수는 libc에 정의되어 있는 전역변수이다.
envrion 변수는 앞에서 확인한 것과 같이 환경변수 문자열 주소 배열의 주소를 가지고 있는 변수이다.
즉, environ 변수를 이용하여 memset 함수를 호출하는 루틴은, 환경변수 문자열을 전부 0으로 만드는 루틴이라고 할 수 있다.
이는 환경변수를 이용한 exploit은 할 수 없음을 의미한다.
stack BOF를 하기 위해 strcpy에 들어가는 주소를 찾아보자.

ebp-40의 주소가 들어감을 알 수 있다. 즉, 버퍼를 채우기 위한 40바이트와, EBP backup 자리의 4바이트 뒤에 return address를 조작할 수 있다.
이는 첫 번째 메인 인자의 45~48번째 글자에 return address의 주소가 들어감을 의미한다. 여기서 “main함수의 첫 번째 인자의 48번째 글자가 \xbf가 아니면 종료한다.” 라는 조건이 이용된다.
리틀 엔디안으로 저장해야 하므로, 48번째 글자에는 주소의 맨 앞 2자리가 들어간다. 이 2자리가 \xbf이면 스택 주소이다.
따라서 이 조건은 return address에 스택 주소를 이용해야한다는 조건이 된다. 이 문제는 스택 주소를 이용하되, 환경변수는 이용할 수 없는 조건을 걸고 있다.
이에 맞춰 스택에 셸 코드를 넣고, return address를 스택의 주소로 넣어주었다.
예외를 일으켜 core파일을 만들고, 이를 이용해 셸 코드가 들어갈 주소를 알아내었다.

심볼링 링크 파일을 만들고 익스플로잇 했다.

orc의 비밀번호는 cantata이다.
tags: writeup, pwnable, buffer overflow, stack overflow, memory corruption, elf file, linux, c lang, x86asm