In short
- MikroTrick chains two RouterOS bugs into a full, unauthenticated takeover of any MikroTik device with SSH reachable. Exploitation ran from September 2, one day before the patches and three days before the advisory.
- We reproduced the entire chain end to end from only the public advisory and the patch diff, in a single uninterrupted run: approximately three hours and roughly 110,000 tokens (the token count covers the main session; the subagent that reverse-engineered the patched binaries in the background ran on top of that), verified against both vulnerable releases. Four frontier models given the same inputs failed.
- These devices no longer sit only at the edge. They wire up local AI clusters (the DGX Spark, TP>2 crowd), so one compromise exposes model weights, datasets, and all east-west traffic.
- Defense still investigates at ticket speed while offense iterates at agent speed, and CERT Polska cannot rule out additional undisclosed bugs. The detection section and IoC table below are the checks to run now.
On September 5, CERT Polska disclosed six vulnerabilities in MikroTik RouterOS. Two of them chain into MikroTrick: a full, unauthenticated takeover of any router with SSH reachable. Attackers had been using it since at least September 2, a day before MikroTik shipped fixes and pushed a notification to every phone running its app, begging people to update.
We handed the public advisory and the patch diff to an AI agent. In a single uninterrupted run, approximately three hours and roughly 110,000 tokens later it had booted the vulnerable RouterOS images in local VMs, recovered the exploit primitives, and chained a working, unauthenticated takeover, verified end to end against both vulnerable releases. That token figure covers the main session only; the subagent that reverse-engineered the patched binaries in the background ran on top of it. Four frontier models given the same inputs either refused or failed to produce a working chain.
Exploitation started three days before the public
advisory. The patch existed, but the window between “fix available” and “fleet
updated” is where campaigns live, and this campaign was already inside. The
timestamps are checkable by anyone: the Last-Modified headers on MikroTik’s
download server put the fixed 7.24.2 builds at September 3, 10:50 GMT, while
the oldest observed attack logs read September 2. The 7.23 train even needed
two patch builds, 7.23.4 on September 3 and 7.23.5 a day later.
A researcher raised the first public alarm. Costin Raiu
flagged “a 1-day full
MikroTik RCE chain against SSH being used in the wild,” pointing at CERT
Polska’s detection guidance, and then
posted the worse version of
the story: what looked like a 1-day was actually running a day before the
patches even shipped, so the team whose detection strategy starts with the vendor
bulletin was already three days late. His follow-on
write-up
adds the forensic details: the patch-drop timestamps on MikroTik’s own download
server, and the staging kit sitting open on the main attack IP, a stock
busybox-mips binary plus tiny Python scripts serving FTP and HTTP, the
disposable tooling of a mass-exploitation wave.
It is still not confirmed that the observed intrusions use exactly these CVEs, and CERT Polska says it cannot rule out additional vulnerabilities the vendor never described. A campaign this early could be riding a different, still-unnamed bug set, so indicators tied to specific CVEs only catch yesterday’s chain. Hunting also has to weigh behavior and exposure.
The attack, high level
The chain needs nothing but network access to the SSH service. A weakness in how RouterOS handles the SSH login sequence lets an unauthenticated client reach a session it should never reach. A second flaw (an argument-handling bug in the login helper) lets that session swap its permissions for the full administrative policy set. The result is a root-equivalent console on the router: no password, no key, no user interaction.
The fingerprints it leaves are unusually crisp:
- Log lines like
login failure for user -2 from <ip> via ssh, followed by configuration changes attributed tossh:-2@<ip> - A highly privileged account named ops that nobody on your team created
- Suspicious scheduler entries combining
fetchandimport, unexpected SOCKS proxies, or tunnels - On patched versions, a
flagged: yesmarker from MikroTik’s built-in compromise scanner
The question is: How fast can you run these checks against everything you own?
How the bugs chain
Each bug in the chain is unimpressive alone, which is why single-CVE triage keeps underestimating days like this one.
The rekey bug (CVE-2026-67279) lets a client that has never authenticated open an SSH session channel anyway, because the server loses track of whether the login step ever happened. By itself, it is almost a dud: the session runs with nearly no privileges.
The username bug (CVE-2026-86060) is a relic from a friendlier era. The RouterOS
login helper supports a legacy mode where a dash-led argument means “read the
trusted username and permission mask from this file descriptor,” a mechanism
built for trusted local processes. A username of -2 therefore tells the
helper to read its own credentials from the terminal, and whatever it reads
becomes the session’s permissions. By itself it is also a dud: RouterOS refuses
to create a user called -2, so no normal login ever reaches that code.
The glue is a state bug that is not even a separately named vulnerability: an
authentication attempt as -2, one that is rejected instantly, leaves the
username pending in the server’s session state. Present -2, get rejected,
trigger the rekey bug, and open a terminal. The server hands the login helper
the pending -2, the helper reads its “trusted” credentials from the
attacker’s keyboard, and the session comes up with the full administrative
policy set. In our lab that session created a full-privilege ops user and
produced, byte for byte, the log lines CERT Polska reported from real
intrusions.
A third bug (CVE-2026-67276) is a parallel path for devices where the chain’s first step is blocked: the SSH server matches authorized public keys by their RSA modulus but not their exponent, and verifies the login signature with whatever key the client supplies. A known public key, and public keys are meant to be public, becomes a skeleton key for that account.
Three flaws, each survivable in isolation, add up to one full takeover. Exposure and topology decide the real severity; individual CVSS scores do not.
Why this target and why now
Pre-auth remote code execution is the rarest, most valuable bug class anywhere. On a router or on a switch, it compounds. These boxes see every packet you send, terminate your VPNs, and sit exactly at the trust boundary your security model is built around. They run no EDR, get no MFA prompts, appear in no endpoint console, and are rarely rebooted, and a reboot is the one event that would even dislodge a careful implant. An unauthenticated exploit there hands over the whole chessboard.
MikroTik has always been the price-performance king of the edge, but lately it picked up a new job: it is the go-to interconnect for the local AI crowd, especially for the DGX Spark owners running local AI clusters that keep landing on the same answer: a MikroTik CRS switch.
Why the usual process loses this race
The standard response loop is a queue. Someone reads the advisory. Someone writes a ticket. Someone figures out which of the hundreds of network devices actually run RouterOS, which of those expose SSH, and which matter. Someone checks logs. Someone schedules a maintenance window. Every step waits on a human who is busy with the previous emergency.
And that is before the vendor’s own clock starts. Patch latency varies wildly by vendor. MikroTik shipped fixes in days this time. We have vulnerabilities we reported to other vendors in July that are still unpatched. Your exposure window is the sum of two queues you do not control: how fast the vendor ships, and how fast your organization applies. You control only the second.
We measured this gap across every confirmed-exploited CVE in the KEV catalogs in an earlier post: the median time from disclosure to in-the-wild exploitation is 1.5 days. MikroTrick compressed it further, to a negative number, and a process measured in tickets cannot beat an adversary measured in minutes.
The adversary’s side is already agentic. The CERT Polska team disclosed that AI models found the vulnerabilities, running in an agent-based research loop, hypothesizing, testing against real routers, discarding false leads, at machine tempo. Offense found six bugs this way while defense still opens tickets.
What detection actually looks like in the logs
Detection here means answering, per device: was it hit at any point since September 2?
Start with the RouterOS log itself, /log print. It is
memory-resident by default and dies with a reboot, and attackers who own the
device can edit it. Treat the on-device log as a first pass, and your
remote syslog or SIEM (/system/logging action targets) as the source of
truth. The entries that matter, as they actually appear:
system,error,critical login failure for user -2 from 82.192.72.4 via ssh
system,info,account user -2 logged in from 82.192.72.4 via ssh
system,info user ops added by ssh:-2@82.192.72.4
ssh,error signature verification failed for user: admin
ssh,info auth timeout
The user -2 failure followed by activity attributed to
ssh:-2@ is the campaign fingerprint CERT Polska
published. A dash-led
username should never exist on a healthy system, so any match is a
near-perfect signal. signature verification failed entries are the SSH
public-key forgery being probed. Bursts of auth timeout are the pre-auth
rekey abuse, and user ops added records the persistence account landing.
Then the config side, because logs are what the attacker let you keep:
/user print: any account you do not recognize,opsabove all/system/scheduler/printand/system/script/print: entries combiningfetchwith/poll/URLs andimport(the observed persistence pattern)/ip socks printand/ip proxy print: proxies nobody turned on/interface wireguard printand tunnel interfaces: unexpected egress/system/device-mode/print:flagged: yesmeans MikroTik’s own compromise scanner fired/system history print: configuration changes carrying assh:-2@<ip>trace. History survives a wiped or rolled log, so a-2trace attached to a config action is a confirmed compromise unless it was your own authorized test/file print: unexpected.rscdrops orautosupout.rifcrash files/system/logging print: logging actions tampered with or disabled
Run this checklist on every exposed device, including the boring ones, and work it retroactively: a hit on September 2 counts as much as a hit today. The devices that deserve the hardest look are the quiet ones. A router whose logs rolled over or went silent right around September 2 is not a clean router.
If you find a hit. Reconstruct the
session from the ssh:-2@<ip> records, then diff the device’s configuration
against its known-good state to list every change the session made: users,
keys, scripts, schedulers, services, firewall rules, proxies, tunnels. Then
walk outward: what could the router reach? If the device is the switch
fabric of a local AI cluster, the honest
answer is every node, every model, and every dataset on that fabric. Which
secrets lived on it (RADIUS shared secrets, VPN and WireGuard keys, SNMP
communities, stored credentials), and therefore what else must be treated as
exposed and rotated? A compromised router is a pivot point; the blast
radius follows your topology, not the device.
None of these steps is exotic; the hard part is doing all of them, on every device, while the next advisory is already landing.
The uncomfortable symmetry
Both sides of this story ran agents. CERT Polska used models to find the vulnerabilities; attackers chained them within days of the patches revealing them, and possibly even before.
The same agentic technique that shortens an attacker’s road to exploit let a defense team find six exploitable bugs in one sweep, coordinate disclosure, and get fixes shipped across every maintained RouterOS branch in a single drop.
What separated the two outcomes in our reproduction was the loop: an agent that can boot the vulnerable router, throw candidate primitives at it, and read what the device answers back converges in an afternoon; a prompt does not. Exploit development now costs an afternoon of agent compute where a specialist’s calendar used to measure it in weeks.
Where defense has to go from here
The old loop lost because every step of the response was gated on a human: somebody had to read the advisory, somebody had to work out which devices were exposed, somebody had to pull the logs. Not one step on the attacker’s side was. Models found the bugs, a patch diff yielded a working exploit in an afternoon, and exploitation started before most teams had seen the bulletin. Hiring faster readers does not fix that asymmetry.
The defensive version of the same loop exists in pieces today: agents that watch disclosure feeds and vendor bulletins continuously and structure what lands; a living inventory of what you actually run, so “which devices are exposed” is a query instead of a census; hunts that fire the moment indicators exist and reach backward to the start of a campaign instead of forward from the day someone reads the news; investigation that reconstructs the session, diffs the configuration, and scopes the blast radius while the evidence is still fresh, all of it continuous, all of it at machine tempo.
Defense is evolving this way because no other posture matches the speed the other side already operates at.
Remediation
If you run MikroTik anywhere: update to 7.24.2, 7.23.4, 6.49.21 or
later, check
for the indicators above, and if the flagged marker or an ops account shows
up, treat the device as compromised and rotate every credential it held. Then
time that sentence against your entire fleet.
If you find a hit and want help scoping it, talk to us or reach
Matt directly at matt 0x40 tolmo 0x2e com.
Appendix: IoC table
| Indicator | Type | Where to look | Meaning |
|---|---|---|---|
login failure for user -2 from <ip> via ssh | log pattern | /log print, syslog | -2 chain attempt |
user -2 logged in from <ip> via ssh | log pattern | /log print, syslog | successful -2 session |
user ops added by ssh:-2@<ip> | log pattern | /log print, syslog | post-exploit persistence |
signature verification failed for user: <name> | log pattern | /log print, syslog | SSH key forgery probing |
auth timeout (burst) | log pattern | /log print, syslog | pre-auth rekey abuse |
82.192.72.4 | IP address | any log, firewall | observed attack source |
103.102.31.18 | IP address | any log, firewall | attempted exploitation |
mythtime.xyz, leappoach.info, eeongous.com | domains | DNS, fetch, scheduler | campaign infrastructure |
account ops in group full | config state | /user print | persistence account |
config change with ssh:-2@<ip> trace | config state | /system history print | confirmed compromise |
scheduler/script entries with fetch + /poll/ + import | config state | /system/scheduler/print | callback persistence |
| SOCKS or proxy unexpectedly enabled | config state | /ip socks print, /ip proxy print | traffic relay |
flagged: yes | device mode | /system/device-mode/print | vendor compromise marker |
unexpected autosupout.rif | file | /file print | service crash during exploitation |
cc1113c8d530a17dc32729aeab429a5a6c811dddac99c2282c03760941cc5e85 | SHA-256 | staging infra, dropped files | busybox-mips payload, byte-identical to the official BusyBox 1.16.1 build |
6e95f70fdbabb57881b3f5b2c8465d4b17ba901100704efb1278bb3386e6729d | SHA-256 | staging infra | ftpsrv.py payload server |
972b474b896f9fac3cd6b5b8476b410b8f39fbedee8a3b0c745d6e3b328d7dcd | SHA-256 | staging infra | launch.sh |
6dca83338d60467b65b7789d4d59754e40a7aaa36f40ea2da57538367ac9b89e | SHA-256 | staging infra | serve.py |
A device matching any one of these is an incident. A device matching none of them is not proven clean.

