#About


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




#Solution


[ + ] 소스 코드 해석


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


2. buffer라는 배열에 40바이트 할당


3. 변수 i와 saved_argc에 각 4바이트씩 할당


4. 조건문을 통해 전달 인자가 2개 미만이면 argv error를 출력 후 종료


5. 반복문을 통해 환경변수 전부 초기화


6. 사용자 입력 값의 48번째 바이트가 \xbf가 아닐 시, stack is still your friend.를 출력 후 종료


7. 사용자 입력 값의 길이가 48 바이트를 넘으면 argument is too long!을 출력 후 종료


8. 사용자가 사용한 인자의 개수를 saved_argc에 담음


9. 사용자 입력 값을 버퍼에 복사 후 출력


10. memset 함수를 통해 buffer 모두 초기화


11. 반복문과 memset 함수를 이용해 사용자가 전달한 인자의 개수와 그 길이만큼 전부 초기화


이번 문제는 buffer 및 사용자가 입력한 인자를 모두 초기화 시키기 때문에, 실행 파일 명은 메모리의 끝 부분에서 초기화 되지 않는 다는 점을 이용해서 문제를 해결할 수 있다


[그림 2] - 초기화 되지 않은 실행 파일 명 확인


실제로 위와 같이 임의의 값을 넣어 core 파일을 생성한 뒤, 스택의 끝 부분 즈음에 살펴보면 실행 파일 명은 초기화되지 않은 것을 확인할 수 있다


 따라서 실행 파일 명을 아래와 같이 NOP과 셸 코드로 작성한 뒤 링크를 걸어주고 core 파일을 생성했으며 사용한 셸 코드는 아래와 같다


\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] - core 덤프 파일 생성 확인


현재 메모리 구조인 | buffer (40) | EBP (4) | RET (4) |에서 RET 주소를 셸 코드가 담긴 링크 파일명의 시작 주소로 변조하기 위해 core 파일을 분석했다


[그림 4] - core 파일 분석


셸 코드가 담긴 실행 파일 명의 시작 주소는 위에서 확인할 수 있듯 0xbffffff01이며 파일의 실행을 위한 ./를 고려한다면 0xbffffff03이 될 것이다 따라서 RET 주소는 0xbfffffff03이 되며, 아래와 같이 RET 주소를 변조해주었을 때 셸을 획득할 수 있다


[그림 5] - vampire 권한의 셸 획득


위와 같은 방법으로 skeleton에 심볼릭 링크를 걸어준 뒤 진행하면 셸을 획득할 수 있고 /home/vampire/tmp/에서의 메모리


주소와 /home/vampire/에서의 메모리주소는 다르지만, 셸 코드 앞 100 바이트의 NOP 때문에 4 바이트의 tmp/는 상관없이 셸 획득 가능


[그림 6] - 셸 획득


+ Recent posts