Dreamhack/Dreamhack Wargame (Challenge)

[68] IT 비전공자 [dreamhack][wargame.kr] strcmp문제 풀기

imaginefuture-1 2024. 11. 16. 09:12

 

 

 

 

연속으로 web 문제~!

 

 

시작페이지다. password?
국룰 guest를 넣었더니 wrong 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>

 

do not brute force! 브루트포스는 막혔다.

 

 

 

`strcmp` 함수는 두 문자열을 비교하는 함수로, 두 문자열이 동일한지 여부를 비교하는 데 사용됩니다. `strcmp`는 **대소문자 구분** 및 **길이가 다른 경우**를 처리하며, 두 문자열이 완전히 동일하면 0을 반환합니다. 그런데 `strcmp` 함수는 **문자열이 일치할 때까지 비교를 진행하는 방식**이기 때문에 일부 취약점이 있을 수 있습니다.

### 취약점 분석
PHP의 `strcmp` 함수는 **정확히 일치하는 경우에만 0을 반환**하고, 그렇지 않으면 음수 또는 양수를 반환합니다. 또한 `strcmp`는 두 문자열을 **끝까지 비교**하므로, 비교가 끝날 때까지 문자열을 계속 비교합니다. 이때 공격자는 **부분 문자열 비교를 통해 유효한 비밀번호를 추측**할 수 있습니다.

현재 코드에서 비밀번호 비교는 `strcmp($_POST['password'], $password)`로 이루어집니다. 이때, 사용자가 입력한 비밀번호가 `$password`와 **부분적으로 일치**하는 경우, 공격자는 일치하는 부분을 하나씩 추출할 수 있습니다.

### 취약점 활용
1. **부분 문자열 비교**: `strcmp`는 한 문자씩 비교하므로, 공격자는 비밀번호의 각 문자를 하나씩 알아낼 수 있습니다. 즉, 비밀번호의 첫 번째 문자부터 차례대로 맞춰가면서 나머지 문자를 유추할 수 있습니다.
   
2. **타이밍 공격 (Timing Attack)**: `strcmp`가 문자열을 비교하는 과정에서, 일치하지 않는 부분이 발견되면 그 즉시 반환되는 값이 달라집니다. 문자열이 일치할 때까지 계속 시간을 소비하므로, 공격자는 이 **시간 차이**를 측정하여 올바른 비밀번호의 각 문자를 유추할 수 있습니다.

### 공격 방법
1. **비밀번호 길이 파악**: 먼저, 비밀번호의 길이를 추측해야 합니다. 이를 위해 반복적인 시도와 응답 시간을 측정할 수 있습니다. 예를 들어, 비밀번호가 "ABC"라고 가정했을 때, 첫 번째 문자 'A'가 일치하는지 확인하고, 그 다음에 두 번째 문자 'B'가 일치하는지 확인하는 방식으로 진행할 수 있습니다.

2. **첫 번째 문자 추측**: 사용자가 `strcmp` 비교를 시도할 때, 첫 번째 문자가 맞다면 비교 시간이 조금 더 길어집니다. 이를 통해 공격자는 첫 번째 문자를 추측할 수 있습니다. 그런 다음, 두 번째 문자, 세 번째 문자 순으로 차례대로 맞춰가면 됩니다.

3. **자동화**: 이 과정을 자동화하면, 공격자는 `strcmp`의 타이밍 차이를 이용해 비밀번호를 완성할 수 있습니다.

### 예시 공격 시나리오
1. **첫 번째 문자 추측**:
   - 비밀번호의 첫 번째 문자를 추측하려면, 다양한 문자들을 입력하고 응답 시간의 차이를 관찰합니다. 예를 들어, 'A', 'B', 'C', 'D'와 같은 문자들을 입력하고 응답 시간을 측정합니다. 올바른 문자가 입력되었을 때, 응답 시간이 길어지므로, 이를 통해 첫 번째 문자를 파악할 수 있습니다.
   
2. **두 번째 문자 추측**:
   - 첫 번째 문자를 맞춘 후, 두 번째 문자를 추측할 수 있습니다. 마찬가지로 'A', 'B', 'C' 등 다양한 문자를 입력하여 타이밍 차이를 확인합니다.
   
3. **반복**:
   - 이러한 방식으로 비밀번호의 모든 문자를 하나씩 유추할 수 있습니다.

### 취약점 수정 방안
이 취약점을 해결하기 위해서는 `strcmp` 대신에 **타이밍 공격을 방지하는 함수**를 사용하는 것이 중요합니다. 예를 들어, PHP에서는 `hash_equals()` 함수를 사용할 수 있습니다. 이 함수는 두 문자열을 **동일한 시간**에 비교하므로, 타이밍 차이를 이용한 공격을 방지할 수 있습니다.

```php
if (hash_equals($password, $_POST['password'])) {
    echo "Congratulations! Flag is <b>" . $FLAG . "</b>";
}
```

### 결론
`strcmp`를 이용한 취약점은 **타이밍 공격**을 통해 비밀번호를 유추할 수 있다는 점에서 매우 위험합니다. 공격자는 이를 이용하여 비밀번호를 차례대로 추측할 수 있으며, 이에 대한 방어책으로는 `hash_equals`와 같은 안전한 문자열 비교 방법을 사용해야 합니다.

 


 

 

흠..지피티가 제대로 작동을 안한다..빠르게 풀이글을 보러가자

 

https://jwcs.tistory.com/34

 

[드림핵] [wargame.kr] strcmp

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를

jwcs.tistory.com

 

 


 strcmp(A, B) 함수는 두 개의 문자열을 비교하는 함수이다.
A<B이면 음수 값
A>B이면 양수 값
A=B이면 0을 반환한다.
특정한 PHP 버전대에서는 strcmp()의 인자 값으로 배열을 넣는 경우 NULL 값이 반환된다.

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

출처 ㅣ https://jwcs.tistory.com/34

 

NULL == 0 true

 

 

 

paswword를 password[]같이 배열로 바꿔주면 null이 되고 == 연산자로 0과 null을 비교하면 true를 반환한다 

 

 

passwrod[]변경
짜잔 플래그야~ 안녕!