ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [A03:2021 - Injection] Command Injection (Low~High) - PHP
    Hacking/CTF 문제 풀이 2025. 6. 15. 23:42
    728x90
    반응형

    DVWA(Damn Vulnerable Web Application)는 웹 애플리케이션 보안 실습을 위한 플랫폼입니다.
    이번 글에서는 Command Injection 취약점 중 Low ~ high 보안 등급에서의 동작을 살펴보고 실제 공격 시나리오와 취약점 원인을 PHP 코드로 분석합니다.

    Command Injection 이란?

    사용자 입력값이 서버의 명령어 실행 함수에 그대로 전달되어 임의 명령어를 실행할 수 있게 되는 취약점입니다.
    공격자는 시스템 명령어를 삽입하여 파일 탐색, 시스템 정보 탈취, 권한 상승 등을 시도할 수 있습니다.


    🔓 Low 보안 등급

    <?php
    
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Get input
        $target = $_REQUEST[ 'ip' ];
    
        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
    
        // Feedback for the end user
        echo "<pre>{$cmd}</pre>";
    }
    
    ?>

    취약점 분석

    1. shell_exec() 함수는 인자로 전달된 문자열을 OS 명령어로 실행하고 결과를 반환합니다.
    2. 사용자 입력값 $_REQUEST['ip']에 대한 필터링이나 검증이 전혀 없어 공격자가 임의 쉘 명령어를 삽입할 수 있습니다.
    3. Linux에서 ;, &&, | 등 여러 명령어 연결자가 허용되어 명령어 삽입이 쉽습니다.
    shell_exec() 명령어 실행 후 결과를 문자열로 반환 echo로 출력 필요
    system() 명령어 실행 후 결과를 즉시 출력 자동 출력

    공격 예시

    127.0.0.1; ls -al
    • ping -c 4 127.0.0.1; ls -al 명령어로 해석되어 ping 실행 후 현재 디렉토리 목록을 출력합니다.

    🔐 Medium 보안 등급

    <?php
    
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Get input
        $target = $_REQUEST[ 'ip' ];
    
        // Set blacklist
        $substitutions = array(
            '&&' => '',
            ';'  => '',
        );
    
        // Remove any of the charactars in the array (blacklist).
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    
        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
    
        // Feedback for the end user
        echo "<pre>{$cmd}</pre>";
    }
    
    ?>

    취약점 분석

    1. Low 등급에서 발견된 ; 와 && 문자를 제거하는 필터링을 추가했지만 여전히 명령어 연결에 사용되는 다른 연산자들(|, & 등)은 차단하지 않아 취약점이 존재합니다.

    공격 예시

    127.0.0.1 | ls

    🛡️ High 보안 등급

    <?php
    
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Get input
        $target = trim($_REQUEST[ 'ip' ]);
    
        // Set blacklist
        $substitutions = array(
            '&'  => '',
            ';'  => '',
            '| ' => '',
            '-'  => '',
            '$'  => '',
            '('  => '',
            ')'  => '',
            '`'  => '',
            '||' => '',
        );
    
        // Remove any of the charactars in the array (blacklist).
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    
        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
    
        // Feedback for the end user
        echo "<pre>{$cmd}</pre>";
    }
    
    ?>

    취약점 분석

    1. 이전 등급에 비해 차단하는 문자가 많이 늘었으나 공백이나 다른 우회 기법에는 여전히 취약합니다.
    2. Blacklist 방식은 필터링 누락에 따른 우회가 쉽고 새로운 특수문자 등장 시 재차 검증이 필요하여 완전하지 않습니다.

    공격 예시

    127.0.0.1|ls

    👑 Impossible 보안 등급

    <?php
    
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
    
        // Get input
        $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' ) ) {
                // Windows
                $cmd = shell_exec( 'ping  ' . $target );
            }
            else {
                // *nix
                $cmd = shell_exec( 'ping  -c 4 ' . $target );
            }
    
            // Feedback for the end user
            echo "<pre>{$cmd}</pre>";
        }
        else {
            // Ops. Let the user name theres a mistake
            echo '<pre>ERROR: You have entered an invalid IP.</pre>';
        }
    }
    
    // Generate Anti-CSRF token
    generateSessionToken();
    
    ?>

    🔚 결론

    사실 이 공격이 통하는 웹서비스가 존재하는지가 의문입니다....

    하지만 이 취약점 상당히 심각한 위험을 가지고 있는 것도 사실입니다.

    • 사용자의 입력값을 신뢰하지 말고 검증해야합니다.
    • Blacklist 방식만 신뢰하면 안됩니다.
    728x90
    반응형
Designed by Tistory.