[pwnable.kr] 3번_bof 풀이
포너블 3번_bof 문제 풀이
시스템 해킹에서 중요하게 다뤄지는 버퍼오버플로우 문제이다.
일단 앞서 풀었던 두 문제와 처음부터 다르게 생겨 어떻게 시작을 해야할지부터 고민했다.
먼저 위의 두 파일을 다운로드 받아야하기 때문에 wget명령어를 통해 다운로드 받았다.
아래의 Running at : nc pwnable.kr 9000은
nc(net cat)은 TCP나 UDP 프로토콜을 사용하는 네트워크 연결에서 데이터를 읽고 쓰는
간단한 유틸리티 프로그램으로 대부분의 리눅스에 기본적으로 탑재되어 있다.
일반적으로 Unix의 cat과 비슷한 사용법을 가지고 있지만 nc는 네트워크에 읽거나 쓰며, 이 명령어를
스크립트와 병용하여 네트워크 디버깅, 테스팅 툴로 사용하며 해킹에도 많이 사용하는 프로그램이라고 한다.
하지만 여기서 nc pwnable.kr 9000 입력해보니 별 반응이 없었다.
ls 명령어로 파일을 확인해보니 다음과 같이 나타났다.
다운로드 받은 파일 모두 root 권한이었다.
bof.c 파일의 내용을 출력한 결과이다.
func 함수와 main 함수로 나뉘는데 main에서 func 함수를 실행할 때, 0xdeadbeef라는 정수를
전해주고 func 함수는 그 값을 전달 받아 key 값에 변수로 저장한다.
그 후 "overflow me : "라는 문구를 출력하고
overflowme라는 32의 크기를 가진 공간에 사용자로부터 입력받은 문자를 저장한다.
key 값이 0xdeadbeef라면 /bin/sh를 실행시키고
아닐 경우에 Nah...문자를 출력시키고 나서 프로그램은 종료된다.
이 코드가 가진 문제는 gets() 함수인 걸 알 수 있다. 옆에 친절하게 smash me! 라고 힌트도 함께 있다.
gets() 함수는 표준 입력에서 문자열을 입력 받아 사용자가 전달한 메모리에 저장하는 함수이다.
하지만 이 코드에서는 입력값에 대한 경계값 검사를 하지 않기때문에 버퍼 오버플로우의 가능성을 열어두어야한다.
gets() 함수를 이용하여 버펑오버플로우 공격을 해서 공격자가 원하는 주소를 0xdeadbeef로 덮어 씌우면 되는데,
얼마만큼의 공간을 채워야하는지 알아야한다.
문제에서 주어진 바이너리를 가상환경에 올려서 gdb를 통해 분석을 해보았다.
main 함수에서가 아니라 func 함수에 주력해야하기 때문에 func 함수를 디스어셈블한다.
함수 코드를 보면 비교하는 cmp 문을 확인할 수 있다. <+40> 부분이다.
func+29위치에서 overflowme[32]는 ebp로부터 0x2c만큼 떨어져 있는 상태고,
func+40의 위치를 통해 key는 ebp로부터 0x8 만큼 떨어져 있는 것을 알 수 있다.
overflowme 문자열을 이용해 key를 덮어야 하기 때문에 overflowme 부터 key 사이의 거리를 구하면
44 + 8 = 52 만큼의 크기가 나온다.
52개의 쓰레기 값을 집어 넣어 문자를 덮는다면 공격이 성공할 것이다.
쓰레기 값 52개와 cafebabe라는 값을 입력하니 /bin/sh이 정상적으로 실행되었다. 또한,
입력시 셸의 권한을 취득하여 ls 명령어를 입력해야한다. 여기서는 nc 명령을 통해 사이트에 셸권한을 얻었다.
제대로된 포너블 문제는 이제부터 시작인 것 같은데, 벌써부터 너무 어렵다고 느껴진다...!
gdb를 이용해 문제를 푼게 처음이다 보니 구글링도 많이 해가면서 풀었다. 아직은
혼자 풀 수 있는 실력이 되지 않아 문제를 풀면서 많이 공부해봐야겠다...