BountyHunter HTB WALKTHROUGH

MEFIRE FILS ASSAN
System Weakness
Published in
7 min readFeb 3, 2024

--

In the following article, I will show you how to take over the machine BountyHunter in Hack The Box. BountyHunter is a good machine to learn about the danger of XML external Entity and use of dangerous function by programmers. In this article, I present the method I follow to pwned this machine

RECONNAISSANCE

We will start by a scan to know about open ports, running services. Nmap is an intuitive tool that help us for this.

nmap -sC -sV -Pn TARGET_IP

If the previous command is confusing, there is an explanation for each flag used

-sC use a set of default scripts for scanning
-sV to have versions of services that are running
-Pn ping probe

There is output after it the command.

Host is up (0.071s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 d44cf5799a79a3b0f1662552c9531fe1 (RSA)
| 256 a21e67618d2f7a37a7ba3b5108e889a6 (ECDSA)
|_ 256 a57516d96958504a14117a42c1b62344 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Bounty Hunters
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The port 22 is running the ssh service and port 80 http service mean there is a site web at the address : http://TARGET_ip. When you browse to the URL, you will see a site look like this. Go to the PORTAL tab

And follow the redirected link

A simple form. Open a developer tools, depending on your browser the shortcut can change (but is usually F12 or CTRL+MAJ+I).

The following code source will appear to you :

So, when the form is submitted, the function bountySubmit() is call. Just click on the link to open the bountylog.js

As you seen, there is two function :

  • returnSecret(data) : a simple JavaScript function use to transfer data received in parameter with a POST request
  • bountySubmit() : the function creates XML object by retrieving the values enter by user and pass it as parameter to the previous function, but earlier convert data to base64 with btoa() function.

So our entry point will be XML by the XML Injection attack.

XML External Entity(XXE)

As we have seen previously, there is a request send after submitting form; then we will use Burpsuite to intercept the request

data here is the XML object encode in base64, but if you carefully take care, you will see that it have also a URL encoding. XML object is first encode with base64 an after encode with URL encoding.

The follow screenshot of decoding by BurpSuite is explicit

So based on our information, we will create an XML payload encode it with base64 and URL encoding.

The first payload is a test payload

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [<!ENTITY example "3"> ]>
<bugreport>
<title>&example;</title>
<cwe>10</cwe>
<cvss>10</cvss>
<reward>10</reward>
</bugreport>

After encode(base64 and URL) the payload, we can tamper with request and as you seen in response the example entity we declare with value “3” is set as title, application is vulnerable to XXE.

Now we know that the app is vulnerable, the next step is to exploit the vulnerability in order to have access.

My first try was to try to read the /etc/passwd and the /etc/shadow file and I can crack to have password of all the users. But it not works, however it helps me to have the username of the victim machine. There is the payload you can use to read local file trough XXE

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [!ENTITY example SYSTEM "file:///etc/passwd">]>
<bugreport>
<title>&example;</title>
<cwe>10</cwe>
<cvss>10</cvss>
<reward>10</reward>
</bugreport>

After encoded and send the payload, there is result in the following screenshot.

Note the development username that seems to be the account use by developers on the machine.

Now we have a username, let’s try to have a password. In my research, I discovered that XXE can be used to read PHP file. Usually, there are leaked passwords in PHP script so we will read and analyze each PHP file of the website. You can enumerate the webapp with a tool like dirbuster.

And the one that caught my attention is the db.php; then we will use this payload to read it

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=db.php">]>
<bugreport>
<title>&example;</title>
<cwe>10</cwe>
<cvss>10</cvss>
<reward>10</reward>
</bugreport>

Encode the payload into base64 and URL encoding; send into request

And as response there is a PHP script in base64 encoding, just decode it.

You can see a password in clear text. We just hope it is the password of development user, and we will try to connect remotely via ssh (remind port 22 is open)

It works. Now we are in, we can retrieve the flag.

development user is our entry point, let’s try privesc to be root.

PRIVILEGE ESCALATION

Privilege escalation can be done via may different methods, but usually is to take profit of misconfigurations of grants for a simple user.
Look at the content of the contract.txt inside the development user home directory.

John talk about a file that can be with all privileges without need to be root. It is the vulnerability we will exploit. To find that file, we use the following command

sudo -l

That list what our user can run as sudo without password

As you seen, the ticketValidator.py can be run as sudo.

Before exploit it, we have to understand what the python script done.

You can read it by using nano or vi in the command line. The code is long but don’t worry it is easy to understand.

The first function is load_file()

We learn from it that an extension for a ticket file is .md

The second function is evaluate(ticketFile)

By read, it we know how the structure of ticket file :

  • Start by # Skytrain Inc
  • The second line ## ticket to any destination you want
  • The third line is __Ticket Code:__
  • The fourth line is the ticket code that start by **
  • After the ** we have the ticket code in this format number1+number2
  • number1 is a number such that if you subtract 4 from it, you get a number divisible by 7. For example : 109,123,130 …
  • number2 is any number while number1+number2 is greater than 100

For example, this is a valid ticket

# Skytrain Inc
## Ticket to Hack City
__Ticket Code:__
**123+45

Execute the ticket validator with this example :

We have understood how the script work, but how to exploit it ?

Look well at this instruction in the evaluate() function

They use eval() function to directly do addition of two parts of ticket code, if you have some basis in python, you know that if we inserted a python script inside the eval() function the script will be executed.

We will use this vulnerability, to open a shell as administrator, with this ticket file

# Skytrain Inc
## Ticket to Hack City
__Ticket Code:__
**123+45,__import__('pty').spawn('/bin/sh')

What will happen ?

  • The python script is executed as sudo
  • The evaluate() function use eval() with this string as parameter “123+45,__import__(‘pty’).spawn(‘/bin/sh’)
  • eval() function will execute “123+45” as python code and “__import__(‘pty’).spawn(‘/bin/sh’)” because we use comma to have two instructions in same line

As you seen in the following screenshot, we are connected as root

And we can capture the flag

Hope you enjoy reading this article, if it is case clap for me; else tell me why in comment.

--

--