DVWA | Command Injection(命令注入)通关笔记

概念

命令注入漏洞(Command Injection Vulnerability)是一种安全漏洞,攻击者可以通过将恶意命令注入到应用程序中,执行未授权的系统命令。以下是该漏洞的产生原因及其危害:

### 产生原因

1. **不当输入验证**:
   - 应用程序没有对用户输入进行充分的验证和清洗,允许恶意输入。

2. **动态构建命令**:
   - 程序在构建系统命令时直接使用用户输入,而没有使用安全的方式(如参数化)。

3. **信任用户输入**:
   - 开发者过于信任来自用户的输入,未意识到这些输入可能包含恶意内容。

4. **错误配置**:
   - Web服务器或应用程序的错误配置可能使命令注入攻击更容易发生。

### 危害

1. **远程执行命令**:
   - 攻击者可以执行任意系统命令,获取系统权限。

2. **数据泄露**:
   - 通过命令注入,攻击者可能访问敏感数据,如用户信息和系统配置。

3. **系统破坏**:
   - 攻击者可以删除文件、修改数据或破坏系统,导致服务中断

4. **后门安装**:
   - 攻击者可在系统中植入后门,长期控制系统。

5. **影响声誉**:
   - 安全事件可能导致用户信任下降,损害企业声誉。

### 总结

命令注入漏洞具有严重的危害,因此,开发者应采取适当的安全措施,如对用户输入进行严格验证和使用安全的命令构建方法,以防止此类攻击的发生。

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

?>

提取Sumbit键值(即输入的ip),做空值校验,

REQUEST传递ip,赋值给$target,

利用php_uname(),返回PHP的系统名称,利用stristr()函数查询前面返回的系统名称中是否存在'Windows NT'字样。

如果存在,则ping

如果不存在,则 ping -c 4,

最后打印最终执行的命令。

shell_exec(‘[$cmd],[$value]’):直接执行命令$cmd。 可见对$value可能存在的非法字符的注入。

于是我们构造命令A:127.0.0.1&ipconfig 

//执行ping 127.0.0.1 和 ipconfig

构造命令B:127.0.0.1&&ipconfig(执行结果通上方一致)

//只有前半段执行成功了才会执行ipconfig 

构造命令C: 127.0.0.1 | ipconfig   xxxx|ipconfig

//前半段后台执行,并且前半段执行失败不影响执行ipconfig

 构造命令D:xxxx || ipconfig

//当且仅当前半段执行失败,才会执行后半段

  构造命令E:127.0.0.1 || ipconfig

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

?>

提取Sumbit键值(即输入的ip),做空值校验,

REQUEST传递ip,赋值给$target,

非法字符数组,

利用php_uname(),返回PHP的系统名称,利用stristr()函数查询前面返回的系统名称中是否存在'Windows NT'字样。

如果存在,则ping

如果不存在,则 ping -c 4,

最后打印最终执行的命令。

这次代码对$target变量做了变量清洗。

str_replace() 函数,替换字符串中的一些字符并作大小写区分。

str_replace([查找的值],[替换前者的值],[目标字符串]),即如果出现&&和;做替换为空处理。

既然只对&&和;做处理,那我们就好办了,

开始构造命令F:127.0.0.1&whoami

 构造命令G:127.0.0.1 | whoami

//前半段后台执行,仅回显whoami的执行结果

 构造命令F: xxxx | ipconfig

 多次尝试后,只有以上三种构造方式可以。

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

?>

说白了就是做了多种过滤,发现管道符后面莫名奇妙的过滤了空格,我们可以去掉空格试试:

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

?>

做了token校验,并做了Sumbit输入格式的限制,不存在命令注入漏洞。

命令注入漏洞加固方法:

防止命令注入漏洞可以采取以下几种有效措施:

1. **输入验证**:
   - 对所有用户输入进行严格验证,确保只接受合法字符和格式,使用白名单策略。

2. **使用参数化命令**:
   - 在执行系统命令时,尽量使用参数化的API或库,如`exec`函数中的参数数组,而不是直接拼接字符串。

3. **避免使用系统命令**:
   - 尽量避免在应用中调用系统命令,使用语言自带的功能或库来实现相同的功能。

4. **最小化权限**:
   - 确保运行应用的用户权限最小化,仅允许其执行必要的操作,降低潜在风险。

5. **错误处理**:
   - 实施适当的错误处理,避免泄露系统信息,防止攻击者通过错误消息获取有用的信息。

6. **定期审计和测试**:
   - 进行安全审计和渗透测试,定期检查代码中是否存在潜在的命令注入漏洞。

通过这些措施,可以有效降低命令注入漏洞的风险,提升应用程序的安全性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值