먼저 ls 명령어로 어떤 파일이 들어있는지 확인하였다.
flag, passcode, passcode.c 파일이 들어있다.
가장 먼저 passcode 파일을 실행하 보았다.
이름을 입력하면 환영한다는 인사말이 나오고
비밀번호를 입력했더니 segmentation fault가 난다.
passcode.c 파일의 내용을 확인했다.
먼저 passcode1, passcode2 변수를 선언하고 사용자에게 값을 입력받아 각각 두 변수에 대입한다.
if 문을 통하여 passcode1은 338150, passcode2는 13371337값과 비교한 후
두 값이 모두 일치할 경우 로그인이 되고, flag를 출력한다.
그렇지 않을 시 로그인이 실패했다는 내용을 출력하고 종료한다.
* fflush 함수
- 스트림에 할당된 버퍼를 비우는 명령
- 함수 호출 이후에도 스트림은 열려 있는 상태로 남아있음
- fclose 호출 등으로 파일이 닫히게 될 경우 버퍼는 자동적으로 비워짐
- fflush(stdin): 입력 버퍼를 비우는 행동, 해당 내용을 완전히 삭제하고 새로운 입력을 받도록 준비
- fflush(stdout): 출력 버퍼를 비우는 행동, 버퍼의 내용을 해당 출력 스트림으로 완전히 출력시키는 것
welcome 함수에서는 name 배열을 100byte 크기로 선언했고
name을 입력받아 name 변수에 대입한 이후에 welcome name을 출력한다.
main 함수에서는 문장을 출력하고 각각 welcome과 login 함수를
실행한 이후에 문장을 출력하고 종료한다.
앞서 나온 login 함수에서 원하는 임의의 값을 대입하면 되지만
그렇게 푸는 문제였다면 passcode.c 파일을 제공하지 않았을 것이기 때문에
gdb 명령어로 passcode 파일을 분석해 보려고 한다.
main 함수를 분석한 내용이다.
welcome 함수를 분석한 값이다.
<+38>을 보면 "enter name:"에서 입력받은 값을 저장하는 장소를 알 수 있다.
100byte까지 받을 수 있는 name 값이 저장되는 위치는 ebp - 0x70이다.
이는 login 함수를 분석한 내용이다.
<+24> 의 내용을 보면 passcode1의 값을 %ebp-0x10에 저장하는 것을 알 수 있다.
앞서 name 변수를 저장하는 공간이 %ebp - 0x70 이었으므로 이 값과 비교해보면
0x70 - 0x10 = 0x60(96)임을 알 수 있다. nama에 100byte를 할당했으므로 4byte가 비는 것이다.
앞서 name을 입력하라고 했던 곳에 A를 100개 입력하면 4byte는 다른 값으로 씌워질 것이고,
그 값은 passcode1의 값이라는 것을 알 수 있다.
이 4byte를 조작하면 fflush를 사용하여 내가 원하는 함수를 실행시킬 수 있을 것이다.
나는 flag의 값을 출력해야 하므로
내가 이 부분에 대입하고 싶은 값은 system("/bin/cat flag")의 주소값이다.
먼저 system의 주소 값은 0x080485e3이다.
fflush got의 주소값도 gdb를 통하여 알아낼 수 있었다. 0x804a004이다.
passcode1 자리에 원하는 값을 넣기 위해 passcode1 입력 이후에 실행되어지는
fflush(stdin) 라인 부분에 system(/bin/cat/flag); 가 시작되는 주소를 넣었다.
위의 방식으로 페이로드를 작성했고 이후 system의 주소 값을 대입하였으나
원하는 대로 동작하지 않았고 *정수값으로 바꾼 후에 다시 대입하였더니
flag 값을 얻을 수 있었다.
* scanf에서 %d로 받아드리기 때문
끝 !