[pwnable.kr] passcode write up
포너블에 대한 감을 키우기 위해서 다시 포너블.kr 문제들을 풀어보고 있다.
예전에 풀 때와 느낌이 확실히 달라서 기록하려고 글을 쓴다.
passcode
#include <stdio.h> #include <stdlib.h> void login(){ int passcode1; int passcode2; printf("enter passcode1 : "); scanf("%d", passcode1); fflush(stdin); // ha! mommy told me that 32bit is vulnerable to bruteforcing :) printf("enter passcode2 : "); scanf("%d", passcode2); printf("checking...\n"); if(passcode1==338150 && passcode2==13371337){ printf("Login OK!\n"); system("/bin/cat flag"); } else{ printf("Login Failed!\n"); exit(0); } } void welcome(){ char name[100]; printf("enter you name : "); scanf("%100s", name); printf("Welcome %s!\n", name); } int main(){ printf("Toddler's Secure Login System 1.0 beta.\n"); welcome(); login(); // something after login... printf("Now I can safely trust you that you have credential :)\n"); return 0; }
일단 취약점이 터지는 코드는 scanf() 함수이다.
scanf()에서는 값을 받을 주소값으로 받지만,
이 코드에서는 주소값으로 받지 않았기 때문에 취약점이 발생한다.
내가 처음에 시도했던 것은 welcome()에서 스택에 값을 저장하고,
passcode1과 passcode2를 name을 저장했던 주소값을 지정해주려고 했었다.
하지만,,,,
ASLR이 적용되어 있었기 때문에 exploit할 수 있는 확률이 정말 적었다.
그래서 다른 취약점을 이용하려고 했다.
만약 welcome() 에서 스택에 입력받은 값들이 passcode1의 값에 영향을 줄 수 있다면?
GOT Overwrite가 발생할 수 있을 것이다.
$ebp - 0x70 값이 name 변수를 가리키고 있다.
이렇게 해서 확인했다.
그리고
여기에서는 passcode1의 값이 $ebp - 0x10의 주소값이 가리키는 값이라고 말할 수 있으며,
name[96~99] 의 값이 저장되어 있는 것을 알 수 있다. (초기화를 안했기 때문이다.)
그리고 우리는 Overwrite 하고자하는 값을 4byte 만큼 덮어쓸 수 있다.
그렇다면 fflush()의 got를 overwrite해서 login() 함수 상의 system()를 쓰는 코드로 바꿔놓으면 개꿀밥도둑.
이 exploit을 하기 위해서는 fflush@got의 주소와 system()의 주소를 알아와야한다.
fflush@got : 0x804a004
system("/bin/cat flag") : 0x080485e3
그럼 이제 익스플로잇을 해보자!
참고로 system()의 주소를 10진수로 쓴 이유는 scanf("%d", passcode1); 이었기 때문에 10진수로 넘겨주었다.
'write-ups > pwnable.kr' 카테고리의 다른 글
pwnable.kr uaf (0) | 2018.02.11 |
---|---|
pwnable.kr coin1 write up (0) | 2017.07.07 |
pwnable.kr cmd2 write up (0) | 2017.07.05 |
pwnable.kr blackjack write up (0) | 2017.07.05 |
pwnable.kr cmd1 write up (0) | 2017.07.05 |