문제

Mommy told me to make a passcode based login system.
My initial C code was compiled without any error!
Well, there was some compiler warning, but who cares about that?

ssh passcode@pwnable.kr -p2222 (pw:guest)


분석

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;   
}

처음 봤을 때는 passcode1에 338150을 넣고 passcode2에 13371337을 넣으면 끝나는 문제 아닌가? 싶다.

하지만 아래의 코드를 유심히 보자.

scanf("%d", passcode1);

!!!

&passcode1이어야 하는데 왜 passcode1인건가!! '&' 어디 있어!

이건 passcode2를 입력받을 때도 마찬가지이다.


하.. 어떻게 해야 될까.

즉, 이런 상황이다.

passcode1에는 현재 쓰레기 값이 들어있는데 저 scanf가 실행되면 우리의 입력은 그 쓰레기 값을 주소로 참조하여 거기 적힐려고 시도될 것이고 아마 그 쓰레기 주소에는 permission이 없어서 에러가 날 가능성이 높다.


실제로 Segmentation fault가 나는 모습


이렇듯 아무 조치 없이 scanf를 실행시키면 안된다.

그렇다면 우리는 passcode1에 쓰레기 주소가 아닌 유효한 주소를 넣어놓으면 된다. 그 작업은 welcome 함수의 name 변수를 이용하면 된다.

name 변수가 사용한 스택이 login함수에서도 쓰이기 때문!


FL4G

방법은 이렇다.

passcode1의 자리에다가 fflush의 got 주소를 적어놓자.

그리고 passcode1을 입력받을 때 system("/bin/cat flag")의 위치를 넣어주면 끝!

fflush가 실행되려는 순간 flag가 읽히기 때문에 passcode2는 생각할 필요도 없다.


gdb로 찾아보니 name의 시작위치와 passcode1의 위치는 0x60만큼 차이난다.

fflush의 got는 0x804a004

system("/bin/cat flag")의 위치는 0x080485E3 (=134514147)

FL4G 읽기에 성공했다!

(이 캡쳐는 로컬에서 본인이 직접 만들어 놓은 flag 파일을 읽은 것이고 똑같은 payload를 서버에서 실행할 경우 마찬가지로 flag를 읽을 수 있다.)

'pwnable.kr' 카테고리의 다른 글

[Toddler's Bottle] input writeup  (0) 2018.09.16
[Toddler's Bottle] random writeup  (0) 2018.09.15
[Toddler's Bottle] passcode writeup  (0) 2018.09.15
[Toddler's Bottle] flag writeup  (0) 2018.09.15
[Toddler's Bottle] bof writeup  (0) 2018.09.15
[Toddler's Bottle] collision writeup  (2) 2018.09.14

+ Recent posts