Command injection Vulnerability

Command Injection is submitted by malicious parameters of the structure of the destruction of command structure, so as to achieve the purpose of the implementation of malicious commands. PHP command injection vulnerability is a common PHP application vulnerabilities.

On this post, i am going to guide how to analysic code for finding command injection.

Requirement:

  • apache server/ngix
  • dvwa

There are four Security level on DVWA Lab.

  1. Low security level The server-side core code
    <?phpif( 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>”;
    }?>You can see two function:stristr(string,search,before_search)
    The stristr function searches for the first occurrence of a string in another string, returning the rest of the string (from the matching point), or FALSE if the searched string is not found. The parameter string specifies the string to be searched, and the search keyword specifies the string to be searched (if the argument is a number, it searches for a character that matches the ASCII value of the number). The optional parameter before_true is a boolean, , If set to “true”, the function will return the search parameter before the first occurrence of the string part.

    php_uname(mode)
    This function returns the description of the operating system that is running php. The value of the parameter mode is “a” (this is the default, containing all the patterns in the sequence “snrvm”), “s” (returns the operating system name) (Returns the hostname), “r” (returns the version name), “v” (returns version information), and “m” (returns the machine type).

    As you can see, the server by the operating system to determine the implementation of different ping command, but the ip parameters did not do any filtering, resulting in a serious command injection vulnerability.

    To exploit, i simple use && character

  2. Medium security level The server-side core code<?phpif( 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>”;
    }

    ?>

    You can see, compared to low-level code, the server-side ip parameters to do a certain filter, that is, “&&”, “;”, essentially blacklist mechanism is used, so there is still a security problem.

    To exploit, i simple use & character, because, this character is not filtered.

  3. High security level
    The server-side core code

    <?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>”;
    }

    ?>

    Compared to Medium-level code, High-level code to further improve the blacklist, but because of the limitations of the blacklist mechanism, we can still bypass.

    Blacklist appears to filter out all illegal characters, but careful observation is to “|” with empty characters. “|” character is a pipe character that indicates the output of Command1 as an input to Command2 and prints only the results of Command2 execution.

  4. Impossible security level
    The server-side core code

    <?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();

    ?>

    You can see three functions:

    stripslashes(string)
    deletes the backslash in the string and returns the string that has been stripped of the backslash.
    explode(separator,string,limit)
    Breaks the string into an array and returns an array of strings. The argument separator specifies where to split the string, the string argument is the string to be split, and the optional parameter limit specifies the number of array elements returned.

    is_numeric(string)
    Checks whether string is a numeric or numeric string, if it returns TRUE, otherwise returns FALSE.

    As you can see, Impossible level of code to join the Anti-CSRF token, while the parameters ip strict restrictions.

DEMO

https://www.youtube.com/watch?v=xzCZi6srE-0