wargame/wargame.kr

10번 md5_compare

NTART 2019. 10. 31. 13:57

그냥 서로 다른 값으로 비교만 하여라

 

value1과 value2가 같은 값이어야 하는 것 같다.

 

<?php
    if (isset($_GET['view-source'])) {
         show_source(__FILE__);
         exit();
    }

    if (isset($_GET['v1']) && isset($_GET['v2'])) {
        sleep(3); // anti brute force

        $chk = true;
        $v1 = $_GET['v1'];
        $v2 = $_GET['v2'];

        if (!ctype_alpha($v1)) {$chk = false;}
        if (!is_numeric($v2) ) {$chk = false;}
        if (md5($v1) != md5($v2)) {$chk = false;}

        if ($chk){
            include("../lib.php");
            echo "Congratulations! FLAG is : ".auth_code("md5_compare");
        } else {
            echo "Wrong...";
        }
    }
?>

코드를 보면, v1값은 ctype_alpha, v2값은 is_numeric 값을 요구한다.

ctype_alpha는 문자열이 모두 알파벳이어야 하며, is_numeric은 숫자여야한다. is_numeric은16진수(0x...)도 허용하는데, string값을 hex값(16진수)으로 바꿔 주입하는게 가능하여 sql injection과 비슷한 취약점이 있다고 한다. 

 

가볍게 해보았지만 실패하였고, 문제를 다시보니 md5 해시를 한 값이 같아야 하기 때문에 다른 접근이 필요하다. 

md5 equal hash 구글링을 하여 QNKCDZO와 240610708의 md5값이 같게 나오는 버그를 볼 수 있었다.

이 두 값은 각각 md5 해시를 하였을 때, 0e830400451993494058024219903391 와 0e462097431906509019562988736854값이 나오는데 모두 0e로 시작하는 float값이며 php는 이 두수를 ==로 비교할 때, 0으로 같은 값이라고 출력한다. 

해결 방안으로는 더 강한 비교인 ===를 해주면 같지 않다고 false값이 나온다.

 

ref)

https://www.php.net/manual/en/function.md5.php

 

PHP: md5 - Manual

From the documentation on Digest::MD5:md5($data,...)This function will concatenate all arguments, calculate the MD5 digest of this "message", and return it in binary form.md5_hex($data,...)Same as md5(), but will return the digest in hexadecimal form. PHP'

www.php.net

https://stackoverflow.com/questions/22140204/why-md5240610708-is-equal-to-md5qnkcdzo

 

Why md5('240610708') is equal to md5('QNKCDZO')?

var_dump(md5('240610708') == md5('QNKCDZO')); Output: bool(true) Example: http://3v4l.org/2vrMi

stackoverflow.com

 

해당 값을 넣어 문제를 해결하였다. 

 

결론이 조금 찜찜하여 md5 해시를 하였을 때, 0e로 시작하는 값을 출력하는 다른 값을 찾아보았다. aabg7XSs는 md5 해시를 돌리면 0E087386482136013740957780965295 값이 나온다. 하지만 240710708값과 다르다고 나왔으니, aabg7XSs는 0값으로 보지는 않는 것 같다.

결론적으로 QNKCKZO와 240610708을 php에서 md5하여 ==비교를 하였을 때,  모든 0e 형식의 값을 0으로 보는 것은 아니지만, 240610708과 QNKCDZO은 0으로 보는 버그와 같은 취약점이라 보면 될 것 같다.