LOB vampire Write-Up
LOB vampire 풀어보자.
이전 문제와 다른 점은 main 함수가 종료되기 전에 모든 argv 인자들을 지우고 있다. 환경변수도 지우고 있고, buffer 변수도 48bytes를 초과하면 프로그램이 종료되기 때문에 shellcode를 입력할 곳이 없다.
일단 main 함수의 어셈블리어 코드를 보면 strcpy 함수를 호출하기 전에 ebp-0x28 주소를 eax 레지스터에 저장하고 있다. 즉, 이 곳이 buffer 변수의 시작점이다.
따라서 스택은 위와 같이 형성될 것이고, strcpy 함수로 argv[1] 값을 buffer 변수로 복사하므로 44bytes를 입력하면 ebp까지 변조할 수 있다.
내가 입력한 값들이 메모리에서 모두 사라지는지 확인해보자. 디버깅하기 위해 skeleton 파일을 다른 이름(kkeleton)으로 복사해주었다. 그리고 [사진 4]에서 확인할 수 있듯이 main 함수가 종료하기 직전에 브레이크 포인트를 설정한다. 그리고 위와 같이 첫 번째 인자로 48번째에 "\xbf" 값을 입력하고 두 번째 인자에 shellcode 용도의 50bytes를 입력하였다. "x/s" 옵션으로 문자열 형태로 저장된 값을 볼 수 있는데, 메모리 끝까지 확인해야 하므로 "x/1200s" 정도 실행해보자.
메모리의 끝자락에 보면 내가 디버깅한 kkeleton 파일명이 남아있다. 이 곳에 shellcode를 입력해야 한다.
파일명에 shellcode를 입력하기 위해 심볼릭 링크를 이용하였다. 따라서 두 번째 인자는 필요없다. shellcode 앞뒤에 "\x90" nop 100bytes씩 입력한 것은 명령어를 구분하기 위함이다. 링크 파일을 디버깅하면 [사진 7]에서 확인했듯이 메모리 끝자락에 파일명이 있었으므로 출력을 많이 해줘야하는데 기존의 파일명보다 길어졌으므로 "x/1400s" 정도 실행해보자.
역시 메모리 끝에 내가 입력한 파일명(shellcode)이 남아있다. 주소는 0xbffffef3인데, shellcode 부분이 필요하므로 자세히 살펴보자.
위와 같이 shellcode 앞에 입력된 "\x90" nop 값을 확인할 수 있다. 주소는 0xbfffff03이다.
그리고 skeleton 파일을 다시 shellcode를 파일명으로 하는 심볼릭 링크 파일을 생성하고 위와 같이 입력하면 skeleton 계정의 password를 확인할 수 있다.