본문 바로가기

CTF_Write_UP/pwnable.kr

pwnable.kr : col 풀이

 

시작

지난번에 이어서 col을 풀어도보록 하겠습니다!

overthewire 문제만 보다가 pwnable.kr 푸니깐 많이 어렵네요..

Daddy told me about cool MD5 hash collision today.

I wanna do something like that too!

root@goorm:/# ssh col@pwnable.kr -p2222

Write UP

col@ubuntu:~$ ls -l
total 16
-r-sr-x--- 1 col_pwn col     7341 Jun 11  2014 col
-rw-r--r-- 1 root    root     555 Jun 12  2014 col.c
-r--r----- 1 col_pwn col_pwn   52 Jun 11  2014 flag

ls로 보니깐 fd와 똑같이 3개의 파일이 있네요.

col 먼저 실행시켜 보죠!

col@ubuntu:~$ ./col
usage : ./col [passcode]

col@ubuntu:~$ ./col 1234
passcode length should be 20 bytes

col@ubuntu:~$ ./col 01234567890123456789
wrong passcode.

./col [passcode] 형태로 사용하고 passcode20 bytes 라고 주어졌습니다.

소스를 한 번 볼까요?

col@ubuntu:~$ cat col.c
#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}

int main(int argc, char* argv[]){
        if(argc<2){
                printf("usage : %s [passcode]\n", argv[0]);
                return 0;
        }
        if(strlen(argv[1]) != 20){
                printf("passcode length should be 20 bytes\n");
                return 0;
        }

        if(hashcode == check_password( argv[1] )){
                system("/bin/cat flag");
                return 0;
        }
        else
                printf("wrong passcode.\n");
        return 0;
}

main 함수에서 0x21DD09EC로 선언된 hashcode 변수와

첫 번째 인자값인 argv[1]check_password로 넘겨서 반환된 값이 같으면

flag 파일을 보여주는 코드네요.

그럼 check_password 함수를 볼까요?

unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}

인자로 받은 char형 배열 pint형으로 형변환 후 ip배열의 시작 주소로 넣어주네요.

res 변수에 반복문을 통해서 ip의 5개의 요소들을 더합니다.

 


 

우리는 argv[1]20 bytespasscode를 입력해야 합니다.

  • int 형 변수 : 4 bytes

  • char 형 변수 : 1 bytes

여기서 argvchar 타입이죠?

때문에 check_passcode 함수에서 intip에 대입 시 4 bytes씩 나누어져 저장됩니다.

5개의 요소를 더하는지 이해가 가시죠??

그러므로, 4 bytes씩 나누어 int로 더한 값이 hasecode와 같으면 됩니다.

계산기를 켜기 귀찮아서! 코드를 짰습니다!! :D

root@goorm:/workspace/LCH_Server# cat calc.c
#include <stdio.h>

int main(){
        int hashcode = 0x21DD09EC;

        printf("%x\n", hashcode / 5);
        printf("%x\n", (hashcode / 5) + (hashcode % 5));

        return 0;
}

root@goorm:/workspace/LCH_Server# ./calc
6c5cec8
6c5cecc

우리는 passcode06C5CEC8 4번, 06C5CECC 1번 입력해주면 되겠네요.

Little-Endian 방식으로 넣어줍시다.

col@ubuntu:~$ ./col `python -c 'print "\xc8\xce\xc5\x06" *4 + "\xcc\xce\xc5\x06"'`
daddy! I just managed to create a hash collision :)

마무리

1학년 때 과제로 지겹도록 나왔던 형 변환 문제와 비슷했습니다 ㅋㅋ..

int4 bytes, char1 bytes라고 지겹도록 외웠던 보람이 있네요 :D

bof 로 찾아오겠습니다! 감사합니다!!

 

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

pwnable.kr : mistake 풀이  (0) 2019.04.16
pwnable.kr : passcode 풀이  (0) 2019.04.14
pwnable.kr : random 풀이  (0) 2019.04.13
pwnable.kr : bof 풀이  (0) 2019.04.13
pwnable.kr : fd 풀이  (0) 2019.04.11