Pwnable/Pwnable.kr

[Pwnable.kr] collision 문제 풀이!![재업로드]

RootJJang 2022. 6. 21. 10:19
SMALL

collision 드가자

 

아부지가 오늘 머찐 MD5 해쉬 충돌에 대해 말씀해주셨어용
나도 저런 거 하고 시풔! 라네요

 

함 접속해보죠

 

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

코드가 꽤 기네요

 

위에 check_password는 사용자가 입력한 20바이트 길이의 패스워드를 4바이트씩 5번 읽어들인다는 뜻이라네요

 

우리가 입력한 패스워드가 hashcode와 같다면 flag를 읽어주네요

 

그냥 hashcode값을 넣자니 길이가 모자르니 check_password를 잘 이용해야겠네요

 

24란 값이 있다고 하고 5를 나누면 24 = 4*5 + 4라는 검산식이 나오는데요

 

하나의 값을 4바이트라고 하고 보면 페이로드 형식이 총 24바이트가 되니까 성립이 안 되네요

 

약간 변형해보죠

 

24 = 4*4 + (4+4) 이러면 똑같이 검산식에도 만족하면서 페이로드 형식에도 성립하네요

 

이 방식의 원리대로 hashcode(0x21DD09EC)에 적용을 해보죠

 

0x21DD09EC = 6C5CEC8*5 + 4를

 

0x21DD09EC = 6C5CEC8*4 + (6C5CEC8+4)로 바꿔봤습니당

 

이게 페이로드 형식이니 이제 페이로드를 짜보겠습니당

 

Payload = ./col `python -c 'print "\xc8\xce\xc5\x06"*4 + "\xcc\xce\xc5\x06"'`(뒤에 0x6c5cecc는 6c5cec8 + 4한 값입니당)

 

Flag = daddy! I just managed to create a hash collision :)

아부지! 방금 해쉬 충돌을 만들었어여!

LIST