#About


[그림 1] - Troll.c 소스 코드 확인




#Solution


[ + ] 소스 코드 해석


1. 외부 다른 소스파일에 있는 environ 포인터 변수 사용


2. buffer라는 배열에 40바이트 및 변수 i 선언


3. 조건문을 통해 인자 값을 검사하며 2개가 아니라면 argc must be two!를 출력 후 종료


4. 반복문을 이용하여 환경변수에 담긴 값의 길이만큼 메모리에서 초기화


5. 조건문을 통해 사용자 입력 값 중 48번째 바이트가 \xbf가 아니면 stack is still your friend.를 출력하고 종료


6. 사용자 입력 값인 첫 번째 인자 값의 길이가 48바이트가 넘어가면 argument is too long!을 출력하고 종료


7. 사용자 입력 값을 buffer에 복사 후 buffer에 들어있는 사용자 입력 값 출력


8. memset 함수를 이용하여 buffer 값 전부 초기화


9. memset 함수를 이용하여 argv[1] 모두 초기화


이전과 다른 점이라면 argc가 반드시 2개가 되어야하며, argv[1]의 값을 전부 초기화시킨다. 이는 인자에 argv[0] 즉, 실행 파일 이름을 셸 코드로 설정한 뒤 RET을 argv[0]의 시작 주소로 변조함으로써 문제를 해결할 수 있고 그 과정은 아래와 같다


[그림 2] - argv[0]을 셸 코드로 설정


위 그림은 argv[0]를 \x90과 셸 코드로 입력해주었으며, argv[0]의 시작주소를 현재 알지못하므로 RET 주소를 임의의 값을 넣어줌으로 인해 


아래와 같이 Segmentation fault이 일어나며 core 덤프 파일을 얻을 수 있었다 


[그림 3] - core dump


core 덤프 파일은 프로그램이 비 정상적으로 종료 또는 충돌 시에 특정 시점에 기록된 작업 메모리 파일이며 


쉽게 말해 프로그램 오류 진단 및 디버깅으로 사용한다 기본적으로 core 덤프 생성은 비 활성화가 되어있으므로 


ulimit -c unlimited 명령으로 활성화 시키며, ulimit -a 명령으로 core 덤프 파일의 최대 사이즈를 확인할 수 있다


[그림 4] - ulimit 명령 사용


core 덤프 파일을 분석하기 위해 -c 옵션을 이용해 core 파일을 gdb상에 올려주었으며, 아래와 같이 argv[0]의 시작주소를 확인할 수 있었다


[그림 5] - argv[0]의 시작 주소 확인


정확히는 ./를 의미하는 2e2f가 시작이지만 셸 코드를 실행시키기 위해 NOP SLED의 시작지점인 0xbffffa73으로 설정했다


따라서 RET 주소를 0xbffffa73으로 변조해주었고 아래와 같이 셸을 획득할 수 있었다


[그림 6] - orge 권한의 셸 획득


셸 획득을 확인했으므로 troll의 셸을 획득하기 위해 아래와 같이 복사했던 파일을 삭제해준 뒤 새로이 troll의 링크 파일로 설정해주었다


[그림 7] - troll의 복사 파일 삭제


[그림 8] - troll의 링크 파일 설정


[그림 9] - 셸 획득




기존에 사용하던 24byte 셸 코드에는 \x2f 즉 디렉터리 구분자를 의미하는 /가 포함되므로 정상적으로 링크 파일을 생성할 수 없으므로 


\x2f를 포함하지 않고 위 문제 해결에 사용한 셸 코드는 아래와 같다 (48byte)


\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff

\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81




[ + ] 덧 붙임


문제를 해결함에 있어 막혔던 부분 때문에 3일이나 걸렸으며 저와 비슷한 실수를 하지 않길 바라는 마음에 씁니다.


RET 주소를 구했더니 처음에 0xbffffc20 였는데 RET에 덮어 씌워줬더니 계속 없는 디렉터리 또는 파일이라는 오류가 떠서 


한참을 헤맸었는데 생각하다보니 \x20이 10진수로 32고 아스키 문자로 띄어쓰기를 의미하므로 계속 오류가 났었음


또한 NOP 개수를 조절함으로써 변경 후 RET 값이 0xbfffffc0a로 마지막 바이트가 줄 바꿈 문자여서 오류가 나기도 했었음



+ Recent posts