Parameters Injection

git

Abusing bare repositories

You can use bare repositories to deliver custom git hooks and execute arbitrary code. For instance, if the vulnerable code executes the following bash commands:

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

You can create a repo with the subproject folder, which is a bare repository with a payload in the post checkout hook:

$ 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
$ # commit and push

References:

git-clone

--config

Set a configuration variable in the newly-created repository; this takes effect immediately after the repository is initialized, but before the remote history is fetched or any files checked out.

core.hooksPath

core.hooksPath sets different path to hooks. You can create the post checkout hook within a repository, set the path to hooks with the hooksPath, and execute arbitrary code.

To execute the payload, run the git-clone:

References:

http.proxy and http.<URL>.proxy

http.proxy or http.<URL>.proxy override the HTTP proxy. You can use this to get SSRF:

Pay attention to other http.* configs and remote.<name>.proxy, they can help to increase the impact.

References:

ext URLs

git-clone allows shell commands to be specified in ext URLs for remote repositories. For instance, the next example will execute the whoami command to try to connect to a remote repository:

References:

<directory>

git-clone allows specifying a new directory to clone into. Cloning into an existing directory is only allowed if the directory is empty. You can use this to write a repo outside a default folder.

-u/--upload-pack

upload-pack specifies a non-default path for the command run on the other end when the repository to clone from is accessed via ssh. You can execute arbitrary code like this:

References:

git-grep

--no-index

no-index tells the git-grep to search files in the current directory that is not managed by Git. In other words, if a working directory is different from a repository one no-index allows you to get access to files in the working directiory.

References:

git-log

--output

output definea a specific file to output instead of stdout. You can use this to rewrite arbitrary files.

References:

git-push

--receive-pack/--exec

receive-pack or exec specifies a path to the git-receive-pack program on the remote end. You can execute arbitrary code like this:

npm scripts

The scripts property of the package.json file supports a number of built-in scripts and their preset life cycle events as well as arbitrary scripts. These all can be executed using npm run-script or npm run for short.

Scripts from dependencies can be run with npm explore <pkg> -- npm run <stage>

Pre and post commands with matching names will be run for those as well (e.g. premyscript, myscript, postmyscript). To create pre or post scripts for any scripts defined in the scripts section of the package.json, simply create another script with a matching name and add pre or post to the beginning of them.

In the following example npm run compress would execute these scripts as described.

There are some special life cycle scripts that happen only in certain situations. These scripts happen in addition to the pre<event>, post<event>, and <event> scripts.

  • prepare (since npm@4.0.0)

    • Runs any time before the package is packed, i.e. during npm publish and npm pack

    • Runs BEFORE the package is packed

    • Runs BEFORE the package is published

    • Runs on local npm install without any arguments

    • Run AFTER prepublish, but BEFORE prepublishOnly

    • NOTE: If a package being installed through git contains a prepare script, its dependencies and devDependencies will be installed, and the prepare script will be run, before the package is packaged and installed

    • As of npm@7 these scripts run in the background. To see the output, run with: --foreground-scripts

  • prepublish (DEPRECATED)

    • Does not run during npm publish, but does run during npm ci and npm install

  • prepublishOnly

    • Runs BEFORE the package is prepared and packed, ONLY on npm publish

  • prepack

    • Runs BEFORE a tarball is packed (on npm pack, npm publish, and when installing a git dependencies)

    • NOTE: npm run pack is NOT the same as npm pack. npm run pack is an arbitrary user defined script name, where as, npm pack is a CLI defined command

  • postpack

    • Runs AFTER the tarball has been generated but before it is moved to its final destination (if at all, publish does not save the tarball locally)

npm cache add

npm cache add runs the following life cycle scripts:

  • prepare

npm ci

npm ci runs the following life cycle scripts:

  • preinstall

  • install

  • postinstall

  • prepublish

  • preprepare

  • prepare

  • postprepare

These all run after the actual installation of modules into node_modules, in order, with no internal actions happening in between.

npm diff

npm diff runs the following life cycle scripts:

  • prepare

npm install

npm install runs the following life cycle scripts (also run when you run npm install -g <pkg-name>):

  • preinstall

  • install

  • postinstall

  • prepublish

  • preprepare

  • prepare

  • postprepare

If there is a binding.gyp file in the root of a package and install or preinstall scripts were not defined, npm will default the install command to compile using node-gyp via node-gyp rebuild.

npm pack

npm pack runs the following life cycle scripts:

  • prepack

  • prepare

  • postpack

npm publish

npm publish runs the following life cycle scripts:

  • prepublishOnly

  • prepack

  • prepare

  • postpack

  • publish

  • postpublish

prepare will not run during --dry-run

npm rebuild

npm rebuild runs the following life cycle scripts:

  • preinstall

  • install

  • postinstall

  • prepare

prepare is only run if the current directory is a symlink (e.g. with linked packages)

npm restart

npm restart runs a restart script if it was defined, otherwise stop and start are both run if present, including their pre and post iterations):

  • prerestart

  • restart

  • postrestart

npm start

npm start runs the following life cycle scripts:

  • prestart

  • start

  • poststart

If there is a server.js file in the root of your package, then npm will default the start command to node server.js. prestart and poststart will still run in this case.

npm stop

npm stop runs the following life cycle scripts:

  • prestop

  • stop

  • poststop

npm test

npm test runs the following life cycle scripts:

  • pretest

  • test

  • posttest

pip

pip install

Extending the setuptools modules allows you to hook almost any pip command. For instance, you can use the install class within setup.py file to execute an arbitrary code during pip install running.

When pip install is run the PostInstallCommand.run method will be invoked.

References:

gem

gem build

gemspec file is a ruby file that defines what is in the gem, who made it, and the version of the gem. Since it is a ruby file you can write arbitrary code that will be executed when running gem build.

When gem build is run the arbitrary ruby code will be executed.

References:

gem install

Extensions

gemspec allows you to define extensions to build when installing a gem. Many gems use extensions to wrap libraries that are written in C with a ruby wrapper. gem uses the extconf.rb to build an extension during installation. Since it is a ruby file you can write arbitrary code that will be executed when running gem install.

When gem install is run the arbitrary ruby code will be executed.

References:

bundler

bundler install

bundler install uses gem under the hood, therefore, it is possible to reuse gem's features for giving a profit.

Gemfile

Gemfile describes the gem dependencies required to execute associated Ruby code. Since it is a ruby file you can write arbitrary code that will be executed when running bundle install.

When bundle install is run the arbitrary ruby code will be executed.

gem dependency

Since bundler uses gem install to install the specified dependencies in Gemfile you can use extensions to embed an arbitrary code.

When bundle install is run the arbitrary ruby code will be executed.

References:

git dependency

One of the sources of gems for bundler are git repositories with a gem's source code. Since a git repositories contains a source code bundler builds it before installing. Therefore, you can write an arbitrary code that will be executed when running bundle install.

You can execute an arbitrary code using both gemspec file and native extensions

Create a repository on github.com with the following hola.gemspec file:

Add the repository to Gemfile as a git dependency.

When bundle install is run the arbitrary ruby code will be executed.

References:

path dependency

You can specify that a gem is located in a particular location on the file system. Relative paths are resolved relative to the directory containing the Gemfile. Since a git repositories contains a source code bundler builds it before installing. Therefore, you can write an arbitrary code that will be executed when running bundle install.

You can specify that a gem is located in a particular location on the file system. Relative paths are resolved relative to the directory containing the Gemfile.

Similar to the semantics of the :git option, the :path option requires that the directory in question either contains a .gemspec for the gem, or that you specify an explicit version that bundler should use.

Unlike :git, bundler does not compile native extensions for gems specified as paths

Therefore, you can gain code execution using the .gemspec file with an arbitrary code or built gem with native extension.

When bundle install is run the arbitrary ruby code will be executed.

References:

terraform

terraform-plan

Terraform relies on plugins called "providers" to interact with remote systems. Terraform configurations must declare which providers they require, so that Terraform can install and use them.

You can write a custom provider, publish it to the Terraform Registry and add the provider to the Terraform code.

The provider will be pulled in during terraform init and when terraform plan is run the arbitrary ruby code will be executed.

Additionally, Terraform offers the external provider which provides a way to interface between Terraform and external programs. Therefore, you to use the external data source to run arbitrary code. The following example from docs executes a python script during terraform plan.

References:

Last updated