본문 바로가기
드림핵

[드림핵] [wargame.kr] strcmp

by jwcs 2023. 7. 12.
728x90

https://dreamhack.io/wargame/challenges/328/

 

[wargame.kr] strcmp

Description if you can bypass the strcmp function, you get the flag.

dreamhack.io

strcmp에서 발생하는 취약점 문제이다.

 

/

password를 입력하는 창이 보인다. view-source를 통해 소스 코드를 확인해보자.

 

<?php
    require("./lib.php"); // for FLAG

    $password = sha1(md5(rand().rand().rand()).rand());

    if (isset($_GET['view-source'])) {
        show_source(__FILE__);
        exit();
    }else if(isset($_POST['password'])){
        sleep(1); // do not brute force!
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Congratulations! Flag is <b>" . $FLAG ."</b>";
            exit();
        } else {
            echo "Wrong password..";
        }
    }

?>
<br />
<br />
<form method="POST">
    password : <input type="text" name="password" /> <input type="submit" value="chk">
</form>
<br />
<a href="?view-source">view-source</a>

패스워드가 랜덤으로 만들어져 암호화되어있다. 이 값이 우리가 입력한 값이 같다면 문제가 풀리게 된다.

무차별 대입공격은 막혀있다. 그럼 어떻게 문제를 풀어야할까?

 

strcmp(A, B) 함수는 두 개의 문자열을 비교하는 함수이다.

A<B이면 음수 값

A>B이면 양수 값

A=B이면 0을 반환한다.

특정한 PHP 버전대에서는 strcmp()의 인자 값으로 배열을 넣는 경우 NULL 값이 반환된다.

자료 첨부한다.

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

 

PHP: strcmp - Manual

In summary, strcmp() does not necessarily use the ASCII code order of each character like in the 'C' locale, but instead parse each string to match language-specific character entities (such as 'ch' in Spanish, or 'dz' in Czech), whose collation order is t

www.php.net

 

게다가 PHP에서는 NULL과 0을 == 연산자를 이용하여 비교했을 때 True를 반환한다. 이를 느슨한 비교라고 한다. 관련 자료 첨부하겠다.

https://www.php.net/manual/en/types.comparisons.php

 

PHP: PHP type comparison tables - Manual

Some function to write out your own comparisson table in tsv format. Can be easily modified to add more testcases and/or binary functions. It will test all comparables against each other with all functions. '==',        'ne' => '!=',        'gt' =>

www.php.net

따라서

name="password"로 선언된 부분을

name="password[]"와 같이 배열로 바꿔준다.

 

이후 아무 값이나 보내면

짜자잔

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

필자는 개발 지식이 부족해 name="password[]"로 바꿔서 보내면 php에서 이를 제대로 받을 수 있는지 몰랐다. $_POST['password[]']로 되어야 제대로 배열을 받을 수 있는 것 아닌가 생각했다.

확인해보니 php에서는 $_POST['password']로 일반 문자열과 배열 모두 받을 수 있다고 한다. 굳굳

728x90
반응형