<?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`와 같은 안전한 문자열 비교 방법을 사용해야 합니다.
흠..지피티가 제대로 작동을 안한다..빠르게 풀이글을 보러가자
strcmp(A, B) 함수는 두 개의 문자열을 비교하는 함수이다.
A<B이면 음수 값
A>B이면 양수 값
A=B이면 0을 반환한다.
특정한 PHP 버전대에서는 strcmp()의 인자 값으로 배열을 넣는 경우 NULL 값이 반환된다.
게다가 PHP에서는 NULL과 0을 == 연산자를 이용하여 비교했을 때 True를 반환한다. 이를 느슨한 비교라고 한다
출처 ㅣ https://jwcs.tistory.com/34
paswword를 password[]같이 배열로 바꿔주면 null이 되고 == 연산자로 0과 null을 비교하면 true를 반환한다
'Dreamhack > Dreamhack Wargame (Challenge)' 카테고리의 다른 글
[70] IT 비전공자 [dreamhack] baby-union문제 풀기 (2) | 2024.11.18 |
---|---|
[69] IT 비전공자 [dreamhack] Command Injection Advanced문제 풀기 (2) | 2024.11.17 |
[67] IT 비전공자 [dreamhack][wargame.kr] login filtering문제 풀기 (1) | 2024.11.15 |
[66] IT 비전공자 [dreamhack]off_by_one_001문제 풀기 (1) | 2024.11.14 |
[65] IT 비전공자 [dreamhack]cmd_center문제 풀기 (0) | 2024.11.13 |