Library / SDK
aploium/shootback avatar
aploium/shootback

shootback runs the tunnel connection backwards so the NAT does not matter

a reverse TCP tunnel let you access target behind NAT or firewall

976 stars232 forksPythonMIT

At a glance

What is it?
shootback is a reverse TCP tunnel written in Python. A master listens on two ports, one for the slaver and one for you, and the slaver dials out to the master from inside the network you want to reach, so the machine behind NAT or a firewall makes the outbound connection and you connect to the master instead. The two halves share nothing but the standard library, and the whole thing runs over any protocol that uses TCP.
Who is it for?
shootback suits an administrator who needs to reach a machine that has no inbound route, a CTF organiser who wants an outside competitor on the same network as the players, or anyone who wants a tunnel with no dependencies to install on the far end, since the slaver is a single file that needs only the Python standard library.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The direction of the connection is the whole trick

shootback is a reverse TCP tunnel that lets you reach a target behind NAT or a firewall, and the reason it works is that the connection is initiated from the inside. A normal tunnel or port forward needs the machine behind the router to accept an inbound connection, which is exactly what a NAT and a firewall prevent. shootback splits the relay into two halves. The master runs on a machine you can reach, it listens on one port for the slaver to call home and on another for you to connect, and the slaver runs on the machine you actually want to reach and dials out to the master. The master then pairs a client connection with a slaver connection and shuttles bytes between them. The project describes the master as requiring Python 3.4 or later and the slaver as Python 2.7 or 3.4 and later, both operating system independent, with no external dependencies beyond the standard library, and the slaver can be built into a single file.

Two ports on the master, one target on the slaver

The interface is small enough to read in a minute, and the two flags on the master are the whole configuration. The `-m` flag is the address the master listens on for incoming slaver connections, and the `-c` flag is the address it listens on for the clients who want to reach the target. The slaver takes the same `-m` flag, pointing at the master's slaver port, and adds a `-t` flag that names the target address the master should forward to, for example a hostname and port. The pairing is done by the master, which holds the client's connection open until a slaver arrives, and then wires the two together. The documentation notes that any service using TCP can be tunneled this way, listing HTTP, FTP, a proxy, SSH and VNC, which is a fair description of the constraint, since the relay is a byte pipe with no protocol knowledge. It also notes the limit of that design, that shootback itself only does the transmission job and does not handle encryption or proxying.

Three commands and a curl

The getting started section gives a working demonstration, and it is the fastest way to understand the topology. The master listens on port 10000 for slavers and on 127.0.0.1 port 10080 for the client:

bash
# master listen :10000 for slaver, :10080 for you
python3 master.py -m 0.0.0.0:10000 -c 127.0.0.1:10080

# slaver connect to master, and use example.com as tunnel target
# ps: you can use python2 in slaver, not only py3
python3 slaver.py -m 127.0.0.1:10000 -t example.com:80

# doing request to master
curl -v -H "host: example.com" 127.0.0.1:10080

The Host header in the curl call is the giveaway that this is a generic byte relay rather than an HTTP aware proxy, since the slaver named example.com as its target and the client has to say which host it wants in the request itself. The first step of the setup is cloning the repository, and the optional third step is building the single file slaver with `python3 build_singlefile_slaver.py`, which exists so that the slaver can be dropped onto a machine that has Python and nothing else.

The SSL option covers the hop that matters, and only that hop

The second example in the documentation shows a realistic case with encryption, and the diagram in the comments is the shape of it. The master listens for slavers on one port and for clients on another, the slaver connects with the `--ssl` option, and the client connects with a plain SSH client to the master's second port, so an SSH session ends up travelling over the tunnel. The comment is careful about what the flag means, the `--ssl` option is for the encryption between the slaver and the master, and it is not for SSH. That distinction matters, because the leg from the client to the master is not covered by the option, so on a machine that is not on a trusted network the client leg still needs its own protection, which in the example is SSH itself. The tips section also makes the point that shootback does not handle proxying, and suggests pointing the slaver at a third party proxy service, a shadowsocks server for example, so that the proxy protocol is handled by the proxy and the tunnel only carries bytes.

Running it as a daemon, and the single file trick

Two operational notes are worth repeating because they are the difference between a demo and a deployment. The first is backgrounding the slaver, and the documentation gives a nohup one liner with a `-q` flag for quiet operation, and also shows the screen route with the usual detach and reattach incantation. The second is that the slaver can be a single file. The repository is tiny, with `master.py`, `slaver.py`, a shared `common_func.py` and the build script that bundles the slaver into one file, and the slaver depends on nothing outside the standard library. That is why the target machine needs nothing installed: a Python interpreter and one file, which is the situation on a locked down corporate machine or a box you do not want to touch with a package manager. The master has the same property, since it is described as needing only Python 3.4 and later with no external dependencies.

Windows has a hard ceiling at 512 connections

The warning section is specific and correct in a way that most projects would not bother with. On Windows, because of a limit in CPython's `select.select()`, shootback cannot handle more than 512 concurrent connections, and beyond that you get a `ValueError: too many file descriptors in select()`. The suggestion is to use a Python distribution whose limit is higher, the Anaconda build being recommended with a documented limit of 2048. The other operational point in the same section is that the tool expects a master port reachable from the internet, since the slaver connects outward to it, and a master bound to a private interface can only be used from inside that network.

The performance numbers, and the question the docs leave open

The performance section reports measurements from a laptop with an Intel i7-4710MQ running Windows 10 on 64 bit, namely 1.6 Gbits per second of loopback transfer measured with iperf at about five percent CPU occupation, and 800 ApacheBench threads handled with less than one percent CPU and eight megabytes of memory. The headline claim in the README is consistent with that, under one percent CPU and eight megabytes of memory under 800 concurrency. Two observations for an engineer reading this. The first is that these are the author's own numbers on their own hardware, and the loopback figure in particular measures the tunnel against itself rather than against a real network. The second is that the documentation describes no authentication anywhere, and the setup instructions bind the master to `0.0.0.0`, so a master reachable from the internet will accept a slaver connection from anyone who finds the port and will relay for anyone who connects to the client port. The project is MIT licensed, has no published releases, and its last push was on 2026-04-03, so treat it as a small, well documented utility that expects you to control the network around it.

Editorial conclusion

shootback suits an administrator who needs to reach a machine that has no inbound route, a CTF organiser who wants an outside competitor on the same network as the players, or anyone who wants a tunnel with no dependencies to install on the far end, since the slaver is a single file that needs only the Python standard library. It is a poor fit if you need authentication on the tunnel, because the documentation describes no credential check between the master, the slaver and the client, and it is a poor fit on Windows at high concurrency, where the standard library's select limit caps it at 512 connections. Before you deploy it, check three things: whether the master port is reachable from the internet, since anything that can reach it can become a slaver, whether you need the SSL option enabled, since the tunnel is plaintext by default, and the state of the code, with the last push to the repository on 2026-04-03 and no tagged releases.

Frequently asked questions

What is shootback and how does it work?

It is a reverse TCP tunnel written in Python. The master listens on one port for the slaver and another for the client, the slaver dials out to the master from behind the NAT, and the master relays bytes between the client and the slaver, so any TCP service can be reached through it.

How do I set up shootback?

Clone the repository, then run `python3 master.py -m 0.0.0.0:10000 -c 127.0.0.1:10080` on the machine you can reach, `python3 slaver.py -m 127.0.0.1:10000 -t example.com:80` on the machine behind NAT, and connect to the master's client port. The slaver can be built into a single file with `python3 build_singlefile_slaver.py`.

Does shootback encrypt the traffic?

Only between the slaver and the master, and only with the `--ssl` option, which the documentation is careful to say is not for SSH. The client to master leg is not covered by that option, so it needs its own protection such as SSH. The tool itself does not handle encryption or proxying.

What is the concurrency limit of shootback on Windows?

512 connections, because of the limit in CPython's select.select(), and beyond that you get a ValueError about too many file descriptors in select(). The documentation recommends a Python distribution with a higher limit, the Anaconda build with its limit of 2048.

Does shootback need any dependencies?

No. The master needs Python 3.4 or later and the slaver Python 2.7 or 3.4 or later, and both use only the standard library. The whole repository is a handful of files, including a script that bundles the slaver into a single file for machines where you do not want to install anything.

Official sources

  1. aploium/shootback on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aploium-shootback.svg)](https://hysenlabs.com/projects/aploium-shootback)

Was this useful?