Summary
Scenario
Something is wrong at Maromalix. On February 10th, 2026, credentials that should never have left the network were suddenly used from an unauthorized external source. The trail led back to a single server: their public-facing web application. No failed logins, brute force, or phishing were detected, yet the attacker gained entry and established a way to return. This follows a pattern of Maromalix being targeted by attackers leveraging AI-assisted tooling. Using the captured network traffic, reconstruct the timeline and uncover exactly how this breach occurred.
Initial Access
Q1: What is the IP address of the attacker that exploited the web application?
By reading the scenario above carefully, we have a public-facing web application asset that got attacked, so let’s start investigation.
We are provided here with a pcap file with ssl keys log file:
At first, filtered for http traffic, and took a look at conversations, found the IP for the web-server (arguably172.31.44.238
is the web-server IP)
Narrowing down a little with this query: http.request.methodPOST and ip.dst172.31.44.238
for less packets and better inspection (~300 packets).
After following someTLS
streams, found this communication:
a weird POST requests generated by a script maybe (User-Agent: python-requests/2.31.0\r\n
) and have the same length (339
).
so, i guess this needs further investigation by adding the source IP address http.request.methodPOST and ip.dst172.31.44.238 and ip.src==63.180.69.24
Actually i couldn’t stop myself from inspecting the fisrtPOST
request with a different length, so i followed the TLS
stream for this hovered packet:
so it’s a payload that abuses a JavaScript weakness (prototype pollution + constructor escape) to escape normal restrictions, then executes the system command id on the server. After that, it tries to sneak the result back to the attacker by embedding it inside an error response.
Also, By investigating the second packets with the length > 339:
we can find this payload also:
So it makes sense now!!
63.180.69.24
Q2: What is the CVE identifier for the vulnerability exploited in this attack?
from the Lab Name, we can search and get the CVE easily:
Or by searching for the CVE from the payloads we’ve already identified in the previous question:
CVE-2025–55182
Execution
Q3: What is the filename of the script downloaded by the exploit payload to install the malware?
based on paloalto report (link) we did identified this
so, we can filter for the user-agent curl
, and GET
requests:http.request.method==GET and http.user_agent contains “curl”
s.sh
Q4: What is the filename of the decrypted implant that serves as the main RAT?
By investigating the bash script file, we can get the correct answer directly:
.7vfgycfd01.js
Defense Evasion
Q5: What is the hidden directory path used by the malware to store its components?
Investigating the same Bash script file, it’s obvious at the beginning of the file:
~/.local/share/.05bf0e9b
Q6: The malware checks system locale to avoid execution in certain regions. What is the first locale code in the blocklist?
since we have the full script, the script contains a Base64 encoded Blob
That is AES Encrypted, with a clear Key and IV as you can see,
So, Let’s decrypt it properly on cyberchef (link), and get the answer:
ru
Command and Control
Q7: What are the two smart contract addresses used for C2 resolution? (Format: in the order they are queried)
from the same previous decrypted Code, we can get the addresses directly:
0x22f96d61cf118efabc7c5bf3384734fad2f6ead4,0xb0cbaA51b3D1D36e8E95F4F68dfBd47ED2eaA7a4
Q8: When was the primary smart contract deployed on the Ethereum network (UTC)?
from the previous image, we can determine that the first contract is the primary one, so let’s check it online (link)
from etherscan, we can can go to the full contract and get the timestamp:
2025–12–05 19:13:47
Q9: Since the smart contract is deployed on a public blockchain, its source code can be obtained.
What function name is used to retrieve the stored C2 URL?
in my case i used the Dedaub (LINK),
Now, we can put the input data we found in the contract into Dedaub:
just like this:
and now it’s decompiled successfully:
it’s basically a minimal storage contract that lets an address store and retrieve a string mapped to its address, so let’s take that full string and decompile it again into Dedaub:
getString
Q10: What is the transaction hash of the first C2 URL published to the primary contract?
investigating the first transaction hash as shown:
investigating the Input data:
Decode Input
so yeah, it contains the C2 URL, so hit the transaction hash for the answer
0xe4efe4d2b118229161f7023e13ab98b54180fbfb1756d11959e4f19238b9655d
Q11: When did the implant retrieve the C2 URL from the blockchain (UTC)?
falling back to our pcap file, we can use this filter: http contains “eth”
or search for eth_call
since it is the JSON-RPC method used to read data from smart contracts:
2026–02–10 18:37
Q12: What C2 URL did the implant retrieve from the blockchain during execution?
we can see here the traffic direction:
https://63.176.62.199:443
Q13: What is the Bot ID assigned to the compromised host?
Get Loay Salah’s stories in your inbox
Join Medium for free to get updates from this writer.
the same previous packet, we can get the BotID from it
4ebfbc8aedf60511
Credential Access
Q14: Once connected to the C2, the implant started executing multi-stage payloads.
What is the endpoint path used for exfiltrating harvested credentials?
checking all visited URLs, until you’ll find this:
/crypto/keys
Persistence
Q15: What is the filename of the systemd user service created for persistence?
Since we are looking for Linux persistence via a systemd user service, so the goal is to find where the attacker creates or references a .service
file.
c16a536e1a9cb42d.service
Q16: What is the comment field in the attacker’s injected SSH public key?
we need to know first that the structure is like this:ssh-rsa