WEB언어/PHP

[PHP]문자열 필터링 함수 eregi 등의 취약점

saltdoll 2017. 12. 19. 04:33
반응형

PHP 5.3+의 환경의 eregi를 통해서 문자열 검증을 하는 경우가 잘 못 처리되는 경우가 있다. (POSIX Regex 필터)

그중에도, HTTP(GET)요청에 %00 (null)을 입력으로 입력하면, 해당 정보를 제대로 처리 못하는 경우가 있다.


test.php

<?
 
$_id = $_GET[id];
 
if (eregi("admin",$_id))
  echo "Filtered !!" . "<br>";
else
  echo $_id . "<br>";
 
?>


해당 환경에서는 오류없음

PHP5.3+환경에서 필터가 비정상적인 것을 알 수 있다.

다음과 같은 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



출처: http://hackability.kr/entry/PHP-문자열-필터링-함수ereg-eregi-취약점을-이용한-우회 [HACKABILITY]





== 추가 내용 =====

[PHP] strcmp 취약점을 이용한 인증 우회

php에서 strcmp 취약점을 이용한 인증 우회 기법


strcmp(A,B) 가 같은면, 0을 반환합니다.


login.php

<?php 
    $ps = 'pass';
    if (!isset($_GET['user_id']) || !isset($_GET['password'])) 
        die("parameter error"); 
 
    if (($_GET['user_id'] == 'admin'
        && (strcmp($ps$_GET['password']) == 0))
        die("login succeed..");
    else 
        die("login failed..");
?>



정상 처리시 예제

http://127.0.0.1/login.php?user_id=admin&password=pass

=> login succeed..


http://127.0.0.1/login.php?user_id=admin&password=asdf

=> login failed..



login.php로 돌아가 strcmp 구문을 우회 해보도록 하겠습니다. 우회 코드는 아래와 같습니다.

(GET 부분을 배열로 넘기는 부분)

http://127.0.0.1/login.php?user_id=admin&password[]=a 


PHP 버전 5.2 에서는 strcmp(String, Array()) 시에 Integer (1 or -1) 을 반환하고, 

PHP 버전 5.3 에서는 strcmp(String, Array()) 시에 NULL 을 반환합니다.

(PHP 버전 5.2에서는 Array()를 "Array" 라는 문자열로 변환하여 비교를 하게 됩니다.)


문제는 아래와 같이 비교 하는 구문인데요. 

if (strcmp(String, Array() == 0)


PHP 5.3 버전에서 strcmp 입력값으로 Array를 주었을 경우, 결과적으로 아래와 같은 행위를 하게 됩니다.

if (NULL == 0)


우리는 미리 결과를 봤기 때문에 NULL == 0 의 결과가 TRUE 라는 것을 알 수 있는데요, 그러면 결과적으로 NULL은 0 인 것일까요?


"==" 으로 비교한 결과


"==="으로 비교한 결과



위 두 표를 보시면 아시겠지만 느슨한 비교를 할 시에는 NULL이 숫자 0과 같기 때문에 0 == NULL 이 TRUE를 반환하지만 NULL이 0과 같은 타입이 아니기 때문에 0 === NULL 시에는 FALSE를 얻게 됩니다.
 



POST에서도 동일한 오류 발생

<?php

$a = $_POST['pass'];

$b = "password";

if (strcmp($a, $b) == 0)

echo "YOU ARE ADMIN !\n";

else

echo "YOU ARE NOT ADMIN! \n";

?>


POST로 데이터를 전송하기 위해 curl 프로그램을 사용하였습니다. 

curl 프로그램의 -X 파라미터를 이용하여 POST로 전송을 하였고, -d 옵션을 이용하여 데이터 부분을 채울 수 있었습니다.


테스트 결과 POST 역시 배열에 의해 GET과 동일하게 취약함을 알 수 있었습니다. 



출처: [PHP] strcmp 취약점을 이용한 인증 우회


반응형
도움이 되셨다면 하트모양의 "♡ 공감"을 눌러주시면 큰 격려가 됩니다.
(로그인하지 않으셔도 가능)