---
description: >-
  Hidden in the shadows, a coven of witches communicates through arcane tokens,
  their messages cloaked in layers of dark enchantments....
---

# WayWitch

## Looking at the code

The code is uses `NodeJs` framework which has this kind of file system:

```
├── build-docker.sh
├── config
│   └── supervisord.conf
├── Dockerfile
├── entrypoint.sh
├── flag.txt
└── src
    ├── database.js
    ├── index.js
    ├── package.json
    ├── routes
    │   └── index.js
    ├── static
    │   ├── css
    │   │   ├── bootstrap.min.css
    │   │   └── main.css
    │   ├── images
    │   │   └── logo.png
    │   └── js
    │       └── jose.min.js
    ├── util.js
    └── views
        └── index.html


```

**`util.js`**

* Contains utility functions shared across the application.
* Example tasks:
  * File system operations.
  * Generating or validating tokens.
  * Parsing data or configurations

#### `Src/`

The folder that contains the core logic and handling of the web server

&#x20;**`Database.js`**

Implements the database connection and sets up the tables according to the defined schema

We can see there's some kind of ticketing system going on which maybe used to authenticate the users. We also see that these tickets are made of `id` , `name` , `username`, `content`:

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FOadtYBBiua8xddYf5EyF%2Fimage.png?alt=media&#x26;token=b0b10f64-6485-4088-a862-d3545e57494c" alt=""><figcaption><p>Look how the admin ticket contains the flag</p></figcaption></figure>

Also the description said to craft the ticket

**`Index.js`**

* The application’s main entry point.
* Sets up:
  * **Express server**.
  * Middleware (e.g., for serving static files or handling requests).
  * Routes (from `routes/index.js`).
* Also there's **`package.json`** file that defines what scripts to run

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FFX5LGkf5QFyPlOkdXOEa%2Fimage.png?alt=media&#x26;token=68ce597e-6d72-4990-a2fa-b9789c5907fc" alt=""><figcaption></figcaption></figure>

**`Routes/`**&#x20;

* Contains route definitions (`index.js`).
* Responsible for:
  * Handling HTTP requests.
  * Sending responses (e.g., rendering views or returning JSON data).

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FH0zIuZwy3yYt2I5i5s1P%2Fimage.png?alt=media&#x26;token=76952e39-5fbe-4859-a127-77518f515ac2" alt=""><figcaption></figcaption></figure>

The router is defined with `casesensitive:true` meaning they require exact word for the route. Now looking at the routes itself:

***

**1. `GET /tickets`**

* **Purpose:** Fetches all tickets, restricted to admin users.
* **Workflow:**
  1. **Checks for Session Token:**
     * Retrieves the `session_token` from cookies.
     * If missing, returns a `401 Unauthorized` status.
  2. **Validates the Token:**
     * Decodes the `session_token` using `getUsernameFromToken`.
     * If invalid, returns a `400 Bad Request` with the error message.
  3. **Checks Admin Privileges:**
     * If the username is not `"admin"`, returns `403 Forbidden`.
  4. **Fetches Tickets:**
     * Calls `db.get_tickets()` to retrieve all tickets.
     * If successful, returns a `200 OK` with the tickets as a JSON object.
     * On failure, returns `500 Internal Server Error`.

***

**2. `POST /submit-ticket`**

* **Purpose:** Allows authenticated users to submit a new ticket.
* **Workflow:**
  1. **Checks for Session Token:**
     * Retrieves `session_token` from cookies.
     * If missing, returns `401 Unauthorized`.
  2. **Validates the Token:**
     * Decodes the `session_token` using `getUsernameFromToken`.
     * If invalid, returns `400 Bad Request` with the error message.
  3. **Validates Request Body:**
     * Extracts `name` and `description` from the request body.
     * If either is missing, returns `400 Bad Request`.
  4. **Adds a Ticket:**
     * Calls `db.add_ticket(name, username, description)` to insert the ticket into the database.
     * If successful, returns `200 OK` with a success message.
     * On failure, returns `500 Internal Server Error`.



## Browsing the application

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FcJ5UiwUV2INAqnT1mNHO%2Fimage.png?alt=media&#x26;token=167502b5-0c3b-4ed6-90b7-fde09f95549d" alt=""><figcaption><p>shall we use the data we got from database file?</p></figcaption></figure>

So we looked at the code , now we know how app works , let's test the theory:

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FIy1WTmQ6heiNfDk0WIl8%2Fimage.png?alt=media&#x26;token=a569656c-4eb8-45c5-86ce-cc69ccc9d300" alt=""><figcaption><p>JSon huh</p></figcaption></figure>

So we control the name and description from client side and also:

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FwPQdN4tuGioRjiS5SkNu%2Fimage.png?alt=media&#x26;token=48bddd9f-1537-40af-986c-3b1574f56cab" alt=""><figcaption></figcaption></figure>

So we craft a token to get the flag from the admin description as seen above in the code. We need the jwt secret for  that -> which is in the `utils.js` file.

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FTcRnrsQkQGn0t8dxvHbZ%2Fimage.png?alt=media&#x26;token=f4a808f0-3d91-4ad2-8b19-fd2dbcd78322" alt=""><figcaption><p>Not So Secret huh?</p></figcaption></figure>

Then we craft the token:

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2Fgrg44g0JC3RALW9z8uir%2Fimage.png?alt=media&#x26;token=4fe3fe2c-3959-46aa-bb5e-3bd6ddc74448" alt=""><figcaption></figcaption></figure>

and get the cookie:

<figure><img src="https://1258745909-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPRj67lRKmIcGcfIbPm4a%2Fuploads%2FLPvcnZZF8Qly3SE0kKol%2Fimage.png?alt=media&#x26;token=a979e39f-8658-4a60-b8e0-3470ea2901a9" alt=""><figcaption></figcaption></figure>

```
HTB{k33p_th3s3_jwt_s3cr3t_s4f3f_br0}
```

