본문으로 바로가기

Command Injection 

웹 애플리케이션에서 시스템 명령을 사용할 때세미콜론 혹은 &, && 를 사용하여 하나의 Command를 Injection 하여

두 개의 명령어가 실행되게 하는 공격

 

 

 

실습

여기 ip를 입력하면 ping을 4번 때린 결과를 볼 수 있는 기능이 있다.

 

 

코드를 살펴보면

<?php

if( isset( $_POST[ 'submit' ] ) ) {

    $target = $_REQUEST[ 'ip' ];

    // Determine OS and execute the ping command.
    if (stristr(php_uname('s'), 'Windows NT')) { 
    
        $cmd = shell_exec( 'ping  ' . $target );
        echo '<pre>'.$cmd.'</pre>';
        
    } else { 
    
        $cmd = shell_exec( 'ping  -c 3 ' . $target );
        echo '<pre>'.$cmd.'</pre>';
        
    }
    
}
?>

shell_exec() 함수를 통해 리눅스 명령어를 사용하는것을 볼수 있다.

PHP에서 명령어를 실행할 수 있는 함수로는 
system() , passthru() , exec() , shell_exec() 등이 자주 사용된다.
이외에도 escapeshellcmd() , pcntl_exec() , proc_open() , curl_exec() , curl_multi_exec() 등이 있다.

 

 

그림으로 이해를 하자면 아래와 같다.

 

따라서 다음과 같이 ; 혹은 &을 이용해서 추가 명령어를 실행한다.

 

이를 이용해서 민감 정보 혹은 파일을 심어서 서버를 마음대로 조작할 수 있는 파급력있는 취약점이지만 이러한 취약점을 가지고 있는 웹은 찾기 힘들다.

 

 

민감정보가 노출되는 모습

 

 

대처 방법

다음은 원래기능인 ping 기능만 실행하기 위해 입력 받은 ip를 검사해주는 코드를 추가한 것이다.

<?php

if( isset( $_POST[ 'submit' ] ) ) {

    $target = $_REQUEST["ip"];
    
    $target = stripslashes( $target );
    
    
    // Split the IP into 4 octects
    $octet = explode(".", $target);
    
    // Check IF each octet is an integer
    if ((is_numeric($octet[0])) && (is_numeric($octet[1])) && (is_numeric($octet[2])) && (is_numeric($octet[3])) && (sizeof($octet) == 4)  ) {
    
    // If all 4 octets are int's put the IP back together.
    $target = $octet[0].'.'.$octet[1].'.'.$octet[2].'.'.$octet[3];
    
    
        // Determine OS and execute the ping command.
        if (stristr(php_uname('s'), 'Windows NT')) { 
    
            $cmd = shell_exec( 'ping  ' . $target );
            echo '<pre>'.$cmd.'</pre>';
        
        } else { 
    
            $cmd = shell_exec( 'ping  -c 3 ' . $target );
            echo '<pre>'.$cmd.'</pre>';
        
        }
    
    }
    
    else {
        echo '<pre>ERROR: You have entered an invalid IP</pre>';
    }
    
    
}

?>

 

마무리

하지만 서버스크립트 프로그래밍에서 시스템 명령어를 사용하는 것은 가능한 피하는 것이 좋다. 반드시 사용해야 하는 경우라면 사용자의 입력이 전달되는 것을 차단해야 한다.