LOB nightmare Write-Up
LOB nightmare 풀어보자.
주어진 코드를 보면 스택, 바이너리, 라이브러리 영역을 사용할 수 없다. 그런데 이전 문제들과는 달리 buffer 변수 값을 argv 인자가 아닌 fgets 함수와 stdin 표준 입력을 이용하여 입력받는다. fgets 함수와 같이 표준 입력을 받는 함수들은 자신만의 임시 버퍼에 입력 값을 저장하고, 변수에 해당 값을 저장한다. 그리고 라이브러리 영역을 "\x40" 값이 아니라 "\x90" 값으로 제한하는 것으로 보아 stdin 입력 버퍼 공간인 0x40~ 주소를 이용하면 될 것 같다.
먼저 main 함수의 어셈블리어 코드를 보면 fgets 함수를 호출하기 전에 ebp-0x28 주소를 eax 레지스터에 저장한다. 즉, 이 곳이 buffer 변수의 시작점이다. 그리고 stdin 표준 입력 버퍼의 주소는 0x08049a3c임을 알 수 있다.
스택은 위와 같이 형성될 것이고, 표준 입력을 이용해 44bytes를 입력하면 ebp까지 변조가 가능하다.
xavius 파일을 백그라운드로 돌리고 메모리 구조를 보면 위와 같이 빨간 박스만 사용할 수 있다. 나머지는 코드상에서 제한되어 있다.
디버깅하기 위해 xavius 파일을 다른 이름(kavius)으로 복사하였다. 그리고 fgets 함수가 끝난 직후에 브레이크 포인트를 설정하고 실행하여 표준 입력으로 문자 "A"을 수십개 입력하였다.
그리고 stdin 표준 입력 버퍼의 주소인 0x08049a3c를 따라가다 보면 0x40015000 주소에 표준 입력을 통해 입력한 값들이 저장되어 있는 것을 확인할 수 있다.
프로그램 종료 직전에도 값이 저장되어 있는지 확인해보았는데, 여전히 저장되어 있다.
따라서 위와 같이 임의의 값 "\x90" 44bytes와 표준 입력 값이 저장되는 "\x00\x50\x01\x40" 값으로 ret를 변조한다. 그리고 shellcode 25bytes를 입력하면 xavius 계정의 password를 확인할 수 있다. 사용한 shellcode는 다음과 같다.
\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