DVWA Command Injection low & impossible level code review 및 대응방안 제시
<?php
if(isset($_POST['submit'])){
$target = $_REQUEST['ip'];
if (stristr(php_uname('s'), 'Windows NT')){
$cmd = shell_exec('ping ' . $target);
}
else {
$cmd = shell_exec('ping -c 4 ' . $target);
}
echo "<pre>$output</pre>";
}
?>
소스코드 리뷰 : 입력받은 값(ip=target)에 대해 아무 검증없이 shell_exec함수를 실행하고 결과를 반환하기 때문에 Command Injection에 대한 취약점 존재.
shell_exec는 PHP 4, PHP 5, PHP 7, PHP 8에서 사용가능.
<?php
if(isset($_POST['Submit'])) {
checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php');
$target = $_REQUEST['ip'];
$target = stripslashes($target);
$octet = explode(".", $target);
if((is_numeric($octet[0])) && (is_numeric($octet[1])) && (is_numeric($octet[2])) && (is_numeric($octet[3])) && (sizeof($octet) == 4)) {
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
if(stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec('ping ' . $target);
}
else {
$cmd = shell_exec('ping -c 4 ' . $target);
}
$html .= "<pre>{$cmd}</pre>";
}
else {
$html .= '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
generateSessionToken();
?>
function checkToken( $user_token, $session_token, $returnURL ) { # Validate the given (CSRF) token
global $_DVWA;
if (in_array("disable_authentication", $_DVWA) && $_DVWA['disable_authentication']) {
return true;
}
if( $user_token !== $session_token || !isset( $session_token ) ) {
dvwaMessagePush( 'CSRF token is incorrect' );
dvwaRedirect( $returnURL );
}
}
소스코드 리뷰 : checkToken 메소드를 사용해서 토큰을 검증 후 입력값을 사용한다. 이때 입력값은 stripslashes로 이스케이프 후 explode 함수로 분할하고, 각 자리가 옥텟인지 확인(is_numeric함수사용), 4개가 모두 옥텟이 맞는지 확인 후 재구성해 사용한다.
shell_exec와 같은 쉘 명령어는 사용지양. 반드시 사용해야 한다면, 사용자 입력값을 검증(유효성 검사)후 사용한다.
escapeshellarg()함수를 입력값 검증에 사용 가능. (PHP 4.0.3~ 사용가능) : 문자열 작음 따옴표 추가 및 \이스케이프.