BashFuck学习
字数 1087 2025-08-18 17:33:32

BashFuck 技术详解

0x00 前言

BashFuck 是一种利用 Bash 脚本特性进行命令混淆和绕过限制的技术,类似于著名的 Brainfuck 编程语言概念。这种技术在渗透测试和 CTF 比赛中特别有用,可以绕过某些字符过滤限制。

0x01 基础知识

系统兼容性说明

  • Debian/Ubuntu 系统的 sh 软链接指向 dash
  • CentOS 系统的 sh 软链接指向 bash
  • Kali Linux 的 zsh 不完全兼容 dash,导致 IFS 解析问题(可用空格代替)

关键概念

  1. IFS (Internal Field Separator): Bash 中的内部字段分隔符,默认为空格、制表符和换行符
  2. 算术扩展 $(()): 用于执行算术运算并返回结果
  3. 八进制/十六进制表示法: Bash 中可以使用 \xxx 形式表示字符

0x02 常见技术方法

方法一:Common Oct (常规八进制编码)

将命令转换为八进制表示形式:

sum_data = ''
str1 = input("请输入要转化的命令:")
str1 = str1.strip()  # 去除首尾空格
data_len = len(str1)  # 判断总长度来循环
for i in range(data_len):
    data = ord(str1[i])
    if data == ord(' '):  # 检查空格字符
        sum_data += "'$IFS$'"
    else:
        data_8 = oct(data)[2:]
        final_data = '\\' + data_8
        sum_data += final_data
print("common_oct")
print("$'" + sum_data + "'")

示例:

$'\154\163'  # 等同于 ls 命令

方法二:BashFuck X (算术扩展构造)

利用算术扩展 $(()) 构造命令:

  1. 基本形式:
"$"''\''\'$(($((1))54))'\'$(($((1))63))\'
  1. 二进制构造形式:
$\'\\$(($((1<<1))#10011010))\\$(($((1<<1))#10100011))\'

数字表示方法:

  • ${#} → 0
  • ${##} → 1
  • ${#_} → 1
  • ${_} → 1
  • ${?} → 0
  • ${?#} → 1

Python 转换脚本:

def bashfuckx():
    final_str1 = ''
    final_str2 = ''
    final_str3 = ''
    str3 = input("请输入要转化的命令:")
    for j in str3:
        final_str1 += '$0<<<$0\\<\\<\\<\\$\\\'' +f'\\\\$(($((1<<1))#{bin(int(get_oct(j)))[2:]}))'+ '\\\''
        final_str2 = '$0<<<$0\\<\\<\\<\\$\\\'' +final_str1.replace('1', '${##}')+ '\\\''  # 用 ${##} 来替换 1
        final_str3 = '${!#}<<<${!#}\\<\\<\\<\\$\\\'' +final_str1.replace('1', '${##}').replace('0', '${#}')+ '\\\''  # 用 ${#} 来替换 0
    result = input("请输入你要的格式\n1代表直接转化\n2代表替换1\n3代表全部替换(无数字)")
    if result == '1':
        print(final_str1)
    elif result == '2':
        print(final_str2)
    elif result == '3':
        print(final_str3)
    else:
        print("无效输入!")

注意: 由于扩展顺序问题,需要使用标准输入完成解析:

/bin/bash<<<

方法三:BashFuck Y (取反构造)

利用 -1 的取反特性构造数字:

数字构造表:

oct_list = [  # 构造数字 0-7 以便于后续八进制形式的构造
    '$(())',  # 0
    '$((~$(($((~$(())))$((~$(())))))))',  # 1
    '$((~$(($((~$(())))$((~$(())))$((~$(())))))))',  # 2
    '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 3
    '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 4
    '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 5
    '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 6
    '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 7
]

示例 Payload (执行 ls 命令):

__=$(())&&${!__}<<<${!__}\<\<\<\$\'\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\'

0x03 技术要点总结

  1. 字符集限制绕过:

    • 使用八进制/二进制表示法绕过特定字符限制
    • 利用 Bash 变量扩展构造所需字符
  2. 执行方式:

    • 通过标准输入重定向解决扩展顺序问题
    • 使用 $0 表示当前 shell (通常是 bash)
  3. 无数字构造:

    • 使用 ${#} 表示 0
    • 使用 ${##} 表示 1
    • 通过这些基础构造所有需要的数字
  4. 空格处理:

    • 使用 $IFS$ 或直接空格
    • 在 Kali zsh 中可能需要直接使用空格

0x04 参考资源

  1. BashFuck GitHub 仓库
  2. GNU Bash 手册 - Shell 扩展

0x05 实际应用建议

  1. 在 CTF 比赛中遇到字符限制时,可以考虑使用 BashFuck 技术
  2. 渗透测试中遇到命令注入但存在字符过滤时,可以尝试此类方法
  3. 建议先本地测试构造的命令,确保在不同系统上的兼容性
  4. 对于复杂命令,可以分段构造测试
BashFuck 技术详解 0x00 前言 BashFuck 是一种利用 Bash 脚本特性进行命令混淆和绕过限制的技术,类似于著名的 Brainfuck 编程语言概念。这种技术在渗透测试和 CTF 比赛中特别有用,可以绕过某些字符过滤限制。 0x01 基础知识 系统兼容性说明 Debian/Ubuntu 系统的 sh 软链接指向 dash CentOS 系统的 sh 软链接指向 bash Kali Linux 的 zsh 不完全兼容 dash ,导致 IFS 解析问题(可用空格代替) 关键概念 IFS (Internal Field Separator) : Bash 中的内部字段分隔符,默认为空格、制表符和换行符 算术扩展 $(()) : 用于执行算术运算并返回结果 八进制/十六进制表示法 : Bash 中可以使用 \xxx 形式表示字符 0x02 常见技术方法 方法一:Common Oct (常规八进制编码) 将命令转换为八进制表示形式: 示例 : 方法二:BashFuck X (算术扩展构造) 利用算术扩展 $(()) 构造命令: 基本形式: 二进制构造形式: 数字表示方法 : ${#} → 0 ${##} → 1 ${#_} → 1 ${_} → 1 ${?} → 0 ${?#} → 1 Python 转换脚本 : 注意 : 由于扩展顺序问题,需要使用标准输入完成解析: 方法三:BashFuck Y (取反构造) 利用 -1 的取反特性构造数字: 数字构造表 : 示例 Payload (执行 ls 命令): 0x03 技术要点总结 字符集限制绕过 : 使用八进制/二进制表示法绕过特定字符限制 利用 Bash 变量扩展构造所需字符 执行方式 : 通过标准输入重定向解决扩展顺序问题 使用 $0 表示当前 shell (通常是 bash) 无数字构造 : 使用 ${#} 表示 0 使用 ${##} 表示 1 通过这些基础构造所有需要的数字 空格处理 : 使用 $IFS$ 或直接空格 在 Kali zsh 中可能需要直接使用空格 0x04 参考资源 BashFuck GitHub 仓库 GNU Bash 手册 - Shell 扩展 0x05 实际应用建议 在 CTF 比赛中遇到字符限制时,可以考虑使用 BashFuck 技术 渗透测试中遇到命令注入但存在字符过滤时,可以尝试此类方法 建议先本地测试构造的命令,确保在不同系统上的兼容性 对于复杂命令,可以分段构造测试