티스토리 뷰

최종 수정: 2014-03-25


안녕하세요. Hackability 입니다.


오늘 포스팅 할 내용은 PHP 에서 입력 문자열 필터링 함수의 취약점을 이용한 우회 기법에 대한 내용입니다.


PHP 에서는 HTTP 메소드를 통해 들어 오는 사용자의 입력 검증 또는 필터링을 위해 eregi 와 같은 함수를 사용해 왔습니다. (POSIX Regex)


예를들어, 간단히 다음과 같이 id 입력에 대해 필터링하는 PHP 코드가 있다고 가정 합니다.


index.php

1
2
3
4
5
6
7
8
9
10
<?
 
$_id = $_GET[id];
 
if (eregi("admin",$_id))
  echo "Filtered !!" . "<br>";
else
  echo $_id . "<br>";
 
?>


간단히, index.php?id=admin 으로 접근을 하게 되면 "Filtered !!" 라고 뜨게 되고 그 외 아이디를 입력하게 되면 해당 문자열을 출력해주게 됩니다.


문제가 없어 보이지만, PHP 5.3+ 부터 POSIX Regex 함수들이 더이상 사용되지 않게 되었습니다. (As of PHP 5.3.0, the POSIX Regex extension is deprecated.) 또한, PHP 6.0 부터는 아예 삭제됩니다. PHP 5.3+ 부터는 POSIX Regex 대신 PCRE Regex 를 사용하게 됩니다.


먼저, 5.3+ 에서 어떻게 위의 필터링을 우회 하는지 보도록 하겠습니다. PHP 5.3+ 에서 POSIX Regex 함수들을 사용할 때, NULL 문자를 만나게 되면 더이상 뒤의 문자열을 체크하지 않게 됩니다. 아래는 5.2 와 5.3에서 위의 index.php 사용에 대한 예 입니다.


PHP 5.2+

/index.php?id=admin



PHP 5.3+

/index.php?id=admin



PHP 5.2+, 5.3+ 모두 정상적으로 필터링 되는 것을 확인할 수 있습니다. 하지만, 첫 바이트에 NULL을 넣어 입력 문자열을 더이상 점검하지 못하도록 하면 어떻게 될까요?


PHP 5.2+

/index.php?id=%00admin


 


PHP 5.3+

/index.php?id=%00admin


 


PHP 5.2+ 에서는 정상적으로 필터링 되지만, PHP 5.3+ 에서는 필터링이 정상적으로 되지 않는 것을 확인 할 수 있습니다. 이를 통해 PHP 5.3+ POSIX Regex 필터링을 우회 하는 것을 확인하였습니다.


마지막으로 PHP 5.3+ 에서 위의 문제를 수정하기 위해 POSIX Regex 함수들을 PCRE Regex 로 변경하는 것을 요구 하고 있습니다.


Function replacements

 POSIX

 PCRE 

 ereg_replace()

 preg_replace()

 ereg()

 preg_match()

 eregi_replace()

 preg_replace()

 eregi()

 preg_match()

 split()

 preg_split()

 spliti()

 preg_split()

 sql_regcase()

 No equivalent


저작자 표시
신고
댓글
  • 프로필사진 wndudwldbs1 만약 특수문자가 ereg 함수로 필터링 되있다면(영소문자,영대문자,숫자만입력가능) 어떻게 필터링을 우회할 수 있나요? 2015.08.01 20:36 신고
  • 프로필사진 ㅇㅇ 보통 웹어플 공격에 대한 방어는 특수문자 필터링으로 하곤 합니다.
    때문에 특수문자를 필터링하는데 이 필터링을 우회하는 방법이 있냐는 질문은 성립되기 어렵습니다.
    2015.08.06 11:00 신고
  • 프로필사진 ㅇㅇ 블로그 쥔장이 예시로 든 것은 사용자가 특수문자가 아닌 특정 문자열을 입력하여 인증을 시도하는 경우 필터링도 admin과 같은 특정 문자열을 막는 상황을 가정하고 쓴 글 같네요. 2015.08.06 11:04 신고
댓글쓰기 폼