[Pwnable.kr] collision

chwrld·2023년 9월 30일

Pwnable.kr

목록 보기
1/1
post-thumbnail

🚩 Daddy told me about cool MD5 hash collision today.

I wanna do something like that too!

💀 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;

}

MD5 알고리즘은 입력 값이 달라도 출력 값은 같을 수밖에 없는 취약점을 이용한 문제이다. (MD5는 ~128비트 입력 값을 받고 128비트 출력 값을 주는데 2^128비트 입력을 모두 주면 결국 출력 값이 같은 해시 값이 생긴다.)

0x21DD09EC 는 어떤 값을 MD5 암호화 한 해시 값이다.
우리는 주어진 코드를 이용해 0x21DD09EC를 만들어야 한다.

  1. 프로그램 인자로 20바이트 입력을 받는다.

  2. 인자 값을 4바이트 단위로 res에 저장한다.

  3. res 값이 hashcode와 같다면 flag 출력

    p1 + p2 + p3 + p4 + p5 = 0x21DD09EC
    위와 같은 식이 만들어지고 조건은
    -> p5 = 0x21DD09EC - (p1 + p2 + p3+ p4)
    -> 32비트 이하

    00000001 + 00000002 .. 이런식으로 하려 했는데 process 함수에서 null 값을 payload로 보낼수 없다고 한다.

🚀 Exploit.py

from pwn import *

p1 = ssh("col", "pwnable.kr", port=2222, password="guest")
payload = p32(0x01010101)
payload += p32(0x01010101)
payload += p32(0x01010101)
payload += p32(0x01010101)
payload += p32(0x21DD09EC - (0x01010101 * 4))

p2 = p1.process(["./col"] + [payload])
p2.interactive()
profile
BoB 13th 최강포린이👮

0개의 댓글