At its core, shellsquid is a database driven HTTP(S) and DNS reverse proxy. The intended purpose is to enable teams to share a single Internet facing interface and port when handling multiple reverse payloads. The original version of shellsquid used customized payloads to determine routing, and was overly complex. This version uses hostnames and is much more straight forward.
For HTTP(S), a common way of configuring payload routing is to register a single domain with a wildcard DNS record, and then use subdomains to route payloads.
For DNS payloads, a domain can be registered and a authoritative DNS server setup, using the shellsquid host IP. You can then use multiple subdomains to route to different internal handlers. dnscat2 was the payload used for testing, consult it's documentation for more information on configuring authoritative DNS.
Binary packages for every supported operating system are availble here.
This package does not provide a web client. The recommended client is shellsquid-ui.
None, shellsquid is written in Go and uses boltdb.
Configuration is done via a JSON file in config.json
. The following values are supported:
{
"proxy": {
"dns": {
"enabled": true,
"listener": ":53"
},
"ssl": {
"enabled": true,
"listener": ":443",
"key": "key.pem",
"cert": "cert.pem"
},
"http": {
"enabled": true,
"listener": ":80"
}
},
"admin": {
"listener": ":1337",
"key": "key.pem",
"cert": "cert.pem"
},
"jwt_key": "something secret",
"bolt_db_file": "squid.db"
}
You will need to generate a certificate and key files separately. Do whatever is best for your needs and environment. For example, a self signed certificate can be generated using the the following syntax and should be stored in the root of the project directory:
$ openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days XXX
Starting the server is as easy as running the compiled binary. If started for the first time, an initial user admin@localhost
will be created with a random password, this will be output to stdout.
$ ./shellsquid
You can now login to the admin interface, by default this is an HTTPS service on TCP 1337.
Records are used to tell shellsquid how to route incoming traffic. On each request, shellsquid will lookup the FQDN provided in the database. If a record is found, the traffic will be routed to the configured handler.
If using the suggested web UI:
- Click "Add Record"
- Fields
- FQDN - This is the hostname that your payload will use. This can be a fully qualified domain name. Can also be a domain name (e.g."example.com", "foo.baz") if using dns as your handler protocol. For http(s) handlers, this may also be the IP of the incoming client. When in doubt, use a FQDN (e.g. "foo.example.com", "bar.foo.baz").
- Handler Host - This is the IP address where your handler is listening.
- Handler Port - This is the port number that your handler is listening on.
- Handler Protocol - Should be either http, https, or dns.
- Click "Submit"
This version of shellsquid does not require any special handlers! There are still some considerations to make when configuring your multi-handler. The reason for this is to control the payload_uri
that is generated by the handler, we need that to output the address of our proxy and not the actual handler. Configuration steps:
- set
LHOST
to the fqdn of your record. - set
LPORT
to the listening port of the proxy. For example, if it's an HTTPS payload and your proxy is configured to listen on 443, then set it to 443. - use the advanced options of
ReverseListenerBindPort
andReverseListenerBindAddress
to set the actual interface and port for the handler to use. - run like normal.
You can not set your ReverseListenerBindAddress
to localhost
or 127.0.0.1
because of a bug in Metasploit.
It is easier to think of shellsquid as a reverse HTTP proxy, such as nginx. For example, an HTTP request is sent to nginx based on a fqdn (e.g., foo.bar.com) along with the respective HTTP Host header. The nginx proxy then routes the request to the appropriate application content.
shellsquid is similar; the HTTP based reverse shell fires and connects back to shellsquid with the LHOST
payload set to a FQDN. It is important to note that shellsquid can route numerous shells based on subdomain. So say we have the following list:
- foo.bar.com
- baz.bar.com
- fud.bar.com
All of the these FQDNs would route based on their subdomain components. shellsquid would then parse the HTTP Host header and route the connection to the actual MSF multi-handler designated by the "show advanced" syntax within MetaSploit. The following images provide a sample configuration:
Setting LHOST
and LPORT
to use the FQDN of your record and port of the proxy
Setting the Backend (i.e., shoveled/proxied) listener to the actual LHOST
and LPORT
established in shellsquid
Authentication and authorization is performed using JSON Web Tokens ("JWT"). The administrative portion of the application is configured by default to listen on a separate port and interface than the HTTP and HTTPS proxy handler. Access to the administrative interface is done using a username and password. Currently, all users have the same permissions and can change the passwords of other users. This is fully intentional, everyone is an admin. There didn't seem like there was much to be gained by having a finegrained permissions model.
The server is written in Go and uses boltdb. Configuration is done in config.json
. This project uses godep for dependency management. To start the server:
# Install godep
$ go get github.com/tools/godep
# Run the server, all dependencies are managed and stored in the using godep in the Godeps directory
$ sudo -E godep go run main.go
Shellsquid is bring your own client. The recommended client is shellsquid-ui.