cgy12306

[pwnable.kr] passcode 본문

Wargame/pwnable.kr

[pwnable.kr] passcode

cgy12306 2020. 1. 26. 22:40

[passcode]

welcome() 함수를 호출하고, login() 함수를 호출한다.

welcome() 함수에서는 name 변수를 100byte만큼 할당해주고, 입력을 받는다.

login() 함수에서는 passcode1 변수에 값을 입력하고, fflush() 함수로 스트림의 버퍼를 비워준다.

이후 다시 passcode2 변수에 값을 입력하고, passcode1은 338150을 passcode2는 13371337과 비교해서 같으면 /bin/cat flag 명령어를 실행한다.

하지만 저 위에서 scanf의 사용법이 잘못 되었다.

원래라면 scanf("%d", &passcode1); 로 작성 되어야 하지만 &가 빠져있다.

이 말은 passcode1의 주소에 값을 넣는게 아닌 passcode1이 가지고 있는 값을 주소로 이용하여 해당 주소안에 값을 넣겠다는 말이다.

그렇다면 우리는 if문에 들어가기도 전에 system 함수를 호출할 수 있다는 말이 된다.

우선 name에 A를 100개 정도 입력해보자.


이후 login 함수의 스택상황을 보면


name 변수의 값이 넘어오는 것을 볼 수 있다.


passcode1 값을 입력받을 때 [ebp-0x10]의 값을 이용해서 받는 것을 볼 수 있다.


ebp의 주소 값은 0xffd38428이다. ebp-0x10지점의 주소는 0xffd38218이다. 이 지점은 name[96] 부분인 것을 알 수 있다. 즉, name[96] 지점은 passcode1이 입력되는 곳이다.

passcode1의 값으로 got를 overwrite 할 것이다.

plt는 프로그램에서 함수를 호출할 때 참조하는 테이블이고, got는 실제 함수의 주소를 가지고 있는 테이블이다.

plt를 참조할 때 got로 점프를 하게 되는데 이 점프하는 부분을 system() 함수가 시작되는 코드의 주소로 덮어쓰면 된다.


0x8048430을 호출하는데 이 주소는 plt의 주소이다.


plt안에서 0x804a004로 점프를 하게 된다. 내용은 아래와 같다.


이 0x804a004를 system() 함수가 시작되는 부분의 주소로 overwrite 하면 된다.


system() 함수를 호출하기 전에 [esp]에 0x80487af를 넣는데 이 부분을 확인해 보면 /bin/cat flag 명령어가 들어가 있는 것을 확인할 수 있다.


그러면 0x80485e3을 passcode1에 넣어주면 된다.

다시 정리해보면 fflush의 got를 system("/bin/cat flag")의 주소로 덮어 씌우면 된다.

passcode1을 입력받을 때 10진수로 입력을 받기 때문에 0x80485e3을 10진수로 바꿔줘야 한다.





'Wargame > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] input  (0) 2020.01.26
[pwnable.kr] random  (0) 2020.01.26
[pwnable.kr] shellshock  (0) 2020.01.26
[pwnable.kr] mistake  (0) 2020.01.26
[pwnable.kr] leg  (0) 2020.01.26
Comments