命令注入
环境变量
BASH_ENV
您可以使用 BASH_ENV 与 bash 来实现命令注入:
$ BASH_ENV='$(id 1>&2)' bash -c 'echo hello'
uid=0(root) gid=0(root) groups=0(root)
hello参考:
BASH_FUNC_*%%
您可以使用 BASH_FUNC_*%% 根据环境变量的值初始化匿名函数并为其命名。以下示例将 myfunc 函数添加到 bash 上下文中:
$ env $'BASH_FUNC_myfunc%%=() { id; }' bash -c 'myfunc'
uid=0(root) gid=0(root) groups=0(root)此外,您可以覆盖现有函数:
$ env $'BASH_FUNC_echo%%=() { id; }' bash -c 'echo hello'
uid=0(root) gid=0(root) groups=0(root)
hello参考:
ENV
当您强制 dash 以交互方式运行时,dash 将查找 ENV 环境变量并将其传递给 read_profile 函数:
read_profile 将打印 ENV 内容:
您可以使用 sh 获得相同的结果:
参考:
GIT_*
以下 GIT_* 参数可用于滥用 git 目录:
GIT_DIR 是
.git文件夹的位置GIT_PROXY_COMMAND 用于覆盖
core.gitProxyGIT_SSH_COMMAND 用于覆盖
core.sshCommandGIT_EXTERNAL_DIFF 用于覆盖
diff.externalGIT_CONFIG*。现代版本的 Git 支持通过
GIT_CONFIG*环境变量设置任何配置值
LD_PRELOAD
LD_PRELOAD 是一个可选的环境变量,包含一个或多个共享库或共享对象的路径,加载程序将在任何其他共享库(包括 C 运行时库 libc.so)之前加载它们。
在 Linux C 中,函数可以在函数定义中使用属性进行声明。这是通过将所需的属性添加到函数定义中来完成的。有两个感兴趣的属性,constructor 和 destructor。具有 constructor 属性的函数将在程序执行 main() 之前运行。对于共享对象,这将发生在加载时。使用 destructor 属性声明的函数应该在 main() 返回或调用 exit() 时运行一次。
换句话说,您可以编译一个共享库在加载时和/或返回之前调用:
重用以下代码来编译共享库:
// C code for LD_PRELOAD injection example // This is a generic LD_PRELOAD example that can be used for testing
使用以下命令编译共享库:
利用:
参考:
PERL5OPT
PERL5OPT 指定命令行选项,但仅限于接受选项 CDIMTUWdmtw。
PERL5OPT=-M 可用于加载 Perl 模块并在模块名称后添加额外代码:
参考:
PERL5DB
PERL5DB 指定用于加载调试器代码的命令。PERL5DB 仅在 Perl 以裸 -d 开关启动时使用。
参考:
PERLLIB 和 PERL5LIB
PERLLIB 和 PERL5LIB 设置在标准库中查找 Perl 库文件的目录列表。如果定义了 PERL5LIB,则不使用 PERLLIB。
如果有办法将恶意的 Perl 模块写入文件系统,PERLLIB 和 PERL5LIB 可用于执行任意命令:
参考:
PYTHONWARNINGS
PYTHONWARNINGS 等同于指定用于警告控制的 -W 选项。参数的完整形式是 action:message:category:module:line。
如果指定的类别包含点,警告控制会触发任意 Python 模块的导入:
如果有办法将恶意的 Python 模块写入文件系统,PYTHONWARNINGS 可用于执行任意命令:
但是,您可以使用 Python 标准库中的 antigravity 模块来运行任意命令。运行 import antigravity 将立即打开浏览器到 xkcd 漫画,该漫画开玩笑说在 Python 中 import antigravity 会赋予您飞行的能力。antigravity 使用标准库中称为 webbrowser 的另一个模块来打开浏览器。此模块检查 PATH 以查找各种浏览器,包括 mosaic, opera, skipstone, konqueror, chrome, chromium, firefox, links, elinks and lynx。它还接受一个环境变量 BROWSER,可用于指定应执行哪个进程。无法在环境变量中为进程提供参数,xkcd 漫画 URL 是命令的硬编码参数:
执行任意命令的一种方法是利用 Perl,它通常安装在系统上,甚至在标准的 Python docker 镜像中也可用。但是,perl 二进制文件本身不能使用。这是因为第一个也是唯一的参数是 xkcd 漫画 URL。漫画 URL 参数将导致错误并使进程退出,而不使用 PERL5OPT 环境变量。
幸运的是,当 Perl 可用时,通常也有默认的 Perl 脚本可用,例如 perldoc 和 perlthanks。这些脚本也会错误并以无效参数退出,但这种情况下的错误发生在 PERL5OPT 环境变量处理之后。这意味着可以利用 Perl 环境变量来执行命令。
参考:
NODE_OPTIONS
NODE_OPTIONS 指定以空格分隔的命令行选项列表。
如果有办法将恶意的 Node.js 模块写入文件系统,NODE_OPTIONS 可用于执行任意命令:
如果没有办法将模块写入文件系统,您可以使用 proc 文件系统,特别是 /proc/self/environ,来传递 payload。
但是,有两个约束条件:
使用
/proc/self/environ只有在内容在语法上有效 JavaScript 时才可能。为此,您需要能够创建环境变量并使其首先出现在/proc/self/environ的内容中。由于第一个环境变量的值以单行注释
//结尾,其他环境变量中的任何换行符都将导致语法错误。使用多行注释/*不会解决问题,因为它们必须关闭才能在语法上有效。在这种情况下,需要覆盖包含换行符的变量的值。
参考:
RUBYOPT
RUBYOPT 指定命令行选项。
如果有办法将恶意的 Ruby 库写入文件系统,RUBYOPT 可用于执行任意命令。-r 选项使 Ruby 使用 require 加载库,但这仅限于扩展名为 .rb 或 .so 的文件:
参考:
编程语言
Go
Java
Node.js
Python
Ruby
Linux 文件
/etc/environment
/etc/environment 包含指定新 shell 基本环境变量的环境变量。但是,它可以被其他程序使用。Linux 任务调度程序(cron)中的每个执行作业都导入此文件,如果存在由用户(例如 root)执行的作业,您可以滥用 /etc/environment 代表该用户执行任意代码。例如,您可以使用 LD_PRELOAD 来获得代码执行。
参考:
技巧
花括号扩展
花括号扩展是一种生成任意字符串的机制。要花括号扩展的模式采用可选序言的形式,后跟一系列逗号分隔的字符串或一对花括号之间的序列表达式,后跟可选的后记。序言前缀到包含在花括号内的每个字符串,然后后记附加到每个结果字符串,从左到右扩展。例如:
您可以使用花括号扩展来创建 payload:
参考:
命令替换
命令替换允许命令的输出替换命令本身。当命令按如下方式包含时,会发生命令替换:
Bash 通过在子 shell 环境中执行命令并用命令的标准输出替换命令替换来执行扩展。
参考:
字符编码
有几种处理编码字符串的方法:
$'string'单词:形式为
$'string'的单词被特殊处理。该单词扩展为字符串,反斜杠转义字符按照 ANSI C 标准指定的方式替换。echo命令:echo提供-e选项来解释反斜杠转义。注意识别的序列取决于echo的版本,以及-e选项可能根本不存在。xxd命令:
参考:
泄露命令行参数
如果您在 cli 命令中有参数注入,该命令已传递敏感参数,如令牌或密码,您可以尝试使用 ps x -w 泄露传递的秘密。
如果 cli 日志隐藏敏感设置或敏感数据未存储在环境中,这可能会很有用。
如果 cli 日志隐藏敏感数据或敏感数据未存储在环境中(例如,GitHub Actions 提供变量插值 ${{...}} 用于注入秘密,并且您无法在执行期间访问秘密),这可能会很有用。另一种情况是当您有盲注时,可以将 ps x -w 的输出重定向到您有权访问的文件。
命令列表
使用运算符 ;、&、&& 或 || 组合多个命令的执行,并可选择由 ;、& 或 \n 之一终止。
此外,您可以使用管道用于相同的目的:
参考:
使用 tr 产生斜杠
重定向
在命令执行之前使用运算符 >、>|、>>、< 等重定向输入和输出。
使用运算符 <<< 提供附加换行符的单个字符串。
参考:
Shell 参数扩展
参数扩展的基本形式是 ${parameter};参数的值被替换:
更复杂的参数扩展形式允许您执行各种操作。例如,您可以提取子字符串并使用它们来创建 payload:
此外,匹配和替换在使用黑名单时可能很有用:
参考:
特殊 Shell 参数
有几个参数 Shell 会特殊处理。其中一些参数您可用于创建 payload:
参考:
Shell 变量
Bash 自动为许多变量分配默认值,如 HOME 或 PATH。其中一些变量可用于创建 payload。例如,您可以将 IFS 变量用作分隔符(这是可能的,因为 IFS 包含分隔字段的字符列表):
此外,您可以覆盖 IFS 并使用任何字符作为分隔符:
参考:
技巧
参考
最后更新于