main 함수의 인풋은 배열의 크기인 argc와 argv 배열이다.
4byte 정수형 long i에 0x1234567(19088743)을 할당했다.
char 유형인 buf는 1024byte로 할당했다.
setuid 함수를 사용하여 level14의 uid 권한을 부여하였다.
if문을 수행하기 위해서는 agrc가 1초과여야 하며 if문 안에서는 strcpy 함수를 사용하여
사용자가 입력한 argv의 내용을 buf에 copy한다.
i 변수의 값이 0x1234567이 아닐 경우에 if문이 실행된다. if 문 안에서는
printf 함수로 "Warnning: Buffer Overflow !!! "을 출력해 위험을 알리고 프로그램을 종료시킨다.
[ 문제 풀이 과정 ]
1. 환경변수에 쉘코드를 저장하고 주소값을 알아내야한다.
2. 버퍼에서 변수 i까지의 거리와 변수 i에서 ret까지의 거리를 계산해야한다.
3. i 값을 검사하여 경고문구를 출력하는 것을 보아 i 변수를 다시 0x1234567로 돌려놔야 한다.
4. ret 위치의 값을 쉘코드로 바꾸는 페이로드를 작성해야한다.
먼저 attackme 파일을 ./tmp로 복사했다.
환경변수를 SHELL이라는 이름으로 등록하였고
제대로 등록이 되었는지 확인하였다.
test 코드를 작성하여 쉘변수의 주소값을 확인하였다.
SHELL 변수의 주소: 0xbffffc32
gdb 명령어로 attackme 파일을 분석했다.
이를 통해 스텍의 구조와 페이로드를 구할 수 있다.
[ 스텍 구조 ]
buf 1024 byte
dummy 12 byte // 1048 - 12 위치에 i가 존재하므로 12byte는 dymmy
i 4 byte // 0x1234567의 값이 유지되어야 함
dummy 8 byte // 변수 i 와 sfp 사이의 거리 12byte 이고 i는 4byte이므로 8byte는 dummy
SFP 4 byte
RET 4 byte // 이 직전까지 오버플로우를 일으켜 여기에 쉘코드가 입력되어야 함
[ 페이로드 ]
[ buf + dummy의 값 ] + [ i 값 ] + [ i 끝에서 ret 전까지의 값 ] + [ ret에 들어갈 쉘코드 주소값 ]
페이로드를 입력하여 쉘스크립트로 넘어왔고, id 명령어로 uid가 level14로 변했음을 확인했다.
my-pass를 입력해 얻은 패스워드는 "what that nigga want?"