# Forensics: Tales for the Brave

# **Introduction**

> In Eldoria, a once-innocent website called “Tales for the Brave” has become the focus of unsettling rumors. Some claim it may secretly trap unsuspecting visitors, leading them into a complex phishing scheme. Investigators report signs of encrypted communications and stealthy data collection beneath its friendly exterior. You must uncover the truth, and protect Eldoria from a growing threat.

**Type**: Forensics  
**Difficulty**: Hard  
**Authors**: [connar](https://connar.github.io/), [rasti](https://rasti37.github.io/)  
**Event**: [**Hack The Box Cyber Apocalypse 2025: Tales From Eldoria**](https://www.hackthebox.com/events/cyber-apocalypse-2025) ([**ctftime**](https://ctftime.org/event/2674/))

Official write-up:  
[https://github.com/hackthebox/cyber-apocalypse-2025/tree/main/forensics/Tales%20for%20the%20Brave](https://github.com/hackthebox/cyber-apocalypse-2025/tree/main/forensics/Tales%20for%20the%20Brave)

# Initial recon

%%[support-cta] 

Given: `IP:PORT`

After closer inspection, it appears to be the address to the website.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743255251905/634a103c-0f0e-4456-afd4-f5097b7bbb7e.png align="center")

The source code reveals two important imports:

```xml
<!DOCTYPE html>
<html lang="en">
<head>
  <!-- cut -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
</head>
<body>
  <!-- cut -->
  <script src="js/index.js"></script>
</body>
</html>
```

`index.js` contains some encrypted payload that is evaluated, possibly on the page load.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743255723873/1bff838c-fa19-4070-b97e-c4015e013b49.png align="center")

Crypto-JS appears to be a JavaScript library for cryptography operations. This one used here is an ancient and outdated.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743255980486/cee20653-393d-4eff-933f-4194701736d2.png align="center")

On browsing, the website presents itself as a newsletter subscription form.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743255116617/d559a9ce-049f-4a45-af89-29d914df57f5.png align="center")

# Analysis

Let’s unravel the suspicious code.

## Stage 01

The first stage contains two phases - building the strings array and evaluation of the encrypted code (stored in a binary format). Because of the variables names and as it appears to be an encryption method, we can infer this is AES encryption (ciphertext, encryption key and IV vector).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743256694682/fd11e6e7-de14-4fa4-a197-3b5c093c2767.png align="center")

After quick deobfuscation (array and `btoa(..)` evaluations, `eval` removal).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743256869869/1bf25a6e-1b90-4993-9ad0-71411d7cb461.png align="center")

After evaluating all of that and converting from hex to text, we can continue with a second stage.

## Stage 02

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743257120185/b3a10357-7c4b-4481-810e-6a5bae399032.png align="center")

This one contains several more strings dictionaries that are used to build the actual JavaScript code. After some doebfuscation, formatting and removal of unnecessary code, the remaining JavaScript can be described as a puzzle that can be solved by inputting a specific value in pre-`@` email value on the form and clicking in the checkboxes in a predetermined sequence. As a reward, the solver is redirected to the unknown URL that was placed as a message sent on Telegram. Fortunately, we don’t have to predict any of that and can focus on the Telegram method alone.

## Telegram Bot API

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743257638824/d6fe3215-1bb2-4ddf-a13c-bf46aac96f39.png align="center")

What this code does is calling the Telegram Bot API (`hhtps://api.telegram.org/*/forwardMessage`) to forward a one message (`message_id=5`) from the specific group chat (`channel_id`) to some other group (`idc`). This code contains all the necessary information to do such a call - apart from the target chat.

I don’t want to download any unnecessary software and create third-party accounts just for the CTF purposes, so I’ve tried to dig as much as possible without doing any of that. [API documentation](https://telegram-bot-sdk.readme.io/reference) gives a good idea of what can be done, so I’ve called a couple of endpoints to see what I can get.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743258644095/c0a6232e-1170-4e76-8006-893bccd8974b.png align="center")

The name suggests we are on the right track, `can_join_groups` flag is set so it confirms the `forwardMessage` scenario. Another response (`/getUpdates` endpoint) gets me puzzled.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743259156907/fe7af8aa-4076-446d-9875-059ff8a55da8.png align="center")

This appears to be a log of what is sent by the bot, or to that bot? But is it an artificial conversation to flavour the challenge? Are those other participants chatting together? Should I do the same? One of the threads got my special interest:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743259312245/8bdfee9f-e0a3-48f5-93b6-b2569e65e682.png align="center")

Well, I think I’ll never find if that’s a real chat between participants or just something coded to appear indefinitely during the event. Either way, I just don’t have any other option to try - requesting the bot to forward me a message should be a way to go.

# Exfiltrating the private chat

To do so, I found no other way than actually downloading the Telegram app (through the APK, barbaric and shady) and creating a private group. Then, when I had that set up, I’ve invited the OperationEldoriaBot, and now I need my group ID. Quick research (no, it can’t be found in HTML and network traffic) helped me find a way to get it. I’ve invited the “GetIDsBot” to the group and voilà.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743259801281/a677fdd7-4a12-48b9-a56e-cf063a0fd1c4.png align="center")

I’ve passed that ID in the `forwardMessage` call… but got the error:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743259915093/d31f0478-3dc2-42b1-94d6-8cc2b0ba1367.png align="center")

I have spent the next two hours or so on finding a solution to that. I’ve searched many StackOverflow posts, GitHub and Redid discussions and two things that were most frequently mentioned: is the bot added as an administrator and is that a public or a private group. I did many combinations of those, at the end finding that when I once changed the group from private to public it gets promoted to “supergroup” permanently and is assigned a different ID - but that didn’t help.

Then I literally went to the bathroom, ate something (not in the bathroom) and came back to the challenge to find out that the last API call I’ve tried now returns a success message. I guess some cache somewhere had to expire.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743260359639/3b65784a-0e39-4e9b-a923-856cb7c358f5.png align="center")

Now with a new tool at my disposal, I can forward message by message all chat messages from that Telegram group (I have skipped a message with ID=5 because it only contains an expired group invitation).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743260488362/569394ae-3476-41d1-9a34-4973f06f8e58.png align="center")

I’m downloading the archive and unzip it using the provided password.

# Brave.exe

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743263043840/93e149ea-7e5b-4365-8dcc-5fbd4ca763aa.png align="center")

File responds as Portable Executable (PE) for Windows. When I try to open them with any of my decompilers, they do not report anything useful. Then I’ve checked the file with DIE ([Detect-It-Easy](https://github.com/horsicq/Detect-It-Easy)).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743263960704/8d1413b1-45dc-419a-8908-50f7dc2a6d79.png align="center")

Report from [VirusTotal](https://www.virustotal.com/gui/file/0ed2b6c373446e31c3ab8e424be0783b7dc397b67db6dbe29173271321c3f426/details) indicates that’s a stealer malware. Because I’m unable to decompile it in each known to me tool, there is another way. To run it in an isolated environment and observe.

## Malware execution analysis

For this, I’ll be using [FlareVM](https://github.com/mandiant/flare-vm). It’s a streamlined Windows Malware Analysis Suite over Windows.

After copying the `Brave.exe` I’m opening the API Monitor. For this scenario (because of trial and error) I’m using “Data Access and Storage” and “Internet” modules/behaviours. Immediately I can see that the malware tries to seek some folder and ends execution.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743464420661/7ac564fb-a773-478f-96f1-ae60bb9e2ed2.png align="center")

Let’s create the folder and try once again.

```powershell
mkdir 'C:\Users\Asentinn\AppData\Local\BraveSoftware\Brave-Browser\User Data\Default\Local Storage\leveldb'
```

Now it looks like it is trying to reach the C&C under `zOlsc2S65u.htb:31337` - but obviously, it cannot.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743464600578/abf8b150-8fc9-4b7b-b5be-2a8f085f86b8.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">I’ve spent hours attempting to figure out why the <code>hosts</code> changes are ignored on my setup. I’m running FlareVM on VirtualBox with Host-only network adapter. Whatever I’ve tried, nothing helped. <code>zOlsc2S65u.htb:31337</code> was unreachable. That was until I started <code>FakeNet</code> that comes with FlareVM.</div>
</div>

Adding domain to the `hosts` file, starting `python -m http.server 31337` - and nothing changes. Now that I think about it - it was meant to exfiltrate data. So let’s give it some data.

```powershell
# Run in the leveldb folder
"htbrulez" > fake.db
```

Starting process once again - and here we have.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743465028410/fea8cf64-1381-4606-8e91-bad4862777a5.png align="center")

It looks like it sends the data with a `POST` request. What keen eye notices is that communication comes with an Authorization Bearer Token:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743465336320/851bc20f-c66e-49b4-8889-48c039b0e7f4.png align="center")

Pasting that into [jwt.io](https://jwt.io/):

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743465400266/ba715ec5-e523-4e29-97f3-e459d16a094a.png align="center")

And Base64 decoding twice the `auth` portion:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1743465495471/6e903a65-cd4d-46ef-9836-6f7582a9034d.png align="center")

# Additional reading

%%[follow-cta] 

* [Malware deobfuscation by John Hammond](https://www.youtube.com/watch?v=XDAiS6KBDOs) - I’ve learned from this video a couple years ago
    
* [Extensive FlareVM installation instructions](https://github.com/mandiant/flare-vm?tab=readme-ov-file#installation-instruction)
    
* [More Windows executables shenanigans like R2R and stomping](https://blog.cyberethical.me/htb-cyber-apocalypse-forensics-oblique-final)
