2017. 5. 10.

[웹 취약점] strcmp 취약점

1. 개요


php 5.3 이상 버전에서 strcmp() 함수로 구현된 로그인 페이지를 우회하여 로그인 할 수 있다.

2. 취약점 진단 방법


<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];
$password = '123456';

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");
}

?>

step 1)

다음과 같이 로그인 페이지가 있다면 주목해야 할 부분은 strcmp 함수 부분이다.
strcmp 함수는 문자열을 비교하는 함수이다.
즉, strcmp(str1, str2) 일 때,
- str1이 더 크면 0 보다 큰 값 반환(양수)
- str2가 더 크면 0 보다 작은 값 반환(음수)
- 내용이 같으면 0 반환
해당 취약점 우회의 핵심은 strcmp($pass, $pw) 의 반환값을 0으로 만들어서 로그인이 허용되게 하려는 것이다.

step 2)

strcmp 함수의 두번째 인자값을 [] (Array) 형태로 넘겨준다.
(주의!. 배열을 인자로 하는게 아니라 타입을 배열로 변경하여 데이터를 아무값을 넣는 것이다. 예를 들면, pw[]=1234 와 같다.)
이로인해, strcmp(String, Array())는 NULL 을 반환하게 되고 NULL = 0 은 true 로 처리되어 인증이 우회되는 것이다.
(참고로 php 5.2 버전에서는 array() 를 Array 라는 문자열로 변환하여 비교한다.)



해당 사이트에서 더 자세한 정보를 확인 할 수 있다.
- http://php.net/manual/en/types.comparisons.php

step 3)

넘어가는 패스워드 파라미터를 확인 한 후, 다음과 같이 수정한다 (GET든 POST 든 상관없음)
(수정전)
xxx.xxx.xxx.xxx/index.php?id=admin&pw=1234
(수정후)
xxx.xxx.xxx.xxx/index.php?id=admin?pw[]=1234 // 배열 형태로 데이터 전달



3. 해결방안


엄격한 비교(Strict comparisons with), 즉 == 가 아닌 === 를 사용하거나 is_string, is_array 와 같은 함수를 통해 입력값을 검증해야 한다.


<참고>

  • http://m.blog.naver.com/koromoon/220604957033
  • http://blog.do9.kr/entry/strcmp-%EC%B7%A8%EC%95%BD%EC%A0%90

Popular Posts

Recent Posts

Powered by Blogger.