티스토리 뷰
PHP 5.3 이상 버전에서 strcmp() 함수를 이용하여 비교를 할 경우에 발생할 수 있는 취약점
<form method='get' action='index.php'>
ID: <input type='text' name='id'><br>
PW: <input type='text' name='pw'><br>
<input type='submit'><br>
</form>
<?php
$id = $_GET[id];
$pw = $_GET[pw];
$pass = 'php_strcmp_vulnerability';
if(!isset($_GET[id]) || !isset($_GET[pw])) {
exit();
}
if(strcmp($id, "admin") ==! 0) {
exit();
}
if(strcmp($pass, $pw) == 0) {
print("<br>$pass");
} else {
print('<br>wrong');
}
?> |
cs |
위와 같이 id와 pw를 입력하여 인증할 수 있는 창이 있다.
여기에서 strcmp($pass, $pw) == 0 이 부분에 취약한 부분이 있다.
일반적으로 strcmp($str1, $str2)를 비교하여 str1이 str2보다 작으면 0보다 작은 값을 반환하고, str1이 str2보다 크면 0보다 큰 값을 반환한다.
그리고 동일할 경우에 0을 반환한다.
그렇기 때문에 id는 admin, pw는 php_strcmp_vulnerability를 입력해주면 $pass와 $pw가 같기 때문에 0을 반환해서 $pass 값을 출력하게 된다.
id와 pw를 맞게 입력하였을 경우 위와 같이 $pass 값이 출력되는 것을 볼 수 있다.
반면에 pw 값을 맞지 않게 입력하였을 경우에는 wrong이 출력된다.
여기에서 값을 전달할 때 [] (Array) 형태로 넘겨줄 경우 strcmp(String, Array())는 NULL을 반환하게 되고 NULL == 0 은 true로 처리되어 인증을 우회할 수 있는 취약점이 있다. (PHP 5.2에서는 Array()를 문자 Array로 비교)
1. if(strcmp("admin",Array()) == 0)
2. if(NULL == 0)
3. true
비교를 했을 때 결과값이 어떻게 되는 지는 아래 표를 통해 확인할 수 있다.
http://php.net/manual/en/types.comparisons.php
Loose comparisons with ==
Strict comparisons with ===
이를 막기 위한 방법으로 위 표를 보면 알 수 있듯이 == 대신에 ===를 사용하면 된다.
= is the assignment operator
== is the comparison operator (checks if two variables have equal values)
=== is the identical comparison operator (checks if two variables have equal values and are of the same type)
'Programming > PHP' 카테고리의 다른 글
POSIX Regex와 PCRE Regex (0) | 2015.10.20 |
---|---|
PHP Object Injection (0) | 2015.09.03 |
'(single-quotes)와 "(double-quotes)의 차이 (0) | 2015.02.03 |