命令注入

环境变量

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 目录:

LD_PRELOAD

LD_PRELOAD 是一个可选的环境变量,包含一个或多个共享库或共享对象的路径,加载程序将在任何其他共享库(包括 C 运行时库 libc.so)之前加载它们。

在 Linux C 中,函数可以在函数定义中使用属性进行声明。这是通过将所需的属性添加到函数定义中来完成的。有两个感兴趣的属性,constructor 和 destructor。具有 constructor 属性的函数将在程序执行 main() 之前运行。对于共享对象,这将发生在加载时。使用 destructor 属性声明的函数应该在 main() 返回或调用 exit() 时运行一次。

LD_PRELOAD 可用于覆盖标准的 libc 调用,查看 为了乐趣和利润滥用 LD_PRELOAD

换句话说,您可以编译一个共享库在加载时和/或返回之前调用:

  1. 重用以下代码来编译共享库:

    // C code for LD_PRELOAD injection example // This is a generic LD_PRELOAD example that can be used for testing

  2. 使用以下命令编译共享库:

  3. 利用:

参考:

PERL5OPT

PERL5OPT 指定命令行选项,但仅限于接受选项 CDIMTUWdmtw

PERL5OPT=-M 可用于加载 Perl 模块并在模块名称后添加额外代码:

参考:

PERL5DB

PERL5DB 指定用于加载调试器代码的命令。PERL5DB 仅在 Perl 以裸 -d 开关启动时使用。

参考:

PERLLIB 和 PERL5LIB

PERLLIBPERL5LIB 设置在标准库中查找 Perl 库文件的目录列表。如果定义了 PERL5LIB,则不使用 PERLLIB

如果有办法将恶意的 Perl 模块写入文件系统,PERLLIBPERL5LIB 可用于执行任意命令:

参考:

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 脚本可用,例如 perldocperlthanks。这些脚本也会错误并以无效参数退出,但这种情况下的错误发生在 PERL5OPT 环境变量处理之后。这意味着可以利用 Perl 环境变量来执行命令。

参考:

NODE_OPTIONS

NODE_OPTIONS 指定以空格分隔的命令行选项列表。

如果有办法将恶意的 Node.js 模块写入文件系统,NODE_OPTIONS 可用于执行任意命令:

如果没有办法将模块写入文件系统,您可以使用 proc 文件系统,特别是 /proc/self/environ,来传递 payload。

但是,有两个约束条件:

  1. 使用 /proc/self/environ 只有在内容在语法上有效 JavaScript 时才可能。为此,您需要能够创建环境变量并使其首先出现在 /proc/self/environ 的内容中。

  2. 由于第一个环境变量的值以单行注释 // 结尾,其他环境变量中的任何换行符都将导致语法错误。使用多行注释 /* 不会解决问题,因为它们必须关闭才能在语法上有效。在这种情况下,需要覆盖包含换行符的变量的值。

参考:

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 环境中执行命令并用命令的标准输出替换命令替换来执行扩展。

参考:

字符编码

有几种处理编码字符串的方法:

  1. $'string' 单词:

    形式为 $'string' 的单词被特殊处理。该单词扩展为字符串,反斜杠转义字符按照 ANSI C 标准指定的方式替换。

  2. echo 命令:

    echo 提供 -e 选项来解释反斜杠转义。注意识别的序列取决于 echo 的版本,以及 -e 选项可能根本不存在。

  3. xxd 命令:

参考:

泄露命令行参数

如果您在 cli 命令中有参数注入,该命令已传递敏感参数,如令牌或密码,您可以尝试使用 ps x -w 泄露传递的秘密。

如果 cli 日志隐藏敏感设置或敏感数据未存储在环境中,这可能会很有用。

如果 cli 日志隐藏敏感数据或敏感数据未存储在环境中(例如,GitHub Actions 提供变量插值 ${{...}} 用于注入秘密,并且您无法在执行期间访问秘密),这可能会很有用。另一种情况是当您有盲注时,可以将 ps x -w 的输出重定向到您有权访问的文件。

命令列表

使用运算符 ;&&&|| 组合多个命令的执行,并可选择由 ;&\n 之一终止。

此外,您可以使用管道用于相同的目的:

参考:

使用 tr 产生斜杠

重定向

在命令执行之前使用运算符 >>|>>< 等重定向输入和输出。

使用运算符 <<< 提供附加换行符的单个字符串。

参考:

Shell 参数扩展

参数扩展的基本形式是 ${parameter};参数的值被替换:

更复杂的参数扩展形式允许您执行各种操作。例如,您可以提取子字符串并使用它们来创建 payload:

此外,匹配和替换在使用黑名单时可能很有用:

参考:

特殊 Shell 参数

有几个参数 Shell 会特殊处理。其中一些参数您可用于创建 payload:

参考:

Shell 变量

Bash 自动为许多变量分配默认值,如 HOMEPATH。其中一些变量可用于创建 payload。例如,您可以将 IFS 变量用作分隔符(这是可能的,因为 IFS 包含分隔字段的字符列表):

此外,您可以覆盖 IFS 并使用任何字符作为分隔符:

参考:

技巧

参考

最后更新于