Keypoints
- BugSleep (MuddyRot) uses a custom C2 protocol over plain TCP sockets with a pseudo‑TLV message format (IntegerMsg and StringMsg).
- Messages are encoded as little‑endian integers or length‑prefixed strings and then encrypted by subtracting a static value from each byte (sample value = 3).
- Two low‑level wrappers, SendSocket and ReadSocket, handle send/receive with retry logic and perform the byte‑subtraction cipher.
- Main implant routines: C2Loop sets up the socket and sends a beacon (ComputerName/Username), CommandHandler processes IntegerMsg command IDs and associated data.
- Implemented commands include Ping, GetFile, PutFile (with different page formats), and a reverse shell that spawns cmd.exe and marshals I/O via pipes until receiving “terminaten”.
- Recreating the C2 in Python follows tracing SendSocket/ReadSocket calls, decoding beacons, and implementing per-command send/receive flows and chunking behavior for file transfers.
- Detection with Snort focuses on the 4‑byte length field pattern in beacons (encoded zero bytes become 0xFD due to the cipher), uses flowbits to correlate beacon+command, and requires a bufferlen:=4 tweak to avoid reassembly timing issues; published SIDs are 63937 and 63938.
MITRE Techniques
- [T1219] Remote Access Tools – RAT functionality provides remote command execution, reverse shell, and file I/O via a custom C2 protocol (‘utilizes a custom C2 protocol for remote access. Enables reverse shell and file I/O operations on the target system.’)
- [T1071] Application Layer Protocol – C2 communications occur over TCP with a bespoke protocol and regular beacons to the C2 server (‘communicates over TCP sockets with a custom protocol. Beacons to the C2 server for command execution.’)
- [T1027] Obfuscated Files or Information – Payloads and files are obfuscated by modifying byte values (subtracting a static value) to evade detection (’employs file obfuscation techniques to avoid detection. Uses payload encryption by modifying byte values.’)
Indicators of Compromise
- [IP] C2 hosts observed – 1.235.234.202, 5.239.61.97, and 2 more hosts
- [File Hash] Sample binaries collected – b8703744744555ad841f922995cef5dbca11da22565195d05529f5f9095fbfca, 94278fa01900fdbfb58d2e373895c045c69c01915edc5349cd6f3e5b7130c472, and 6 more hashes
- [Snort SIDs] Detection rule identifiers – 63937, 63938
BugSleep’s protocol is a simple pseudo‑TLV over TCP: two record types (IntegerMsg and StringMsg) where integers are little‑endian 4‑ or 8‑byte values and strings are length‑prefixed with a 4‑byte little‑endian length followed by the bytes of the string. All payloads observed in samples are obfuscated by subtracting a static value from each byte (sample subtraction = 3), so detection and decoding must reverse that subtraction. Low‑level I/O is performed through two wrappers (SendSocket/ReadSocket) that perform the cipher, retry sends/receives up to 10 times, and are the primary points to emulate when building a C2 server.
When implementing a C2 server, mirror the implant’s sequence: accept a connection, read the 4‑byte length then the encoded beacon StringMsg (ComputerName/Username with the byte‑subtraction applied), return a 4‑byte IntegerMsg (the blog returned the received string length in tests), then send command flows as IntegerMsg IDs followed by command data. Key commands to implement: Ping (send/receive 4 bytes; observed command ID behavior requires accounting for an off‑by‑one decrement in the client), GetFile (server receives a path string, implant opens the path and sends file pages—observed to send full 1024‑byte pages), PutFile (implant expects pages starting with a 4‑byte page number followed by 1020 bytes), and reverse shell (implant spawns cmd.exe and marshals stdin/stdout via pipes until it receives the terminator string “terminaten”). Trace each SendSocket/ReadSocket call in the implant to reproduce exact sequencing, lengths, and chunking.
For detection, leverage the 4‑byte length field and the encoded zero bytes that become 0xFD when the subtract‑3 cipher is applied; beacons typically show |XX 00 00 00| in plaintext which encodes to |XX FD FD FD| in the wire samples. In Snort, set a beacon flowbit when a client sends the 4‑byte length packet (use bufferlen:=4 to match the initial 4‑byte send and avoid TCP reassembly timing issues), then create a command rule that checks the flowbit and a PCRE matching known command ID patterns at the proper offset. This flowbit chaining reduces false positives and mitigates stream reassembly ordering problems; Talos published SIDs 63937 and 63938 covering these rules. Read more: https://blog.talosintelligence.com/writing-a-bugsleep-c2-server/