passcode - 10 pt
파일 목록을 보았다.
passcode@pwnable:~$ ls
flag passcode passcode.cpasscode.c의 내용은 아래와 같다.
passcode@pwnable:~$ cat passcode.c
#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;
}10번째, 15번째 줄을 보면 &가 없어 passcode1이나 passcode2에 값이 저장되는 것이 아니라 passcode1과 passcode2를 주소로 한 곳에 저장된다.
welcome()을 GDB로 살펴보면 아래와 같다.
13번째 줄 0x0804862f <+38>: lea -0x70(%ebp),%edx 를 통해 name이 [ebp - 0x70]에 저장됨을 알 수 있다.
login()을 GDB로 살펴보면 아래와 같다.
10번째 줄 0x0804857c <+24>: mov -0x10(%ebp),%edx을 통해 passcode1이 [ebp - 0x10]에 저장됨을 알 수 있다.
[ebp - 0x10] - [ebp - 0x70] = 0x60 = 96이므로 100보다 작기 때문에 4 byte 만큼 값을 덮어쓰는 것이 가능하다.
passcode1 에 fflush@got 주소를 넣고 scanf 입력으로 system("/bin/cat flag") 실행 주소를 넣으면 scanf("%d", passcode1) 실행 직후 system("/bin/cat flag") 이 실행된다.
즉, 아래와 같은 논리의 페이로드를 생각해볼 수 있다.
아래와 같이 fflush@got 주소를 알아낸다.
fflush@got 주소는 0x804a004이다.
login()을 disassemble 한 것의 33번째, 34번째 줄을 보면 아래와 같다.
system("/bin/cat flag") 의 실행 주소는 0x080485e3이다.
scanf("%d", passcode1) 의 표준 입력 형식이 %d 이므로 정수 값으로 넘겨주어야 한다.
0x080485e3는 decimal으로 134514147이다.
아래와 같이 입력해 플래그를 알아낸다.
Flag? : Sorry mom.. I got confused about scanf usage :(
Last updated
Was this helpful?