Hack The Box: DevOops
DevOops: Retired 13 October 2018
If you are interested in learning more about penetration testing, Hack the Box is a great way to get your feet wet in a legal and well built environment. Head over to hackthebox.eu to get started.
Been a while since I had time to do a HTB machine but it felt good to get back in the saddle with this one.
Enumeration
As with all hacking, we start off with a quick nmap
scan. In this case, just scanning the top 100 ports was enough to get me started: nmap --top-ports 100 10.10.10.91 -sV
Seeing that port 5000 was running something on HTTP, I browsed directly to the page to see what was there.
This page appears to be some sort of feed aggregater but is under construction which usually means we will be able to either find some bugs or some poorly secured debug functionality. The first step though is to do some directory brute forcing to determine if there is any low hanging fruit or additional interesting directories.
I opted to use GoBuster this time around instead of WFUZZ just because I wanted to try something new. I had also heard that GoBuster is much faster and flexible. The installation process on the GoBuster GitHub page is a little involved, luckily the tool is already part of the Kali repos so all I had to do was an apt-get install gobuster
and I was ready to go.
I used a fairly simple GoBuster command for my initial run including .py
extensions because of the message on the initial landing page that referenced a Python file. I still used my trusty WFUZZ medium.txt
wordlist as my initial guesses.
gobuster -u http://10.10.10.91:5000 -t 50 -w /usr/share/wordlists/wfuzz/medium.txt -x .py
On the first run I was able to find the upload
directory, which sounded like a really juicy target.
Initial Access - XXE to LFI
This page appears to take an XML file as input which immediately set off bells in my head that this is likely an XXE vulnerability. After some trial and error (this error specifically: SAXParseException: xxe-test.xml:2:0: junk after document element
), I was finally able to figure out the proper format for the XML file to upload without getting an Internal Server Error
<Version>
<Author>TestAuth</Author>
<Subject>TestSub</Subject>
<Content>TestContent</Content>
</Version>
At one point I got an error that gave me a Python traceback that revealed the directory that I was running in, /home/roosa/deploy/src
.
File "/home/roosa/deploy/src/feed.py", line 81, in upload_file
#flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(Config.UPLOAD_FOLDER, filename))
return process_xml(filename)
# return redirect(url_for('uploaded_file',filename=filename))e
return template('upload.html')
@app.route('/uploads/<filename>')
def uploaded_file(filename):
Playing around with the XML file and following the guide here, it looks like there is an XXE vulnerability that allows for internal entities, which eventually led me to a local file inclusion with this file:
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<Version>
<Author>&xxe;</Author>
<Subject>TestSub</Subject>
<Content>TestContent</Content>
</Version>
Knowing that I had an ability to retrieve local files, I started poking around the file system looking for interesting files. I was able to retrieve feed.py
but that file did not provide much additional info other than details on how the application works. Finally, I decided to try to user files and attempted to retrieve the user's SSH key if it existed. Modifying my XML file to retrieve /home/roosa/.ssh/id_rsa
was successful and pulled back an SSH key. The formatting was off (newlines replaced with just spaces) so correcting for that with sed -i 's/ /\n/g' id_rsa_roosa
left me with a properly formatted SSH private key. A quick chmod 600 id_rsa_roosa
to set the proper permissions and I was able to SSH to the host as roosa
:
ssh -i id_rsa_roosa roosa@10.10.10.91
Privilege Escalation
Doing initial enumeration and just poking around the directories, I found two interesting files that contained what looked like SSH keys.
~/work/blogfeed/resources/integration/authcredentials.key
~/deploy/resources/integration/authcredentials.key
Both files were the same. I saved the key off and tried to SSH to the host as root
with no luck.
Further enumeration revealed that there was a git repository which I found because earlier I noticed the git
user in the /etc/passwd
file. Looking for the git directory using find . -name *git*
I found that the repo was in ~/work/blogfeed
Navigating to the repo and running git log
revealed some interesting commits.
Seeing that there was an error with the key commit, I decided to grab the initial key that was commited and see if that would work for me.
git show d387abf63e05c9628a59195cec9311751bdb283f:resources/integration/authcredentials.key
That revealed a different version of the key. Again attempting to use that key to SSH as root
was successful and this box was owned!
Lessons Learned
- Git repo histories are ALWAYS worth investigating
- GoBuster is a fast alternative for bruteforcing directories and files.
- XXE does not have to be complicated and reference external entities. Sometimes internal entities and file includes are sufficient.