쉽고 깔끔하게

[pwnable.kr] Toddler's Bottle 2번 collision 문제풀이 본문

Pwnable/pwnable.kr

[pwnable.kr] Toddler's Bottle 2번 collision 문제풀이

찐무 2021. 6. 10. 16:12
728x90
반응형

© PWNABLE.KR SINCE 2014 - ALL RIGHTS RESERVED.

 


문제

http://pwnable.kr/play.php

아빠가 오늘 멋진 MD5 해시 충돌에 대해 말씀해주셨어요.

저도 그런 거 하고 싶어요!


문제를 해결하기에 앞서,

• 해시함수 (Hash Function)

   : 임의의 길이를 갖는 메시지를 입력으로 하여 고정된 길이의 해시값 또는 해시 코드라 불리는 값을 출력하는 일방향 함수

   → 메시지가 다르면 해시값도 다르다는 특징을 가지고 있음

 

• 해시 충돌 (Hash Collision)

   : 2개의 다른 메시지가 같은 해시값을 갖는 것

   → 해시함수가 유한한 가짓수의 출력값을 생성하는 경우 해시 충돌이 발생함


터미널을 이용하여 ssh col@pwnable.kr -p2222에 접속합니다. (password : guest)

ls -l 명령어를 통해 현재 디렉터리에 존재하는 파일들의 정보를 확인합니다.

[ col ] 파일의 속성은 -r-sr-x---로 SetUID가 설정되어 있으며 실행 시 파일 소유자(col_pwn)의 권한으로 실행됩니다.

[ col.c ] 파일은 유일하게 제 3자(other)가 파일을 읽을 수 있는 권한(-rw-r--r--)을 가지고 있습니다.

[ flag ] 파일은 파일 소유자인 col_pwn만이 해당 파일을 읽을 수 있습니다.

▶︎ 따라서 SetUID가 설정된 [ col ] 파일이 실행되는 동안에는 [ flag ] 파일을 읽을 수 있습니다.

 

cat 명령어를 통해 [ col.c ] 파일의 내용을 확인합니다.

해당 코드를 살펴보면,

 

  • Code 1
unsigned long hashcode = 0x21DD09EC;

hashcode를 0x21DD09EC로 정의하고 있습니다.

 

  • Code 2
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;
}

check_password라는 이름을 가진 사용자 함수를 따로 정의해줬습니다.

이 함수는 char*형으로 정의된 p를 int*형으로 변환시킨 뒤, 이를 4byte(int의 크기)씩 나눠 res에 더해줍니다.

 

  • Code 3
if(argc<2) {
    printf("usage : %s [passcode]\n", argv[0]);
    return 0;
}

인자의 갯수가 2보다 작으면(argc<2) 'usage : argv[0] [passcode]'를 출력하고 프로그램을 종료합니다.

▶︎ 따라서, [ col ] 파일 실행 시 ./col 인자값 과 같은 형태로 실행해야 합니다.

 

  • Code 4
if(strlen(argv[1]) != 20) {
    printf("passcode length should be 20 bytes\n");
    return 0;
}

strlen() 함수를 이용하여 argv[1] 인자값의 길이를 구한 뒤 20byte가 아니라면(!= 20) 'passcode length should be 20 bytes'를 출력하고 프로그램을 종료합니다.

 

  • Code 5
if(hashcode == check_password( argv[1] )) {
    system("/bin/cat flag");
    return 0;
}

사용자에게 입력받은 인자값 argv[1]을 check_password 함수에 넣어 반환된 res 값을 hashcode인 0x21DD09EC과 비교합니다.

▶︎ 따라서 check_password 함수의 p값이 for문을 5번 돌아 hashcode의 값인 0x21DD09EC가 된다면 flag를 얻을 수 있습니다.

 

결과적으로,

code 3) [ col ] 파일 실행 시, ./col 인자값 형태로 실행하기

code 1, 2, 5) 인자값과 hashcode의 값이 일치해야 하므로 0x21DD09EC를 5로 나눈 값을 인자값으로 넘겨주기

 

  • 0x21DD09E / 5

이에 0x21DD09EC를 5로 나눠주게 되면 0x6C5CEC8이라는 값이 나오게 됩니다.

 

  • 0x21DD09EC - 0x21DD09E8

그러나, 0x6C5CEC8에 5를 곱해주게 되면 0x21DD09E8이라는 값이 나오면서 hachcode와 다른 값이 나오게 됩니다.

→ hachcode 값인 0x21DD09EC에 0x21DD09E8을 빼주게 되면 (0x21DD09EC - 0x21DD09E8) 0x4 차이가 난다는 것을 알 수 있습니다.

▶︎ 따라서, hachcode 값과 일치하는 값을 만들어 주기 위해 ⭐️0x6C5CEC8 * 4 + 0x6C5CECC 을 인자로 전달해줍니다.

 

<정답>

 

728x90
반응형

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

[pwnable.kr] Toddler's Bottle 1번 fd 문제풀이  (0) 2021.06.09