ipwn
[pwnable.kr] passcode 본문
Passcode문제이다.
읽어보니 컴파일 중 컴파일러가 경고를 했다는 것 같은데..
한 번 서버 접속을 해보자.
코드를 읽어보니 이름을 받아오고 passcode1 == 338150, passcode2 == 13371337일 경우 플래그를 읽어준다.
하지만 이상한 점이 있다.
scanf로 passcode1, passcode2를 입력 받는 부분을 보면 &연산자가 없다.
주소를 참조해서 변수에 입력을 하는 scanf인데, 변수의 주소가 아닌 그냥 passcode1, passcode2라는 변수를 넣었기에
그 변수의 값을 참조해 입력값을 받아온다는 것이다.
즉 이 곳에서 컴파일러가 경고문을 띄워줬다는 것을 알 수 있다.
만약 passcode1, passcode2의 변수에 원하는 주솟값이 있다면 그 주소안의 값을 덮어씌울 수 있게 된다.
이 부분은 main함수인데 빨간 부분을 보면 welcome 함수가 종료 된 후 스택을 정리한 뒤 바로 login함수를 호출을 한다.
즉 welcome함수와 login함수의 ebp는 같은 ebp값을 사용하게 된다.
welcome함수를 한 번 보겠다.
녹색 밑줄을 보면 esp에서 0x88(136)만큼의 공간을 확보를 한 것을 알 수 있고,
빨간색 밑줄을 친 부분 즉 ebp-0x70이 name의 시작주소이며 이 값이 scanf의 인자로 전달되는 것을 알 수 있다.
name은 100byte의 문자열이므로 ebp-0x70 ~ ebp-0xc까지가 name의 공간인 것도 알 수 있다.
login함수를 보니 passcode1의 값이 할당 된 공간은 ebp-0x10 ~ ebp-0xc까지
총 4byte의 공간을 사용한다는 것을 알 수 있다.
아까 name의 공간은 ebp-0x70 ~ ebp-0xc 까지 할당되었던 것을 알 수 있었는데, 즉 passcode1의 공간을
name을 입력 받을 때 미리 채워넣어줄 수 있다는 말이 되겠다.
하지만 그 뒤는 아무리 보아도 passcode2의 값을 우리가 조작할 수 있는 부분은 없어보인다.
그럼 어떻게 exploit을 할 수 있을까?
꼭 if문을 통과하지 않더라도 system("/bin/cat flag")를 실행할 수 있지 않을까?
가령 다른 함수의 got를 system("/bin/cat flag")의 주소로 바꿔버린다거나 말이다.
아까 scanf로 passcode1를 입력받는 부분을 보면, passcode1의 주소가아닌 passcode1의 값을 참조하기에
passcode1이 가르키는 위치의 값을 바꿔버릴 수 있다는 말이 된다.
이제 plt, got의 개념이 필요하다.
(plt, got 개념은 아래 블로그를 참조했다.)
https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/
https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/
코드를 보면 scanf로 passcode1을 입력받고, 바로 fflush함수가 실행된다.
이 함수의 got 부분을 가져와서 system("/bin/cat flag")로 바꿔버리면 flag가 읽어와질 것이다.
사실 처음 풀 때는 printf의 got 부분을 바꿔버렸지만 풀고 난 뒤 다른 분들은 어떻게 풀었나 하고 라업들을 보니,
다 fflush로 푸셨기에.. 나도 라업에서는 fflush로 풀겠다.
(참고로 fflush 함수는 파일 스트림의 버퍼를 지워주는 역할이지만, 이걸 클리어 하는데는 딱히 알 필요 없다.)
컴파일 방식마다 다르지만 라이브러리 함수를 호출할 때는 plt를 호출한 뒤 got로 점프해서 함수를 실행하게 된다.
함수의 첫 호출 때는 got로 이동한 뒤 어떤 행동(위의 블로그에 잘 설명되어 있다.)을 한 뒤 함수의 주소를 알아내고,
두 번째 호출 때 부터는 got에 함수의 실주소값이 적혀서 함수가 실행되게 되는 것이다.
즉 got에 다른 함수의 부분이 적혀있다면 다른 함수가 실행되게 된다는 의미이다.
fflush의 plt부분을 읽어봤다. fflush함수의 got는 0x804a004라는 것을 알아냈다.
이제 system("/bin/cat flag")의 위치만 알아내면 되겠다.
system("/bin/cat flag")의 주소는 0x080485e3이다.
이제 모든 것을 알아냈으니 payload를 작성해보자.
일단 dummy 96byte + fflush got + &system("/bin/cat flag")가 되겠다.
마지막 system("/bin/cat flag")의 값은 %d의 format으로 입력을 받으니 10진 값으로 바꿔서 넣어주면 된다.
한 번 맞는지 payload를 넣어 보겠다.
flag를 성공적으로 읽어왔다.
'Write up > Pwnable.kr' 카테고리의 다른 글
[pwnable.kr] blackjack (0) | 2018.01.03 |
---|---|
[pwnable.kr] random (0) | 2018.01.01 |
[pwnable.kr] flag (0) | 2017.12.31 |
[pwnable.kr] bof (0) | 2017.12.31 |
[pwnable.kr] collision (0) | 2017.12.28 |