Back to Intelligence

TeamPCP Redis Attacks Since 2020: Detection and Hardening Guide for Internet-Exposed Redis Infrastructure

SA
Security Arsenal Team
August 7, 2026
10 min read

New analysis has extended the operational history of the threat actor tracked as TeamPCP back to 2020, revealing that the group spent years compromising internet-facing infrastructure — with Redis servers as a primary target — before pivoting to the software supply chain campaigns that put them on most defenders' radar. The linkage is supported by overlapping domains, consistent malware deployment paths, staging techniques, and shared backend infrastructure spanning both eras of activity.

This matters for defenders for two reasons. First, TeamPCP is not a new actor riding a supply chain fad — they are a mature operation with years of infrastructure-compromise tradecraft, which means their supply chain intrusions are backed by hardened operational security and established staging pipelines. Second, the same weaknesses that made Redis servers attractive to them in 2020 — unauthenticated internet exposure, default configurations, and dangerous administrative commands left enabled — are still widespread in 2026. If your organization runs Redis, container registries, or CI/CD tooling, this actor's TTPs are directly relevant to your threat model.

Technical Analysis

Threat Actor Profile

TeamPCP's evolution follows a pattern we have seen repeatedly in IR engagements: actors who cut their teeth on opportunistic infrastructure compromise (cryptojacking, botnet recruitment, data theft from misconfigured services) accumulate staging infrastructure, payload delivery pipelines, and monetization channels. That mature apparatus then gets repurposed for higher-value operations — in TeamPCP's case, supply chain campaigns targeting developer tooling and package ecosystems.

The 2020-era Redis activity attributed to TeamPCP aligns with the classic exposed-Redis playbook, which remains depressingly effective:

  1. Discovery: Mass scanning of the internet for TCP/6379 (and 6380) accepting unauthenticated connections. A PING returning +PONG confirms an open instance.
  2. Abuse of administrative commands: With no authentication required, attackers use Redis's own command surface against the host:
    • CONFIG SET dir / CONFIG SET dbfilename combined with SAVE to write attacker-controlled content to arbitrary files writable by the Redis process — classically /var/spool/cron/crontabs/<user> for cron-based execution or ~/.ssh/authorized_keys for persistent SSH access.
    • SLAVEOF / REPLICAOF to point the victim at an attacker-controlled master, enabling full-sync delivery of malicious content or malicious modules.
    • MODULE LOAD to load a malicious .so file, achieving arbitrary native code execution inside the Redis process.
  3. Payload staging: Post-exploitation, shells spawned from the Redis context retrieve second-stage tooling — miners, scanners, lateral movement kits, and in TeamPCP's later operations, the same staging infrastructure later reused for supply chain payload delivery.
  4. Persistence: Cron entries, injected SSH keys, and — in containerized environments — escape attempts via mounted host paths or overly permissive service accounts.

Why the 2020-to-Supply-Chain Arc Matters Defensively

The infrastructure overlap is the key defensive signal. Domains and staging paths used in the early Redis campaigns were later observed delivering payloads in TeamPCP's supply chain operations. That means:

  • Historical telemetry has value. If you have long-retention DNS, proxy, or netflow logs, retro-hunting against TeamPCP-associated infrastructure can reveal compromises that predate your current detections by years.
  • An exposed Redis server is a beachhead, not an endpoint. An actor with supply chain ambitions who lands on your Redis host is not there to mine Monero — they are mapping your build systems, developer credentials, and artifact signing paths.
  • The group's operational longevity implies disciplined infrastructure hygiene. Expect fast flux, domain rotation, and payload paths that change between campaigns. Behavioral detection (Redis spawning shells, cron writes, module loads) is far more durable than IOC matching.

Exploitation Status

Unauthenticated Redis exploitation is actively exploited in the wild and has been continuously since at least 2018. Shodan and Censys continue to show tens of thousands of internet-exposed Redis instances. TeamPCP's confirmed operational window (2020–present, per the analysis) means this is not a theoretical exposure — it is an actively monetized attack surface used by a proven, persistent actor.

Detection & Response

The detections below target the durable behaviors in TeamPCP's Redis playbook: Redis spawning child processes, filesystem writes to persistence locations, replication/module abuse, and suspicious outbound connections from cache-tier hosts.

YAML
---
title: Redis Process Spawning Shell or Downloader
description: Detects redis-server (or its container equivalent) spawning shells, downloaders, or script interpreters — a hallmark of exposed-Redis exploitation chains including TeamPCP's campaigns.
references:
  - https://thehackernews.com/2026/08/teampcp-linked-to-redis-attacks-dating.html
  - https://attack.mitre.org/techniques/T1190/
  - https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/08/10
tags:
  - attack.initial_access
  - attack.t1190
  - attack.execution
  - attack.t1059.004
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/redis-server'
      - '/redis-server *'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/curl'
      - '/wget'
      - '/python'
      - '/python3'
      - '/perl'
      - '/nc'
      - '/ncat'
      - '/base64'
  condition: selection_parent and selection_child
falsepositives:
  - Redis health-check or orchestration scripts that legitimately exec helpers (rare; tune per environment)
level: critical
---
title: Redis Service Account Writing to Persistence Locations
description: Detects the redis user (or redis process context) writing to cron directories or SSH authorized_keys files — the classic CONFIG SET dir/dbfilename + SAVE persistence technique used against exposed Redis.
references:
  - https://thehackernews.com/2026/08/teampcp-linked-to-redis-attacks-dating.html
  - https://attack.mitre.org/techniques/T1053.003/
  - https://attack.mitre.org/techniques/T1098.004/
author: Security Arsenal
date: 2026/08/10
tags:
  - attack.persistence
  - attack.t1053.003
  - attack.t1098.004
logsource:
  category: file_event
  product: linux
detection:
  selection_paths:
    TargetFilename|contains:
      - '/var/spool/cron/'
      - '/etc/cron.d/'
      - '/etc/crontab'
      - '/.ssh/authorized_keys'
  selection_user:
    User:
      - 'redis'
  condition: selection_paths and selection_user
falsepositives:
  - Redis persistence (RDB/AOF) writes to its own data directory only — legitimate Redis file writes should never target cron or .ssh paths
level: critical
---
title: Redis Replication or Module Load Commands on Linux Host
description: Detects evidence of SLAVEOF/REPLICAOF or MODULE LOAD abuse in audit or command telemetry, indicating an attacker is weaponizing Redis replication or loading malicious native modules.
references:
  - https://thehackernews.com/2026/08/teampcp-linked-to-redis-attacks-dating.html
  - https://attack.mitre.org/techniques/T1505/
  - https://attack.mitre.org/techniques/T1105/
author: Security Arsenal
date: 2026/08/10
tags:
  - attack.persistence
  - attack.t1505
  - attack.command_and_control
  - attack.t1105
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    CommandLine|contains:
      - 'MODULE LOAD'
      - 'module load /'
      - 'SLAVEOF '
      - 'REPLICAOF '
      - 'CONFIG SET dir'
      - 'CONFIG SET dbfilename'
  filter_cli_admin:
    Image|endswith:
      - '/redis-cli'
    User|contains:
      - 'sre-'
      - 'dba-'
  condition: selection and not filter_cli_admin
falsepositives:
  - Legitimate replication setup during cluster provisioning (filter on known admin accounts and maintenance windows)
level: high
KQL — Microsoft Sentinel / Defender
// Hunt for exposed-Redis exploitation behavior via Syslog/CEF ingestion in Sentinel
// Targets: redis spawning shells/downloaders, cron/SSH persistence writes, and egress from cache-tier hosts
let Lookback = 14d;
let RedisChildren = dynamic(["/bin/sh", "/bin/bash", "/usr/bin/curl", "/usr/bin/wget", "/usr/bin/python3", "/bin/nc", "/usr/bin/base64"]);
union isfuzzy=true
    (Syslog
    | where TimeGenerated > ago(Lookback)
    | where ProcessName has_any ("redis-server")
        or SyslogMessage has_any ("MODULE LOAD", "SLAVEOF", "REPLICAOF", "CONFIG SET dbfilename", "authorized_keys", "/var/spool/cron")
    | project TimeGenerated, Computer, ProcessName, SyslogMessage, SeverityLevel),
    (DeviceProcessEvents
    | where TimeGenerated > ago(Lookback)
    | where InitiatingProcessFileName has "redis-server"
    | where FileName in~ ("sh", "bash", "curl", "wget", "python3", "nc", "ncat", "perl", "base64")
    | project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, AccountName)
| sort by TimeGenerated desc
;
// Companion: unexpected outbound connections FROM Redis hosts to non-peer infrastructure
DeviceNetworkEvents
| where TimeGenerated > ago(Lookback)
| where InitiatingProcessFileName has "redis-server"
| where RemotePort != 6379 and not(RemoteIP startswith "10.") and not(RemoteIP startswith "192.168.") and not(RemoteIP startswith "172.16.")
| summarize ConnectionCount = count(), DistinctDestinations = dcount(RemoteIP) by DeviceName, RemoteIP, RemotePort, InitiatingProcessCommandLine
| order by ConnectionCount desc
VQL — Velociraptor
-- TeamPCP-style exposed-Redis triage: enumerate Redis processes, their children,
-- persistence artifacts, and outbound connections on Linux endpoints
LET redis_procs = SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ 'redis' OR Exe =~ 'redis-server'

LET suspicious_children = SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE Ppid in (SELECT Pid FROM redis_procs)
  AND (Exe =~ '/(sh|bash|dash|curl|wget|python|perl|nc|ncat|base64)$'
       OR CommandLine =~ 'http://|https://|base64|chmod \+x')

LET cron_artifacts = SELECT FullPath, Mtime, Size,
       read_file(filename=FullPath, length=4096) AS ContentPreview
FROM glob(globs=['/var/spool/cron/crontabs/*', '/etc/cron.d/*', '/etc/crontab'])
WHERE ContentPreview =~ 'curl|wget|http://|base64|/tmp/|/dev/shm/'

LET ssh_keys = SELECT FullPath, Mtime, Size
FROM glob(globs=['/root/.ssh/authorized_keys', '/home/*/.ssh/authorized_keys'])
WHERE Mtime > now() - 1209600  -- modified in last 14 days

LET redis_netstat = SELECT Pid, Name, Status, "Laddr" AS LocalAddr, "Lport" AS LocalPort,
       "Raddr" AS RemoteAddr, "Rport" AS RemotePort
FROM netstat()
WHERE Name =~ 'redis' AND RemoteAddr != '127.0.0.1' AND Status = 'ESTABLISHED'

SELECT 'redis_process' AS FindingType, * FROM redis_procs
UNION ALL
SELECT 'suspicious_child' AS FindingType, * FROM suspicious_children

Remediation

There is no vendor patch for this threat — it is a configuration and exposure problem. Remediation is hardening and verification:

Immediate Actions

  1. Remove Redis from the internet. Bind Redis to loopback or a private interface (bind 127.0.0.1 / internal IP in redis.conf), and enforce it at the network layer with security groups/firewall rules. TCP/6379 should never be reachable from untrusted networks.
  2. Enable authentication. Set a strong requirepass (or use Redis 6+ ACLs with least-privilege users). ACLs also let you restrict dangerous commands per-user.
  3. Verify protected-mode yes is active (it is the default, but confirm it has not been disabled in container images or config templates).
  4. Disable dangerous commands via rename-command or ACLs: CONFIG, MODULE, SLAVEOF, REPLICAOF, DEBUG, SHUTDOWN, SAVE/BGSAVE where operationally feasible.
  5. Run Redis as a non-root user with a read-only data directory outside any cron, SSH, or web root path. Even if CONFIG SET dir is abused, there should be nowhere useful to write.

Verification and Forensic Sweep

Run the following on any host that has ever had Redis reachable from a non-routable interface it shouldn't have been:

Bash / Shell
#!/bin/bash
# TeamPCP / exposed-Redis compromise sweep + hardening verification
echo "=== [1] Is Redis bound to a public interface? ==="
ss -tlnp 2>/dev/null | grep -E ':(6379|6380)' || echo "No Redis listeners found"

echo "=== [2] Redis config: protected-mode, bind, requirepass, renamed commands ==="
redis-cli CONFIG GET protected-mode 2>/dev/null
redis-cli CONFIG GET bind 2>/dev/null
redis-cli CONFIG GET requirepass 2>/dev/null
redis-cli CONFIG GET rename-command 2>/dev/null
grep -E '^(bind|protected-mode|requirepass|rename-command)' /etc/redis/redis.conf /etc/redis.conf 2>/dev/null

echo "=== [3] Suspicious cron persistence (TeamPCP staging pattern) ==="
grep -rEl 'curl|wget|base64|/tmp/|/dev/shm/' /var/spool/cron/ /etc/cron.d/ /etc/crontab 2>/dev/null

echo "=== [4] Recently modified authorized_keys files ==="
find /root/.ssh /home/*/.ssh -name authorized_keys -mtime -30 -exec ls -la {} \; 2>/dev/null

echo "=== [5] Loaded Redis modules (should be empty or known-good) ==="
redis-cli MODULE LIST 2>/dev/null

echo "=== [6] Redis replication state (unexpected master = compromise indicator) ==="
redis-cli INFO replication 2>/dev/null | grep -E 'role|master_host|master_link_status'

echo "=== [7] Child processes of redis-server ==="
REDIS_PID=$(pgrep -x redis-server | head -1)
[ -n "$REDIS_PID" ] && ps --ppid "$REDIS_PID" -o pid,comm,args 2>/dev/null

echo "=== [8] Outbound connections from redis-server ==="
[ -n "$REDIS_PID" ] && lsof -p "$REDIS_PID" -i 2>/dev/null | grep -v '127.0.0.1\|::1'

echo "=== [9] Redis data dir contents (look for unexpected .so / dump payloads) ==="
REDIS_DIR=$(redis-cli CONFIG GET dir 2>/dev/null | tail -1)
ls -la "$REDIS_DIR" 2>/dev/null

Supply Chain Angle

Because TeamPCP progressed from infrastructure compromise to supply chain operations, apply the same scrutiny upstream: pin dependencies by hash, verify artifact signatures, restrict CI/CD runners' network egress, and audit GitHub Actions/third-party automation for unauthorized version bumps — the group's later campaigns abused exactly that trust path.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.