{
	"id": "dca89a9f-54df-46a4-af84-61f0638d81a4",
	"created_at": "2026-09-26T02:03:04.306512Z",
	"updated_at": "2026-09-26T02:05:38.773785Z",
	"deleted_at": null,
	"sha1_hash": "0e8e81080408d5ed3ca222ee4cbdf58eaea64f9c",
	"title": "public-research/potassium/report.md at main · deepfield/public-research",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 185317,
	"plain_text": "https://github.com/deepfield/public-research/blob/main/potassium/report.md\n\npublic-research/potassium/report.md at main · deepfield/public-\n\nresearch\n\nBy deepfield-ert\n\nArchived: 2026-09-26 02:01:23 UTC\n\nPotassium: it was never about the taste\n\nNokia Deepfield Emergency Response Team (ERT)\n\nFirst published: 2026-05-20 | Last updated: 2026-05-21\n\nContent warning: This report quotes malware artifacts verbatim, including domain names, URL paths,\n\ncampaign tags, and embedded strings chosen by the threat actor. Some contain crude or offensive\n\nlanguage, including an antisemitic slur. These are reproduced exactly as found in samples to enable\n\naccurate detection and attribution.\n\nSummary\n\nPotassium is a Mirai-derived DDoS botnet, first publicly identified in March 2026 by Synthient and named after\n\nthe C2 subdomain  potassium.vitacocoyougolocobecauseyouaresodamndeliciocobarampam[.]st . Since then we\n\nhave observed at least two additional campaign roots from the same operator:\n\nikhebkankerinmijnrechterteelbal[.]st  (the  iambig  variant, grammatically correct Dutch for \"I have cancer\n\nin my right testicle\", a phrase that uses kanker as Dutch internet slang for emphasis rather than its literal medical\n\nmeaning), and most recently  botlesscucks[.]st  (the  botlesscucks  campaign, first observed 2026-05-18,\n\nwhich the operator brands internally with an antisemitic slur we use only as a verbatim IoC in Detection). Whether\n\nthere are other campaign roots we have not seen is an open question; the operator clearly rotates infrastructure on\n\na multi-week cadence. Three campaign roots, three crude jokes, one operator with strong opinions about what\n\nmakes a good domain name.\n\nWhat distinguishes Potassium from the dozens of Mirai forks we track is not its DDoS capability, which is\n\nstandard, but its choices. The operator encrypts a 222-entry config table with ChaCha20, the first time we have\n\nseen ChaCha20 used for string-table obfuscation in a Mirai variant, while protecting C2 traffic with nothing more\n\nthan a static XOR key ( 0xED ). There is a reverse shell capability the operator branded  SHOUT . There is a DNS\n\nanti-fingerprinting scheme that resolves to decoy IPs in unrelated ASNs and recovers the real C2 by swapping the\n\ntwo 16-bit halves of the address. And there is a banner string baked into the binary that reads:  it was never\n\nabout the taste . The result is a botnet that looks more thought-about than most Mirai forks and shipped anyway.\n\nThe original  vitacoco  C2 has not responded to our probes since late April. The  iambig  C2\n\n( 45.153.34[.]245 ) is reachable intermittently. The newest campaign,  botlesscucks  ( 45.156.87[.]243 ,\n\nPfcloud / VMHeaven NL, staging at  117.55.203[.]189 ), is the one currently dispatching attack commands to\n\nPage 1 of 12\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nconnected bots, at a steady rate of roughly 300 commands per day. The first hour after the new C2 came online\n\nincluded FiveM lobbies on residential ISPs in Switzerland, Canada, Hungary, and the UK; an Arma 3 server on a\n\nDutch host; and roughly seven Tor SOCKS ports on Google Cloud IPs.\n\nKey findings\n\nAt least three campaigns from one codebase ( vitacoco ,  iambig ,  botlesscucks ), each with a\n\ndifferent C2 root domain and staging path but with byte-identical ChaCha20 key, ChaCha20 nonce, bot\n\nseed ( 14861879 ), XOR key ( 0xED ), 19-byte registration header, killer-port bind ( 127.0.0.1:1234 ), and\n\nC2 protocol. The operator appears to roll the campaign root every three to four weeks.\n\nChaCha20 for config, XOR for the wire. The choice to invest in real cryptography for the static string\n\ntable while protecting in-flight C2 traffic with a single static byte is unusual. The threat model it implies\n\n(defeat static-string extraction; do not defeat network monitoring) is rare and idiosyncratic.\n\nSHOUT reverse shell. A named protocol (command  SHELL , response  SHOUT ) that lets the operator run\n\n/bin/sh -c \u003canything\u003e  on infected devices and receive XOR-encoded stdout, capped at 4 KB. We have\n\nobserved only DDoS commands in the wild, but the capability is present on every infected device.\n\nDNS word-swap obfuscation. Resolved A records point to decoys in unrelated ASNs (US DoD network\n\nspace at Incirlik AFB, universities, government research networks, AWS, Verizon Business, Kazakh\n\nresidential broadband). The bot swaps the two 16-bit halves of the resolved address before connecting. The\n\nactual C2 IP is never the one visible in DNS.\n\nActive C2 monitored continuously since late April 2026, observing attack commands, info-query\n\nheartbeats, and three campaign rotations.\n\nTimeline\n\nDate Event\n\n2026-\nvitacocoyougolocobecauseyouaresodamndeliciocobarampam[.]st  registered (StanCo / Istanco)\n02-12\n\n2026-\nFirst sample observed (ReversingLabs)\n03-13\n\n2026-\nPublic report by Synthient identifying the installer and C2 domain\n03-17\n\n2026-\n10-architecture rebuild batch uploaded to MalwareBazaar (x86, PPC, SH4, MIPS, ARM variants)\n04-07\n\n2026-\nhavanagila  staging build ( 45.153.34[.]26 ) shares the iambig C2 root\n04-22\n\n2026- iambig  campaign variant appears from  92.38.186[.]44 ; C2 domain\n\n04-24 ikhebkankerinmijnrechterteelbal[.]st\n\nPage 2 of 12\n\nDate\n\n2026-\n\n05-01\n\n2026-\n\n05-09\n\n2026-\n\n05-10\n\n2026-\n\n05-18\n\nSamples\n\nSix representative hashes across multiple architectures (plus nine additional architecture variants from the\n\nrebuild batch), all sharing byte-identical ChaCha20 key and nonce material:\n\nHash\n\n(prefix)\n\n6ef4ce02\n\ncd29241e\n\na87aa799\n\n3f13e18e\n\n6833cb46\n\ncd8420b5\n\na75a61c1\n\nAcross all three campaign variants the 32-byte ChaCha20 key (\n\n( 4a1b00ff...00010305\n\n( 0a0b0c0d0e0f00030201020304050504030201\n\nport rotation pool are byte-identical. Ghidra function-size comparison shows 94% overlap between\n\nvitacoco . These are rolling campaigns from the same operator on the same source tree.\n\nAll samples are statically linked ELF binaries compiled with\n\nhashes are in\n\nC2 architecture\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nEvent\n\niambig  rebuild (3.4 KB smaller), also served via netcat on port 25565; the rebuild switches to a\n\nnew 11-port rotation pool\n\nOriginal  vitacoco  C2 not responding to TCP probes; iambig C2 active\n\nhavanagila  arm7 binary rebuilt ( cd8420b5...\n\n45.153.34[.]26/havanagila123/arm7\n\nbotlesscucks  campaign first observed; C2 root\n\n45.156.87[.]243 , staging  117.55.203[.]189/jewishgoldowner/arm7\n\nArchitecture Campaign\n\nARM vitacoco\n\nx86 vitacoco\n\nARM\n\nARM\n\nARM\n\nARM\n\nARM\n\n), bot seed (\n\niocs/hashes.csv .\n\niambig\n\nhavanagila\n\niambig\n\nhavanagila\n\nbotlesscucks\n\n14861879 ), XOR key (\n\n), killer-port bind (\n\n, 144,388 bytes) at the same staging path\n\nbotlesscucks[.]st , real C2\n\nApril\n\nC2 domain\n\npotassium.vitacoco...st\n\nsame (10-arch rebuild)\n\nikhebkankerinmijnrechterteelbal.st\n\nsame (iambig sibling)\n\nsame (rebuild, 3.4 KB trimmed)\n\nsame (arm7 rebuild served from  45.153.34[.]26 )\n\nmusika.botlesscucks.st  (+  stoplooking1/2\n\nfallbacks)\n\n5a3f2e7b...3c2b6a08 ), 12-byte nonce\n\n0xED ), 19-byte registration header\n\n127.0.0.1:1234 ), and the post-2026-05-01 11-\n\niambig  and\n\nAboriginal Linux (GCC 4.2.1) and uClibc. Full\n\nPage 3 of 12\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nDNS word-swap obfuscation\n\nThe DNS resolution layer includes an IP transformation that makes A records misleading to casual observers.\n\nWhen the bot resolves a C2 domain, the returned IP is word-swapped before connection:  A.B.C.D  becomes\n\nC.D.A.B . The actual C2 IP is never the one in DNS.\n\nThe  vitacoco  domain resolves to IPs such as  132.198.176.65 , which belongs to the University of Vermont\n\n(AS1351). The bot word-swaps this to  176.65.132.198 , the actual C2. Similarly,  132.246.176.65  (National\n\nResearch Council of Canada, AS376) becomes  176.65.132.246 . An analyst checking DNS records without\n\nknowledge of the swap sees C2 traffic apparently bound for universities and government research institutions. The\n\nmisdirection survives most automated enrichment pipelines. The whole obfuscation layer is one line of bitwise\n\nalgebra, and the bar it has to clear is whatever enrichment runs by default.\n\nThe swap function from the binary (at  0x17ac8 ):\n\nuint swap_ip(uint ip) {\n    return ((ip \u0026 0xff0000) \u003e\u003e 8 | (ip \u003e\u003e 24) \u003c\u003c 16) \u003e\u003e 8 |\n           (ip \u0026 0xff) \u003c\u003c 16 |\n           (((ip \u0026 0xff00) \u003c\u003c 8) \u003e\u003e 16) \u003c\u003c 24;\n}\n\nThis expression is algebraically equivalent to  (ip \u003c\u003c 16) | (ip \u003e\u003e 16) , a swap of the two 16-bit halves of the\n\n32-bit word. The function has a single callsite, sitting between the in-binary DNS resolver and the  connect()\n\nsyscall. There is no other transformation between resolution and connection. Any sample whose  connect()\n\ntarget IP is the halves-swap of one of its DNS-resolved IPs is almost certainly Potassium or a same-codebase\n\nvariant.\n\nThe pattern survived every campaign rotation. The  botlesscucks  campaign uses it identically:\n\nmusika.botlesscucks[.]st  resolves to  87.243.45.156  (Kazakh residential broadband, AS21299), and the bot\n\nconnects to  45.156.87.243  (Pfcloud / VMHeaven NL, AS51396).\n\nPort rotation\n\nEach connection attempt selects a random port from an 11-entry table embedded in the binary. The four samples\n\nanalyzed in late April share an identical pool:\n\n19876, 60764, 27603, 27776, 29502, 1207, 26608, 7574, 876, 57536, 6428\n\nThe  iambig  rebuild from 2026-05-01 onward and the entire  botlesscucks  campaign use a different pool,\n\nwith all 11 ports listening simultaneously on the live C2:\n\n7193, 15987, 23789, 27651, 32876, 38429, 42061, 46852, 49376, 54123, 61543\n\nCombined with DNS round-robin (five-plus IPs) and the word-swap layer, a single connection attempt uses one of\n\ndozens of possible IP and port combinations. The two distinct pools across campaign generations mean an external\n\nprober tracking only the original pool will miss the newer infrastructure entirely.\n\nPage 4 of 12\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nSingle-instance lock on TCP/1234\n\nThe bot binds a TCP listener on port 1234, bound to the egress IP discovered via the standard \"UDP-connect to\n\n8.8.8.8:53 + getsockname\" trick, with 127.0.0.1 fallback. This is not a backdoor or an alternate C2 channel: the\n\naccept handler immediately closes the listener, kills its children, sleeps a second, and exits. A second bot instance\n\nlaunched on the same device hits  EADDRINUSE  on its own bind, connects to the existing listener to trigger that exit\n\nbranch, and takes over. The wider pattern is Mirai's single-instance lock, but the dedicated port (vs. the more\n\ncommon  127.0.0.1:48101 ) and the takeover semantics are characteristic enough to be useful as a host indicator.\n\nEncryption\n\nChaCha20 config table (222 entries)\n\nThe static config table uses IETF ChaCha20 with a key and nonce embedded in the  .data  section:\n\nParameter Value\n\nKey (32 bytes) 5a3f2e7b 8c9d0a6e 3b4f7c8a 1d5c2b0d 6f1a0c3e 2d8e4a09 1c7e5a4d 3c2b6a08\n\nNonce (12 bytes) 4a1b00ff 2d7c3a12 00010305\n\nCounter 1 (first 64-byte keystream block skipped)\n\nThis is the first Mirai variant we have observed using ChaCha20 for string-table obfuscation. Standard Mirai uses\n\na 4-byte XOR key; most derivatives follow suit. The ChaCha20 choice makes static string extraction harder than a\n\nsimple XOR brute-force, but the key is static in  .data , identical across all builds, so offline decryption is\n\nstraightforward once located. In key-rotation terms the operator's stance is one-and-done: the ChaCha20 key has\n\naged better than the original C2 domain.\n\nThe 222 entries cover C2 domains, bot process names, an operator banner, process kill lists (100+ kernel threads\n\nand daemons), filesystem paths (50+ DVR and IoT-specific paths), architecture identifiers, shell paths, and reboot-\n\nblocking strings.\n\nXOR C2 traffic (key 0xED)\n\nAll C2 wire traffic, including registration, attack commands, info-query responses, and SHOUT responses, uses a\n\nsingle static XOR byte. The contrast with the ChaCha20 config table is striking: the operator invested in real\n\ncryptography to protect strings at rest and protected strings in transit with the digital equivalent of ROT13. A\n\nnetwork observer with  tcpdump  and  xxd  reads every command in real time, which the operator presumably\n\nknows and presumably does not care about.\n\nWhat is different about the C2 protocol\n\nThe wire protocol is conventional Mirai underneath: TCP, select-based event loop, 15-second timeout, 2-byte\n\nplaintext keepalive every six timeouts, attack commands in the standard 4-byte duration plus 1-byte attack ID plus\n\nPage 5 of 12\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nN-target plus TLV-options binary format. We will not repeat that here. What is worth calling out is the handful of\n\ndesign choices that distinguish Potassium from other Mirai families we track.\n\nCampaign tags in the registration packet. Every bot stamps itself with a short ASCII tag on registration\n\n( wget.woof ,  curl.woof ,  xpl1 ,  xpl2 ,  xpl3 ,  hoofdzak ,  iambig ,  jewishgold ). The  jewishgold  tag is\n\nan antisemitic slur chosen by the operator and reproduced verbatim only because it is a literal byte sequence on\n\nthe wire; we use  botlesscucks  (the C2 root domain) as our analyst label for the same campaign throughout this\n\nreport. The tag combines the download method that delivered the bot and the campaign name, giving the operator\n\nper-installer analytics on the C2 side. The combination of delivery vector and campaign in a single string is more\n\ngranular than we typically see, though we have not gone looking for the equivalent in other families. Marketing-\n\nfunnel attribution for botnet installs is the kind of thing the rest of the ecosystem may well be doing too, just less\n\nvisibly.\n\nBroken registration trailer the C2 accepts anyway. The 2-byte trailer at the end of every registration packet is\n\ncomputed by a routine at  0x134e0  in the binary — an Internet checksum (ones-complement sum of little-endian\n\n16-bit words), not the CRC16 sometimes assumed. At the registration call site the routine is invoked with a halved\n\nbyte count  (N + M + 4) \u003e\u003e 1 , so the checksum only protects roughly the front half of the XOR-encoded body.\n\nThe live C2 treats the trailer permissively: a CRC16-Modbus over the full body is accepted, and so is the bot's\n\nexact broken halved-length output. The most natural reading is that C2-side validation of the trailer was loosened\n\nat some point after the bot code was originally compiled, taking the mismatch off the table without anybody\n\nhaving to ship a new bot build. The asymmetric posture — real ChaCha20 for the static config table, an\n\nunenforced 2-byte trailer on the wire — is consistent with the rest of the family's threat model.\n\nReceive-side  RECV_MAGIC  for info queries. The C2 prefixes status-poll packets with a fixed 18-byte magic. The\n\nbot checks this prefix before falling through to the SHELL or attack-command parsers. The magic is data, not a\n\nheader field, which makes it cheap to grep for in packet captures: searching  tcpdump  output for the XOR-\n\ndecoded magic flushes every potassium info query on the wire.\n\nSHOUT reverse shell on the same channel. Most Mirai forks ship a dispatcher and stop there. Potassium ships\n\nSHELL  (C2 → bot, plaintext command up to 1010 bytes) and  SHOUT  (bot → C2, XOR-encoded stdout up to\n\n4090 bytes) on the same TCP connection, framed by a 5-byte literal magic and a big-endian length. The\n\nimplementation is plain  pipe()  +  fork()  +  execl(\"/bin/sh\", \"sh\", \"-c\", cmd, NULL) , with\n\n/system/bin/sh  as an Android fallback. The capability changes the post-attack posture: an infected device is not\n\njust a DDoS source, it is a foothold the operator can use for credential collection, lateral movement, and\n\npersistence beyond the DDoS payload. The naming ( SHELL  in,  SHOUT  back) is the kind of onomatopoeia\n\nengineering you do when you have one shot at a memorable wire-format magic and you are not going to waste it.\n\nWord-swap obfuscation, again. Covered above but worth repeating in this context: the bot does its own DNS\n\nresolution against  8.8.8.8:53  (bypassing the libc resolver entirely), then halves-swaps the result before\n\nconnect() . Combined with five-IP DNS round-robins, this is the most effective obfuscation layer the family\n\nships.\n\nAttack methods\n\nPage 6 of 12\n\nThe attack module retains Mirai's standard binary command format (4-byte big-endian duration, 1-byte attack ID,\n\n1-byte target count, N × 5-byte\n\nentries, each pointing to a flood handler whose actual socket type is verified from\n\ndisassembly\n\nby stock-Mirai (ID → name) mapping will mislabel them. The protocol column below is verified from each\n\nhandler's\n\npoints at a different handler in potassium. The Notes column flags name/protocol mismatches and handler quirks;\n\nempty cells indicate the name and the implementation agree. The dispatch table:\n\nID\n\n0\n\n1\n\n2\n\n3\n\n4\n\n5\n\n6\n\n7\n\n8\n\n9\n\n10\n\n11\n\n12\n\n13\n\n14\n\n15\n\n16\n\n17\n\n18\n\n19\n\n. The dispatch IDs are reassigned relative to a reference Mirai source, so any tool that labels methods\n\nsocket()  arguments; the Name column shows the conventional Mirai name for that slot ID, which now\n\nName\n\nudp_plain\n\nudp_raw\n\ntcp_bypass\n\nsyn_spoof\n\nack_flood\n\nsyn_data\n\ntcp_socket\n\nsocket_hold\n\ntcp_raw\n\nwra_flood\n\ngre_ip\n\ntcp_stomp\n\novh_bypass\n\nstd_flood\n\nudp_bypass\n\nudp_openvpn\n\ndns_query\n\nmc_ping\n\ntcp_xmas\n\nhttp_connect\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\n\u003cIP/prefix\u003e  targets, 1-byte option count, TL\n\nProtocol\n\nUDP RAW\n\nUDP DGRAM\n\nTCP RAW\n\nTCP RAW\n\nTCP STREAM\n\nUDP RAW\n\nUDP DGRAM\n\nUDP DGRAM\n\nTCP RAW + STREAM\n\nICMP RAW\n\nGRE (IPPROTO_RAW)\n\nTCP RAW\n\nUDP DGRAM (connected)\n\nUDP DGRAM\n\nTCP RAW + STREAM\n\nUDP DGRAM (connected)\n\nTCP RAW\n\nTCP RAW + STREAM\n\nTCP RAW\n\nTCP STREAM\n\nPage 7 of 12\n\nV options). The dispatch table is 20\n\nsocket()  calls in the\n\nNotes\n\nCrafted UDP flood\n\nDGRAM despite the name\n\nRAW UDP despite the name\n\nUDP despite the name\n\nUDP despite the name\n\nTwo sockets per handler\n\nICMP, not TCP\n\nGRE encapsulation\n\nconnect() -locked, uses  send()\n\nSix-template payload rotator (see below)\n\nTCP despite the name\n\nconnect() -locked\n\nTCP despite the name\n\nMinecraft-server ping flood\n\nTCP with all flags set\n\nL7 GET/POST with 3-UA rotation\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nReading the table is a little like reading a Discord server channel list after a busy weekend of admin changes: the\n\nlabels still mean what they originally meant; the channels do not.\n\nThe TLV option parser supports keys for fixed payload size ( 0x00 ), source and destination ports ( 0x06 ,\n\n0x07 ), TTL ( 0x04 ), connection count ( 0x18 ), packet-per-second cap ( 0x22 ), user-agent override ( 0x24 ),\n\nand HTTP method and path overrides ( 0x14 ,  0x15 ). Options  0x1a  and  0x1b  are a min/max range for\n\nrandomized per-packet payload size: the attack handler reads both, requires  0x1a ≤ 0x1b , and picks a random\n\nlength in  [0x1a, 0x1b]  for each packet it crafts. Typical observed values  0x1a=1312, 0x1b=1440  are a narrow\n\nwindow sitting just under common MTUs, which keeps the attack traffic from fragmenting.  0x00  (above) and\n\n0x1a / 0x1b  are alternative modes — fixed vs. randomized payload size — rather than redundant.\n\nThe  std_flood  handler (ID 13) rotates across six payload templates. Three of them mimic authenticated web\n\ntraffic with  token=\u003c40-hex\u003e\u0026guid=\u003c24-hex\u003e  strings. These are not real credentials; they are attack-payload\n\ncontent designed to look like legitimate web requests so DDoS-mitigation L7 fingerprinters spend time processing\n\nthem.\n\nObserved in the wild\n\nFrom continuous monitoring of the active C2 since 2026-05-09, we have logged roughly\n\nper day alongside heartbeat info queries from the C2.\n\ndispatched methods break down as follows:\n\nAttack ID Name\n\n7 socket_hold\n\n4 ack_flood\n\n15 udp_openvpn\n\n14 udp_bypass\n\n12 ovh_bypass\n\nAcross the 10-day window 2026-05-09 to 2026-05-19 the\n\nProtocol\n\nUDP\n\nTCP\n\nUDP\n\nTCP\n\nUDP\n\n300 attack commands\n\nShare of dispatches\n\n66.0%\n\n17.5%\n\n5.8%\n\n4.5%\n\n2.6%\n\n8\n\n1\n\n13\n\n19\n\n9\n\n3, 10\n\nEight handlers in the dispatch table (\n\ndns_query ,  mc_ping\n\ntcp_raw TCP 1.2%\n\nudp_raw UDP 1.2%\n\nstd_flood UDP 0.7%\n\nhttp_connect TCP 0.3%\n\nwra_flood\n\nsyn_spoof ,  gre_ip\n\nudp_plain ,\n\n,  tcp_xmas ) were not dispatched during the window\n\nICMP\n\nTCP, GRE\n\ntcp_bypass ,  syn_data\n\nPage 8 of 12\n\n0.2%\n\n\u003c0.1% each\n\n,  tcp_socket ,  tcp_stomp ,\n\n. They are present in the binary; the\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\noperator did not invoke them in the observed period. If any of them ever fires we will be looking at the binary\n\nagain, on Chekhov's gun rules.\n\nRoughly a third of all attacks target gaming infrastructure (FiveM, Arma 3, Minecraft, Source-engine servers); the\n\nremainder split between general web ( 80 / 443 ), DNS, and miscellaneous services. Attack duration distribution:\n\nminimum 20 seconds, median 66 seconds, p95 180 seconds, single observed maximum of 3600 seconds. The 66-\n\nsecond median sits squarely in the range of the cheapest tier offered by most booter services we have priced;\n\nwhether that reflects operator demos or paying customers picking the entry-level option, we cannot tell from the\n\nC2 traffic alone.\n\nThe gaming target list reads less like an infrastructure campaign and more like someone trying to ratio a specific\n\nDiscord. FiveM, Arma 3, and Source-engine community servers are where individual disputes turn into paid\n\noutages.\n\nThe newest campaign ( botlesscucks ) has been live too briefly to draw firm conclusions, but its first hour of\n\nobserved traffic skews to the same  socket_hold  /  ack_flood  /  udp_bypass  /  ovh_bypass  /  std_flood  mix\n\nas iambig, with target ports leaning slightly more toward gaming ( 6672  repeated, plus new sightings on  9050 ,\n\n9011 ,  9005 ,  9026 ,  9062 ,  9116 ,  9124 , which look like Tor SOCKS ports, a target class we had not\n\npreviously seen this operator hit). GTA mod lobbies and Tor SOCKS endpoints share very little customer\n\ndemographic, which makes the same-hour overlap one of the more curious patterns we have logged.\n\nBot behavior\n\nProcess management\n\nProcess disguise: renames itself via  /proc/self/comm  to  dvrLocker  or  dvrInside  (from config table\n\nentries 4 and 5), blending in with DVR management processes.\n\nFake crash banner: outputs  Segmentation fault (core dumped)  to stdout on startup (config table entry\n\n9), followed by the actual banner  it was never about the taste  (entry 8). Anyone watching terminal\n\noutput briefly believes the bot crashed; the motto two lines later somewhat undoes the bit.\n\nCompetitor killer: scans  /proc/*/maps  for byte patterns from rival Mirai-family binaries and sends\n\nSIGKILL  to any match. Standard Mirai-fork behaviour; the targets are the usual suspects.\n\nReboot prevention: kills  reboot ,  shutdown ,  halt , and  poweroff  processes.\n\nWatchdog disable: accesses  /dev/watchdog  and  /dev/misc/watchdog  to prevent hardware watchdog\n\nresets.\n\nDaemonization: double  fork()  with stdio redirect to  /dev/null .\n\nScanner\n\nMirai-style telnet scanner with process-name awareness. The kill list contains 100+ kernel thread names, network\n\ndaemons, and system processes that should not be terminated. ADB-based delivery to Android devices is observed\n\nin practice (the  execl(\"/system/bin/sh\", ...)  fallback in the SHOUT handler is consistent with this), while the\n\nDVR/IoT-specific paths in the config table ( /dvr/bin ,  /mnt/mtd/app ,  /duksan ,  /userfs ,  /gm/bin ,\n\nPage 9 of 12\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\n/var/Sofia ,  /home/davinci ) point at HiSilicon-based DVRs, NVRs, and IP cameras as an additional target\n\ndevice class.\n\nOperator artifacts\n\nThe naming. The operator's naming conventions are a study in commitment to a bit. The parent domain\n\n( vitacocoyougolocobecauseyouaresodamndeliciocobarampam[.]st ) is 60 characters of stream-of-consciousness\n\nbrand enthusiasm for Vita Coco coconut water. The staging path  /mypantsarefullofshit/arm7  is exactly the\n\nkind of URL path that gets flagged in corporate proxy logs. The alternative staging path\n\n/1000mgofpotassiumaday/arm7  is where the family gets its public name. The botnet is, in effect, named after a\n\ndietary supplement recommendation encoded in a URL path. There are worse precedents for botnet naming\n\nconventions, but not many.\n\nThe Dutch pivot. The  iambig  campaign is the only one of the three with Dutch content. Its C2 domain\n\n( ikhebkankerinmijnrechterteelbal[.]st ) is native-level Dutch with correct grammar and word order, and the\n\nuse of kanker as an intensifier (rather than its literal medical meaning) is characteristic of Dutch internet slang.\n\nThe campaign tag  hoofdzak  (\"main thing\", observed 2026-05-09) is also Dutch. The other artifacts on the\n\noperator's side ( vitacocoyougoloco… ,  botlesscucks , the motto, all staging paths, the  xpl*  /  wget.woof  /\n\ncurl.woof  tags) are in English. The honest reading is that the operator has at least Dutch fluency, not that they\n\nare primarily Dutch-speaking; one branded campaign in idiomatic Dutch is what the evidence supports.\n\nThe motto. Config table entry 8 reads  it was never about the taste . Printed to stdout after the fake segfault.\n\nIn context, it appears to be an operator motto, possibly referencing the Vita Coco theme (coconut water being\n\nfamously divisive on taste). It also works as a statement of purpose for the botnet itself: the point was never the\n\nproduct, it was the infrastructure.\n\nThe bot seed. Every Potassium bot generates its unique ID by appending random digits to the seed  14861879 .\n\nThe 8-digit number is consistent across all builds and campaigns. We have not identified a meaning.\n\nRelationship to other families\n\nUnrelated to the Aisuru / Jackskid ecosystem. No shared cryptography (no custom RC4, no XXTEA, no\n\nmbedTLS), no shared C2 protocol (raw TCP and XOR vs. their HTTP token/guid or TLS), no shared\n\ninfrastructure, no shared developer artifacts.\n\nShared toolchain, not shared code. The Aboriginal Linux GCC 4.2.1 cross-compiler is used by Potassium,\n\nFlameblox, and Katana, but it is a publicly available Mirai build environment used by unrelated operators. The 10-\n\narchitecture batch rebuild in April 2026 demonstrates the same pattern we see in Flameblox: an operator who\n\nfound the Aboriginal multi-target build system and compiled for everything it supports.\n\nCross-family targeting overlap. Across our 10-day monitoring window, 124 potassium attack commands landed\n\non a target IP within 60 seconds of an attack from a different family we track. Roughly half of those pairings (63\n\nevents) put potassium and CECbot on the same target within a second or two of each other, often on the same\n\ndestination port. Lower-volume same-window overlap is also visible with Vibenet — a Mirai family we track\n\ninternally but have not yet documented publicly — (46 events) and Drifter (14). We have not identified shared\n\nPage 10 of 12\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\ninfrastructure, shared code, or shared cryptographic material between potassium and any of these families. The\n\ncleanest reading is shared booter customers rather than shared operators: a single buyer paying multiple services to\n\nchain volume against the same target is the simplest explanation for simultaneous same-target same-port\n\ncommands. This is the first time we have looked at cross-family target sync systematically; whether the pattern is\n\nspecific to potassium or normal across the booter ecosystem is an open question we plan to widen. From the\n\noperator side this is two separate businesses each receiving a paid order; from the victim side it is one bad\n\nafternoon.\n\nDetection\n\nNetwork indicators\n\nTCP connections with XOR  0xED  encoded payloads.\n\nRegistration packets containing the 19-byte fixed header\n\nbyte plaintext tag length, an XOR-encoded body, and a 2-byte trailer (not strictly bound to a single\n\nchecksum function — see C2 protocol).\n\nConnections to one of 11 fixed ports per variant. Pre-rebuild samples (all\n\niambig ):  876, 1207, 6428, 7574, 19876, 26608, 27603, 27776, 29502, 57536, 60764\n\niambig  (2026-05-01 and later) and all  botlesscucks  traffic:\n\n38429, 42061, 46852, 49376, 54123, 61543 .\n\nLocal TCP listener on port 1234.\n\nSYN packets to port 23/TCP (the telnet scanner).\n\nBot's own DNS resolution targeting  8.8.8.8:53  (the libc resolver is bypassed). The resolved IP is then\n\nhalves-swapped before  connect() .\n\nHost indicators\n\nProcess names  dvrLocker  or  dvrInside .\n\nBanner strings  Segmentation fault (core dumped)  and\n\nListener bound to port 1234 on the device's egress interface (or\n\nfails).\n\nIndicators of compromise\n\nMachine-readable IoC files are in  iocs/ :\n\nFile Contents\n\ndomains.csv C2 root and subdomain candidates per campaign\n\nips.csv DNS-decoy IPs, word-swapped real C2 IPs, staging IPs\n\nhashes.csv Representative sample SHA-256 hashes per campaign and architecture\n\nkeys.csv ChaCha20 key/nonce/counter, XOR key\n\nPage 11 of 12\n\n0a0b0c0d0e0f00030201020304050504030201\n\n7193, 15987, 23789, 27651, 32876,\n\nit was never about the taste\n\n127.0.0.1:1234\n\n, bot seed, killer port\n\n, a 1-\n\nvitacoco  builds plus original\n\n. Post-rebuild\n\n.\n\nif the egress IP probe\n\nhttps://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nPrior research and acknowledgements\n\nThe Potassium family was first publicly identified by @deobfuscately (Synthient) on 2026-03-17, who named it\n\nafter the staging URL path  /1000mgofpotassiumaday/arm7  and posted the original sample SHA-256\n\n( 6ef4ce02... ). Without that initial pivot we would not have had a starting point.\n\nWe previously posted a public update on 2026-05-07 confirming the  iambig  variant, three sample hashes, the\n\nbyte-swap C2 mechanism, and the Dutch C2 domain. One framing in that update has since been corrected by the\n\nverification work in this report: the C2 protocol is raw TCP with  0xED  XOR, not HTTP — the  token=  /  guid=\n\nstrings are attack-payload content (see Attack methods), not C2 metadata. ADB-based delivery to Android\n\ndevices, also mentioned in that post, remains consistent with our observations; the encrypted config table\n\nadditionally references HiSilicon DVR/NVR/IP camera filesystem paths, so the target device class is broader than\n\nAndroid TV alone.\n\nThe reverse engineering, protocol verification, encryption analysis, attack-table verification, three-campaign\n\nattribution, DNS word-swap mechanism, live monitoring infrastructure, and the cross-family same-target overlap\n\nmeasurement in this report are original Nokia Deepfield ERT analysis. Errors in this report are ours; corrections\n\nwelcome.\n\nEdit history\n\nDate Change\n\nC2 protocol: documented registration trailer (broken halved-length Internet checksum; live C2\n\n2026- accepts other forms, indicating server-side validation was loosened post-compilation); corrected\n\n05-21 TLV options  0x1a / 0x1b  from speculative \"timing/rate hints\" to min/max range for randomized\n\npayload size.\n\nSource: https://github.com/deepfield/public-research/blob/main/potassium/report.md\n\nPage 12 of 12",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://github.com/deepfield/public-research/blob/main/potassium/report.md"
	],
	"report_names": [
		"report.md"
	],
	"threat_actors": [],
	"ts_created_at": 1790388184,
	"ts_updated_at": 1790388338,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/0e8e81080408d5ed3ca222ee4cbdf58eaea64f9c.pdf",
		"text": "https://archive.orkl.eu/0e8e81080408d5ed3ca222ee4cbdf58eaea64f9c.txt",
		"img": "https://archive.orkl.eu/0e8e81080408d5ed3ca222ee4cbdf58eaea64f9c.jpg"
	}
}