워게임/247CTF

[247CTF] COMPARE THE PAIR - 웹해킹 / MD5 Magic Hash

SecurityMan 2023. 9. 23. 11:00

 

php의 약한 비교(Loose Comparison) 로 인해 발생하는

php magic hash 와 관련된 웹 해킹 문제이다.

 

반응형

 

 

문제페이지어 들어가면 이런 코드가 나온다

 

php 로 작성되었는데

 

GET 으로 password 파라미터가 설정되어있고,

 

md5(salt. $_GET['password']) 의 값이 

 

password_hash 의 값인 0e902564435691274142490923013038 와 같은지 확인한 후

 

같으면 flag 를 보여주는 기능이다.

 

salt 까지 들어간 해시값의 원래 문자열을 찾는건 불가능에 가깝지만

 

비교할때 '===' 가 아닌 '==' 을 이용해 두 값을 비교하기 때문에 취약점이 발생한다.


위 사진처럼 php 에서는 == 을 사용해 비교를 할 경우

두 값이 정확하게 같지 않아도 True 를 리턴하게 된다.

이것을 이용해서 MD5 Magin Hash 라는 것을 이용할 것이다.


https://github.com/spaze/hashes/blob/master/md5.md

위 사이트에서 MD5 Magic Hash를 만드는 입력값을 쉽게 확인할 수 있다.

: 앞 부분이 입력값, 뒷부분이 MD5 해시값인데,

해시값을 보면 공통적으로 맨 앞부분이 0e 로 시작하는것을 볼 수 있다.


여기서 의도하는것은 위 사진을 보면 알기 쉽다.

계산기를 사용하다가 가끔식 봤을텐데,

컴퓨터에서 큰 수를 표기하기 위해서 지수(e)를 사용한다.

만약 MD5값이 0e291529052894702774557631701704 와 같이 나왔다면,

이것을 0의 지수승이라고 인식하게 되어서 그 값이 그냥 0이 되어버리는 것이다.

 

마침 맞춰야하는 0e902564435691274142490923013038 역시 0e로 시작하기 때문에

 

salt 값 + 임의의 값 을 해서 맨 앞이 0e로 시작하는 숫자로된 해시값을 찾으면 된다.

 

import hashlib

salt = "f789bbc328a3d1a3"

for i in range(1000000000):
    password = salt + str(i)
    password = password.encode('utf-8')

    md5_hash = hashlib.md5()
    md5_hash.update(password)
    hashed_password = md5_hash.hexdigest()

    if "0e" in hashed_password[:2] and hashed_password[2:].isdigit():
        print("found : ", hashed_password, password)

 

이렇게 파이썬을 이용해 코드를 작성한다.

 

숫자 1부터 시작해 계속 늘려가면서

 

salt + str(숫자) 를 해 평문을 생성해주고

 

그 평문을 md5 해시값으로 만든 뒤

 

맨 앞이 0e로 시작하고, 나머지 부분이 숫자로만 이루어졌는지 확인하는 코드이다.

 

 

코드를 실행시킨 뒤 잠시 기다리면

 

해당 조건을 만족하는 입력값을 찾을 수 있다.

 

 

URL 창에서 ?password= 뒤에 찾은 값을 입력해주면

 

플래그가 출력되는것을 볼 수 있다.

반응형