博客

  • 渗透测试时目标系统没有 python,如何构造超长字符串测试栈溢出?

    问题背景

    在渗透测试中,测试目标程序的栈缓冲区溢出漏洞时,需要构造大量字符(如 3000+ 个 A)作为输入,观察程序是否会崩溃或触发保护机制。

    但有些精简的嵌入式系统(BusyBox、纯 Shell 环境)没有安装 python 或 perl,无法用简单的方式生成测试数据:

    # 这些命令在精简系统上不存在
    python3 -c "print(A*3000)"
    perl -e "print Ax3000"

    解决方案

    方法一:dd + tr(最推荐)

    这是最通用的方法,dd 和 tr 是 POSIX 标准命令,几乎所有 Linux 系统都有。

    dd if=/dev/zero bs=3000 count=1 2>/dev/null | tr "\0" "A"

    参数解读:

    • dd if=/dev/zero – 从零设备读取字节
    • bs=3000 – 每次读写 3000 字节
    • count=1 – 只读取 1 次
    • tr \0 A – 把所有零字符转换为 A

    方法二:纯 Shell 循环

    如果系统没有 tr 命令,可以用 Shell 内置循环:

    i=0
    while [ $i -lt 2000 ]; do
      printf "A"
      i=$((i+1))
    done

    方法三:bash 大括号扩展

    注意:ash/dash 等精简 shell 不支持此语法

    printf A%.0s {1..3000}

    实际测试案例

    场景:测试程序是否有栈保护(Canary)

    目标:检查 /bin/busybox 是否有栈溢出保护

    步骤 1:生成超长字符串

    PAYLOAD=$(dd if=/dev/zero bs=5000 count=1 2>/dev/null | tr "\0" "A")
    echo "Payload 长度: ${#PAYLOAD}"

    步骤 2:执行测试

    # 方法1:作为命令行参数传入
    ./busybox "$PAYLOAD"
    
    # 方法2:通过管道传入
    echo "$PAYLOAD" | ./busybox

    步骤 3:判断结果

    输出结果 结论
    *** stack smashing detected *** ✅ 有栈保护 (Canary)
    *** stack protector aborted *** ✅ 有栈保护
    Segmentation fault (core dumped) ❌ 无栈保护,存在漏洞
    程序正常运行 参数未触发溢出,尝试增加长度

    场景:测试命令注入过滤

    测试目标程序是否对超长输入做了长度限制:

    PAYLOAD=$(dd if=/dev/zero bs=10000 count=1 2>/dev/null | tr "\0" "A")
    ./vulnerable_program "$PAYLOAD"

    观察输出:

    • 被截断 → 可能有长度过滤
    • 完整输出 → 可能存在溢出

    完整检测脚本

    #!/bin/sh
    # 二进制栈保护检测脚本 - 适用于无 python/perl 的精简系统
    
    TARGET=${1:-"./test_program"}
    
    echo "=== 栈溢出测试 ==="
    echo "目标: $TARGET"
    
    # 生成 5000 个字符的测试数据
    PAYLOAD=$(dd if=/dev/zero bs=5000 count=1 2>/dev/null | tr "\0" "A")
    echo "测试 payload 长度: ${#PAYLOAD}"
    
    # 执行并捕获输出
    OUTPUT=$(timeout 2 "$TARGET" "$PAYLOAD" 2>&1)
    RESULT=$?
    
    echo "执行结果码: $RESULT"
    
    # 分析输出
    if echo "$OUTPUT" | grep -q "stack smashing"; then
      echo "✅ 结果: 程序有栈保护 (Canary enabled)"
      echo "   攻击者需先绕过 Canary 才能利用溢出"
      exit 0
    elif echo "$OUTPUT" | grep -qi "segmentation fault"; then
      echo "❌ 结果: 程序无栈保护 (No Canary)"
      echo "   存在栈溢出漏洞,可尝试提权"
      exit 1
    elif [ $RESULT -eq 139 ] || [ $RESULT -eq 136 ]; then
      echo "❌ 结果: 程序崩溃 (信号 $RESULT)"
      echo "   可能存在漏洞,需进一步分析"
      exit 1
    else
      echo "⚠️ 结果: 未触发崩溃"
      echo "   尝试增加 payload 长度 (修改 bs=5000 为 bs=10000)"
    fi

    使用方法:

    chmod +x test_canary.sh
    ./test_canary.sh /path/to/target_binary

    常见问题

    Q: 生成多长的字符串合适?

    A: 从 1000 开始,如果没触发溢出,逐步增加到 5000、10000。不同漏洞触发所需长度不同。

    Q: 除了 A 还能用什么字符?

    A:

    • 测试英文程序:用 A 或 x
    • 测试中文处理:用中文测试时注意编码
    • 测试特殊字符:用 printf 生成换行符、制表符等

    Q: 程序崩溃但没有明显输出?

    A: 使用 $? 查看退出码,139 通常表示段错误 (Segmentation Fault)。


    总结:渗透测试中测试栈溢出时,精简系统没有 python 用 dd + tr 组合是最可靠的方法。生成超长字符串后执行目标程序,观察是否触发 stack smashing 来判断是否存在漏洞。

    核心命令:

    dd if=/dev/zero bs=5000 count=1 2>/dev/null | tr "\0" "A"
  • ADB 离线部署 linux-exploit-suggester

    问题背景

    目标车辆零部件系统没有网络,无法直接下载工具。但可以通过 ADB 连接,如何把 linux-exploit-suggester 部署到目标系统上?

    方案一:ADB 推送 + Shell 运行(推荐)

    # 推送脚本到设备
    adb push linux-exploit-suggester.sh /data/local/tmp/
    
    # 进入设备 Shell 并运行
    adb shell
    cd /data/local/tmp
    chmod +x linux-exploit-suggester.sh
    ./linux-exploit-suggester.sh

    方案二:手动导出信息 + 离线分析

    如果无法在目标设备运行脚本:

    # 导出系统信息
    adb shell uname -a > kernel_info.txt
    adb shell cat /etc/os-release > os_info.txt
    
    # 在攻击机离线分析
    ./linux-exploit-suggester.sh --uname "Linux hostname 5.4.0-42-generic"

    方案三:介质摆渡(无 ADB 时)

    使用 U 盘等介质:

    # 拷贝到 U 盘
    cp linux-exploit-suggester.sh /media/usb/
    
    # 插入目标设备并挂载
    mount /dev/sdb1 /mnt/usb
    cp /mnt/usb/linux-exploit-suggester.sh /tmp/
    
    # 运行
    cd /tmp
    chmod +x linux-exploit-suggester.sh
    ./linux-exploit-suggester.sh

    注意事项

    • 脚本主要依赖 bash 或 sh,大多数嵌入式系统都有
    • 无法联网时,脚本需要联网下载 POC 会失败,但核心漏洞检测功能不受影响
    • 确保推送到有执行权限的目录(如 /tmp)
  • WSL Kali 如何接收外部 nc 连接?

    问题背景

    在 WSL2 中运行 Kali Linux,想让远程服务器通过 nc 发送文件到本地。但不清楚目标 IP 应该填什么。

    情况一:同一局域网(最简单)

    如果远程服务器和你的电脑在同一个局域网,直接用电脑的局域网 IP。

    # WSL Kali 监听
    nc -l -p 9999 > received_file.zip
    # 远程服务器发送
    nc 192.168.255.112 9999 < file_to_send.zip

    情况二:公网连接(需要反向连接)

    如果远程服务器在云上,使用反向连接:

    # 目标监听
    nc -l -p 9999
    # WSL 主动连接
    nc <远程服务器公网IP> 9999 > received_file.zip

    情况三:通过端口转发

    需要配置 Windows 防火墙和 WSL 端口转发(较复杂)。

    最佳实践

    优先使用反向连接:无论目标能否访问你,都可以用。

    # 目标监听
    nc -l -p 9999 < file.zip
    # WSL 获取
    nc <目标公网IP> 9999 > file.zip

    这样不需要配置任何防火墙或端口转发。

  • TFTP 没有正确目录,如何传输文件?

    问题背景

    使用 TFTP 从目标系统下载文件时,发现目标系统的 TFTP 根目录不是常见路径,导致文件无法传输。

    解决方案

    方案一:使用 HTTP 替代(推荐)

    如果目标系统有 python:

    cd /root
    python3 -m http.server 8080

    本地下载:

    wget http://<目标IP>:8080/firmware.bin

    完成后按 Ctrl+C 停止服务器。

    方案二:移动文件到 TFTP 目录

    先找根目录:

    ls -ld /var/lib/tftpboot /tftpboot /srv/tftp

    移动文件:

    cp /root/firmware.bin /var/lib/tftpboot/
    chmod 644 /var/lib/tftpboot/firmware.bin

    方案三:使用 nc 传输

    # 目标监听
    nc -l -p 9999 < /root/firmware.bin
    # 本地接收
    nc <目标IP> 9999 > firmware.bin

    对比总结

    • HTTP (python):简单、任意路径、无需配置
    • TFTP:标准协议,但需要找根目录
    • nc:快速、直连

    在嵌入式渗透测试中,优先尝试 python HTTP 服务器,这是最省事的方法。

  • 没有 iptables 命令,但可能有防火墙怎么办?

    问题背景

    在渗透测试中,有时发现目标系统没有 iptables 命令。但这不代表没有防火墙,可能只是用了其他工具。

    常见原因

    • 使用了 nftables(iptables 的继任者)
    • 使用了云服务商的安全组
    • 使用了 firewalld、ufw
    • iptables 命令被删除但规则仍生效

    解决方案

    方法一:检查 nftables

    sudo nft list ruleset

    方法二:检查云安全组

    如果是云服务器,防火墙规则可能在云控制台。测试方法:

    telnet <目标IP> <端口>

    方法三:检查 firewalld

    sudo firewall-cmd --state
    sudo firewall-cmd --list-all

    删除 iptables 后规则是否生效?

    结论:是的,规则仍然生效。iptables 只是管理工具,真正的规则存储在内核 Netfilter 模块中。

  • strings 找不到 __stack_chk_fail,如何检测二进制保护?

    问题背景

    检测二进制文件是否开启了栈保护(Canary),通常使用 strings | grep __stack_chk_fail。但如果二进制文件被 strip(剥离了符号表),这个方法就会失效,返回空结果。

    解决方案

    方法一:动态测试法(最可靠)

    通过构造栈溢出,观察程序崩溃时的行为来判断。

    dd if=/dev/zero bs=5000 count=1 2>/dev/null | tr "\0" "A" > payload.txt
    ./target_program "$(cat payload.txt)"

    结果判断:

    • 输出 *** stack smashing detected *** → ✅ 有 Canary 保护
    • 输出 Segmentation fault → ❌ 无 Canary 保护

    方法二:检查文件是否被 strip

    file target_program

    输出包含 stripped → 符号表已被删除

    核心结论

    静态检测失败 → 用动态测试。strings 无结果 ≠ 无保护(可能被 strip)。动态测试是金标准:触发溢出看是否报 stack smashing。

  • 精简系统没有 getenforce/sestatus,如何检测 SELinux?

    问题背景

    在渗透测试中,有时会遇到非常精简的 Linux 系统(如嵌入式设备、容器、BusyBox 环境),这些系统可能没有安装 SELinux 的管理工具:

    • 没有 getenforce 命令
    • 没有 sestatus 命令
    • 没有 /sys/fs/selinux 目录
    • mount 也找不到 selinux 相关信息

    这种情况下,如何判断系统是否开启了 SELinux?

    解决方案

    方法一:读取内核状态文件

    这是最直接的方法。SELinux 运行时会在 /sys/fs/selinux 挂载一个文件系统,但如果目录不存在,基本可以确定 SELinux 未启用。

    # 检查 enforce 状态文件
    cat /sys/fs/selinux/enforce

    结果解读:

    • 输出 1Enforcing(强制模式,已启用)
    • 输出 0Permissive(宽容模式,已启用但只记录不拦截)
    • 文件不存在 → Disabled(未启用)

    方法二:检查内核启动参数

    如果方法一失败,可以通过内核启动参数进一步确认:

    cat /proc/cmdline

    查找以下参数:

    • selinux=0 → 明确禁用
    • enforcing=0 → 设为宽容模式
    • 如果没有这些参数 → 通常默认启用(取决于编译配置)

    方法三:检查文件系统挂载点

    即使目录不存在,也可以检查是否尝试挂载过:

    ls -ld /sys/fs/selinux
    mount | grep selinux

    方法四:检查 SELinux 相关内核模块

    如果系统编译了 SELinux 作为模块,可以检查模块是否加载:

    lsmod | grep selinux

    完整检测脚本

    #!/bin/sh
    echo "=== SELinux 状态检测 ==="
    
    # 方法1:检查 enforce 文件
    if [ -f /sys/fs/selinux/enforce ]; then
        status=$(cat /sys/fs/selinux/enforce)
        if [ "$status" = "1" ]; then
            echo "✅ Enforcing(强制模式)"
        else
            echo "⚠️ Permissive(宽容模式)"
        fi
        exit 0
    fi
    
    # 方法2:检查内核参数
    if grep -q "selinux=0" /proc/cmdline; then
        echo "❌ 已通过内核参数明确禁用"
    elif grep -q "enforcing=0" /proc/cmdline; then
        echo "⚠️ 已通过内核参数设为宽容模式"
    else
        echo "❓ 未检测到 SELinux,可能未编译或未启用"
    fi

    实际测试结果

    根据一次嵌入式设备测试的实际结果:

    测试命令:getenforce → 无此命令
    测试命令:sestatus → 无此命令
    测试命令:ls /sys/fs/selinux → 目录不存在
    测试命令:mount | grep selinux → 无输出

    结论: 系统未开启 SELinux。

    安全影响分析

    如果确认系统未开启 SELinux,意味着该系统缺少了 MAC(强制访问控制) 这一层重要防护:

    • 即使通过 SUID 漏洞获得 root 权限,也没有额外的访问控制限制
    • Root 用户可以访问任意文件,包括 /etc/shadow
    • 需要依靠传统的 DAC(自主访问控制)来保护系统

    扩展:检查 AppArmor

    有些系统可能使用 AppArmor 作为替代方案:

    ls -d /sys/kernel/security/apparmor 2>/dev/null && echo "AppArmor 已开启" || echo "AppArmor 未开启"

    参考命令:

    • getenforce – 最简方式
    • cat /sys/fs/selinux/enforce – 文件方式
    • cat /proc/cmdline – 启动参数方式
  • 测试文章 – 来自爪爪

    这是一篇测试文章 🐾

    Hello World! 这是通过 WordPress REST API 自动发布的。