보안/System Hacking

[pwnable.kr] collision

melonbbang-ruffy 2025. 2. 18. 18:09

https://pwnable.kr/play.php

 

https://pwnable.kr/play.php

 

pwnable.kr

 

md5 hash collision 문제인듯

서버로 접속해 들어가보자.

flag 파일이 보이는데 r--r----- 권한인 것을 보아 파일 소유자 / 루트 계정 아니면 열 수 없을듯

col.c 코드를 살펴보자

code

더보기
#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");

파일을 실행할 경우 -> 사용자의 입력값을 받아 passcode와 비교한다.

passcode는 20바이트의 크기를 가지고 있는 것으로 보이고, 20바이트 문자열을 5개의 4바이트 정수로 변환 후 덧셈 연산을 수행하기 때문에 원하는 합(0x21DD09EC)을 만들어내는 임의의 20바이트 문자열을 만들어 낼 경우 플래그 값을 알아낼 수 있을것으로 보인다.

null = 0x00

null 값을 제외한, 각 5개의 4바이트로 이루어진 수를 조합할 때 hashcode인 0x21dd09ec 보다 작은 임의의 무작위 값을 만들고, hashcode에서 해당 수를 뺀 값을 16진수로 나타낸 후, 리틀 엔디언 형식으로 순서를 바꿔서 해당 파일을 실행할 때 인자로 넣어주면 될 듯 하다

 

 

Exploit

payload는 다음과 같다.

4바이트 임의의 정수를 0x08 이라고 하자. 해당 정수를 4개 생성하고, 0x08080808 을 hashcode 값에서 빼 보자.

0x01bce9cc가 나온다.

리틀 엔디언 형식이므로 0xCC 0xE9 0xBC 0x01 이런 식으로 보내야 될듯

payload는 다음과 같다.

./col "$(python -c 'import sys; sys.stdout.write("\x08"*16 + "\xCC\xE9\xBD\x01")')"

플래그 획득