Process Migration and Evasion

LinuxBeginner
Practice Now

Introduction

In this lab, you will learn how attackers maintain persistent access and evade basic detection. While automated frameworks like Metasploit use Meterpreter to seamlessly migrate payloads into stable Windows processes (such as explorer.exe or svchost), Linux environments require a different approach.

The general principle is platform-independent: attackers prefer to hide inside long-lived, ordinary-looking execution contexts instead of unstable or obviously suspicious ones.

In Linux, attackers achieve the exact same evasion goals by identifying stable system processes and using "Process Name Spoofing" to disguise their malicious payloads. You will learn how to perform reconnaissance on running processes, identify trusted system components, and execute a payload that masquerades as a legitimate kernel thread to evade detection.

This is partly about stability and partly about human perception. Defenders looking at large process lists are more likely to overlook names that blend into expected system noise.

View Running Processes (ps)

In this step, you will learn how to list and analyze running processes on a Linux system. Attackers use this reconnaissance phase to understand the environment and find legitimate processes they can impersonate.

Again, enumeration comes first. You cannot choose a believable camouflage process if you do not know what "normal" looks like on the host.

The ps (process status) command is the standard tool for viewing active processes. To get a comprehensive view of all processes running on the system, you can use the aux flags.

Run the following command in your terminal to view the running processes:

ps aux | head -n 15

The a flag shows processes for all users, u displays the user-oriented format (including CPU and memory usage), and x shows processes not attached to a terminal. We pipe the output to head -n 15 to only show the first 15 lines, keeping the output manageable.

You should see an output similar to this:

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1 167008 11468 ?        Ss   10:00   0:01 /sbin/init
root           2  0.0  0.0      0     0 ?        S    10:00   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   10:00   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   10:00   0:00 [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I<   10:00   0:00 [slub_flushwq]
root           6  0.0  0.0      0     0 ?        I<   10:00   0:00 [netns]
root           8  0.0  0.0      0     0 ?        I<   10:00   0:00 [kworker/0:0H-events_highpri]
root          10  0.0  0.0      0     0 ?        I<   10:00   0:00 [mm_percpu_wq]
root          11  0.0  0.0      0     0 ?        S    10:00   0:00 [rcu_tasks_rude_]
root          12  0.0  0.0      0     0 ?        S    10:00   0:00 [rcu_tasks_trace]
root          13  0.0  0.0      0     0 ?        S    10:00   0:00 [ksoftirqd/0]
root          14  0.0  0.0      0     0 ?        I    10:00   0:00 [rcu_sched]
root          15  0.0  0.0      0     0 ?        S    10:00   0:00 [migration/0]
root          16  0.0  0.0      0     0 ?        S    10:00   0:00 [idle_inject/0]

Notice the processes enclosed in square brackets, such as [kthreadd] or [kworker/0:0H-events_highpri]. These are kernel threads. They are highly stable, run continuously, and are rarely inspected by system administrators, making them perfect candidates for evasion.

Identify Stable Target Processes

In this step, you will identify specific processes that are ideal for evasion. A stable process is typically a system daemon or desktop service that starts automatically and keeps running for a long time.

If an attacker's payload crashes, they lose access. By disguising their payload as a stable process, they avoid raising suspicion. In some Linux environments, kworker entries are easy to observe and make a convenient naming model because their names look technical and blend into long process lists.

Let's check whether this environment shows any kworker-style names. Run the following command:

ps -ef | grep kworker | head -n 5

The -e flag selects all processes, and -f does full-format listing. We use grep to filter only the lines containing "kworker".

If the environment exposes kernel worker entries, you may see output similar to this:

root           8       2  0 10:00 ?        00:00:00 [kworker/0:0H-events_highpri]
root          25       2  0 10:00 ?        00:00:00 [kworker/1:0H-events_highpri]
root          31       2  0 10:00 ?        00:00:00 [kworker/2:0H-events_highpri]
root          37       2  0 10:00 ?        00:00:00 [kworker/3:0H-events_highpri]
root          43       2  0 10:00 ?        00:00:00 [kworker/0:1-events]

If you only see the grep command and no real kworker entries, that is acceptable in this lab environment. We will still use the familiar [kworker/X:Y] naming style in the next step because the goal is to learn how process name spoofing works, not to rely on a specific kernel thread being visible.

Migrate to a Stable Process

In this step, you will simulate process migration by launching a long-running process and spoofing its process name.

A dummy payload named malicious_payload.sh has been prepared for you in ~/project, but there is an important Linux detail here. When you run a shell script, the process list usually shows the interpreter, such as /bin/bash /home/labex/project/malicious_payload.sh. That behavior makes the spoofed name difficult to observe clearly in this environment.

To make the spoofing easy to verify, we will use a simple long-running command instead. The security concept stays the same: we are giving a process a misleading visible name so it blends into the process list.

Execute the following command to launch a disguised background process:

bash -c 'exec -a "[kworker/u4:2]" sleep 600' &

The bash -c part starts a new Bash process and runs the command string that follows. exec -a "[kworker/u4:2]" replaces that Bash process with sleep 600, but tells the operating system to display the process name as [kworker/u4:2]. The sleep 600 command keeps the process alive long enough for you to inspect it. The trailing & runs the process in the background.

You will see a small output indicating the background job number and the Process ID (PID), similar to:

[1] 1337

Your disguised process is now running silently in the background and should appear with the spoofed name.

Verify Persistence and Access

In this final step, you will verify that your disguised process is visible under its spoofed identity and then clean it up.

Search for the spoofed name you assigned in the previous step:

ps aux | grep "kworker/u4:2"

You should see an output similar to this:

labex       1337  0.0  0.0   7008  1536 pts/0    S    10:15   0:00 [kworker/u4:2]
labex       1345  0.0  0.0   6480  2272 pts/0    S+   10:16   0:00 grep --color=auto kworker/u4:2

In this environment, the disguised process is only a demonstration created with sleep, not a real kernel worker. The important point is that the visible name in the process list now looks like a trusted system component.

Finally, clean up the demonstration process by terminating the command line that contains the spoofed name. Run the following command:

pkill -f "kworker/u4:2"

You can run ps aux | grep "kworker/u4:2" one more time to confirm the disguised process has been successfully terminated.

Summary

Congratulations! You have successfully completed the Process Migration and Evasion lab.

You have learned how attackers analyze running processes to identify stable, trusted system components. You also learned how to use process name spoofing (exec -a) to disguise a malicious payload as a legitimate kernel thread, effectively simulating the evasion techniques used by advanced frameworks like Meterpreter. Finally, you verified the stealthiness of the spoofed process and learned how to properly terminate it. These skills are essential for understanding how persistent threats hide within a Linux environment.