최근에 “==” 으로 느슨한 비교를 하는 워게임 문제를 풀었습니다.
이에 느슨한 비교가 무엇인지 자세하게 알아봅시다.
loose comparison(느슨한 비교)
느슨한 비교란 말 그대로 느슨한 비교
입니다. 코드에서 ==
혹은 ===
으로 비교하는 것을 볼 수 있습니다. ==
은 느슨한 비교, ===
은 엄격한 비교라고 합니다. 왜 엄격하고 느슨한 비교인지는 php 느슨한 비교 표를 보면 이해가 쉽습니다.
위의 표에서 다음과 같은 결과를 확인 할 수 있습니다.
1
2
3
True == "문자열" -> 결과가 False
True === "문자열" -> 결과가 True
예를 들어 아래와 같이 사용자 인풋 값과 해시된 패스워드를 비교하여 login 하는 코드가 있다고 가정해 봅시다.
1
2
3
4
5
6
$input = "사용자 인풋 값"
$password = md5($password)
if($input == $password){
login()
}
위의 코드에서 사용자 인풋값의 Type
이 String
이라면 문제 없이 잘 비교가 될 것입니다. 하지만 만약 사용자 인풋값의 Type
을 변경할 수 있어서 Boolean(True)
로 바꿀 수 있게된다면?????? -> if문을 통과해 login() 함수를 실행할 수 있습니다.
## PHP strcmp() 함수 PHP에서 strcmp()
함수는 값을 비교할 때 사용하는 함수입니다. strcmp()
함수 원형 및 리턴 값을 보면 아래와 같습니다.
1
2
3
4
5
int strcmp ( string $str1 , string $str2 ) // 리턴 값이 INT형임
Returns < 0 //str1이 str2 보다 작다
Returns > 0 // str1이 str2 보다 크다
Returns = 0 // 두 값이 동일하다
PHP 5.3이상 에서 발생할 수 있는 느슨한 비교 취약점입니다.
예시로 아래와 같은 코드가 있다고 해봅시다. 사용자 입력 값 $input
에 배열을 넣게 되면 strcmp($input,$password)
값은 NULL
이 됩니다. NULL == 0
은 True
가 되므로 해당 if문을 통과하게 되어 login()함수가 실행될 것입니다.
1
2
3
4
5
6
$input = "사용자 인풋 값"
$password = md5($password)
if(strcmp($input, $password) == 0){
login()
}