이번에도 힌트를 열어 확인해보면 /usr/bin/bof의 소스코드를 볼 수 있다.
간단하게 해석하면 buf배열에 40바이트 이하의 키보드 입력을 받고 buf2배열에 go가 들어가 있으면 Good Skill이라는 문자열을 출력하고 level10권한 부여 후 배시셸을 실행시키는 코드이다.
그런데 여기서 주의해서 봐야 할 점은 buf배열의 크기가 10바이트 라는 것이다.
buf배열의 크기는 10바이트인데 fgets()함수로 40바이트 이하의 키보드 입력을 받고 있다.
힌트에서 얻은 소스코드를 bof.c라는 파일로 복사하고 지역 변수가 스택에 배치되는 위치를 알 수 있도록 아래와 같이 밑줄친 소스를 한줄 추가한다.
그리고 실행해보면
buf의 주소는 0xbffff7e0 buf2의 주소는 0xbffff7f0이라고 나온다.
즉, 0x10(16)바이트 만큼 떨여져 있다는 것을 확인할 수 있다.
이해하기 쉽게 그림으로 표현하면 아래와 같다.
높은 메모리 주소 |
RET |
4 bytes |
|
|
SFP |
4 bytes |
|
dummy |
6 bytes |
||
buf2[10] |
10 bytes |
||
dummy |
6 bytes |
||
낮은 메모리 주소 |
buf[10] |
10 bytes |
buf2 배열에 go라는 문자열이 들어가야 하기 때문에 buf 배열을 오버플로우 시켜야한다.
즉,buf배열을 넘어서 dummy까지 덮어 쓴 후 buf2에 go라는 문자열이 들어가도록 하면 된다.
bof를 실행시켜 AAAAAAAAAABBBBBBgo를 입력하면 아래와 같이 문자열이 들어가게 된다.
높은 메모리 주소 | RET | 4 bytes | | |
| SFP | 4 bytes | ||
dummy | 6 bytes | |||
buf2[10] | 10 bytes | go | ||
dummy | 6 bytes | BBBBBB | ||
낮은 메모리 주소 | buf[10] | 10 bytes | AAAAAAAAAA |
AAAAAAAAAABBBBBBgo를 입력하여 오버플로우 시키게 됨으로써 level10의 쉘을 실행시킬 수 있게 되었다.