워게임/Root Me

[Root Me] PHP - Loose Comparison - 웹해킹 / MD5 Magic Hash

SecurityMan 2022. 10. 25. 11:00


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

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

반응형


문제 페이지에 접속하면 이런 화면이 나온다.

seed 와 hash를 입력하는 칸이 있고, 옆에는 check 버튼이 있다.

뭔지 모르겠으니 일단 아래 source code 버튼을 눌러 소스코드를 확인해본다.


source code 버튼을 누르면 이렇게 아래쪽에 소스코드가 출력된다.


이 부분부터 살펴본다.

seed 에 입력한 값은 $s 에 저장되고,

hash 에 입력한 값은 $h 에 저장된다.

각각의 변수에 저장되기 전에 sanitize_user_input 함수와

secured_hash_function 함수에 입력값을 먼저 넣어주는데,


sanitize_user_input 함수는 정규식을 이용해

사용자가 알파벳 소문자/대문자, 숫자만 입력할 수 있도록 제한하고 있다.


secured_hash_function 에서는 내부적으로 sanitize_user_input 함수를 실행하고,

결과값을 md5 해시값으로 만들어 리턴해주는 역할을 한다.


마지막으로 gen_secured_random 함수의 결과로 생성된 $r 을 이용해

$s + $r 의 값이 $h 값과 같은지 확인하고 있다.


gen_secured_random 함수는 말 그대로 랜덤한 숫자를 생성하는 함수이다.

상식적으로 $s.$r == $h 라는 조건문은 절대로 통과할 수 없다.

$r에 무슨 값이 올지 전혀 모르기 때문에 아무리 $s와 $h 값을 고심해서 넣어도

두개의 값이 같아질 수는 없는 것이다.

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


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

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

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


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

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

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

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


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

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

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

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

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

import requests

url = 'http://challenge01.root-me.org/web-serveur/ch55/index.php'

data = {'s':'0e',
        'h':'MMHUWUV',
        'submit':'Check'}

r = requests.post(url, data=data)

print(r.text)


굳이 파이썬 코드를 안써도 풀 수 있지만 한번 코드로 만들어 봤다.

h 변수에는 아까 github에 있었던 Magic Hash 생성값중 하나를 아무거나 넣어주고,

s 변수에는 0e 만 넣어준다.

그럼 h 변수는 Magic Hash 가 생성되어 0 이 되어 버리고,

s 변수의 경우에도 0e + 랜덤한 숫자($r) 이 되어버려서 그냥 0이 되어버린다.

결론적으로는 조건문이 0 == 0 이 되어버리기 때문에 결과는 참이 될 것이다.


코드를 실행시키면 플래그가 출력되는것을 볼 수 있다.

반응형