[3pt]collision

Pwnable.kr 2015. 8. 7. 10:07
#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;
}


Introduction:

  문제를 보면 char형으로 입력받은 20개의 문자를 int형으로 캐스팅 한 후 res라는 변수에 중첩해서 더하는 것을 볼 수 있음. 즉, 입력받은 20개의 문자는 4문자 단위로 나눠져 int형 배열에 저장되며, flag의 내용을 보기 위해서는 이렇게 나뉘어진 int형 배열의 값이 중첩되어 더해진 res변수의 결과값이 "0x21DD09EC"가 되게 하면 됨.


How to solve:

  그림 1은 어떻게 하면 res의 값이 "0x21DD09EC"가 되게 할 수 있을지를 확인하기 위해 수행된 실험이다. "0x21DD09EC"를 5로 나눠 10진법으로 나타내었을 때 "113626824"가 나왔고, 이 값에 다시 5를 곱해보니 "568134120"(a)이라는 결과가 나왔다. "0x21DD09EC"을 10진법으로 나타내었을 때의 값은 "568134124"(b)인데, 이는 (a)와 4만큼 차이나는 결과이다. 따라서 flag의 값을 확인하기 위해서는 "113626824"*4 + "113626824"+4의 결과가 입력되어야 할 것이다. 답을 확인하기 위해 그림 2와 같이 결과를 입력하였고, 그림 3과 같은 결과가 도출되었다.


<그림 1> int형 배열 5개의 합이 "0x21DD09EC"가 되어야 하므로 "0x21DD09EC"를 5로 나눠봄


<그림 2> int형 배열의 값과 res의 값을 확인하기 위해 화면에 출력


<그림 3> 계산한 값을 입력한 결과 답을 얻음



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

[4pt]input  (0) 2015.08.15
[1pt]mistake  (0) 2015.08.06
[1pt]cmd1  (0) 2015.08.06
[1pt]fd  (0) 2015.08.06
[5pt]bof  (0) 2015.08.06
Posted by Hugh_K
l