Analyzing Processes
Find detailed information about other running processes using the /proc folder and other tricks
/proc
/proc
This folder on a Linux system holds all the information about running processes. From their memory to their executable, or the files they have open. Every process has a unique Process ID (PID). In the /proc/[PID]
directory, you can find information specific to that certain process. Here are a few interesting files:
/proc/[PID]/cmdline
: Command line arguments passed to the program on startup (\x00
byte as separator)/proc/[PID]/exe
: A symbolic link to the executable file that was used to start the process/proc/[PID]/environ
: Environment variables for the process (\x00
byte as separator)/proc/[PID]/fd/
: A directory that contains symbolic links to the opened files of the process/proc/[PID]/maps
: Information about the memory mappings for the process, including the addresses and permissions of each mapping/proc/[PID]/mem
: A file representing the process's memory which should not be world-readable, only root and the owner of the process. Combined with themaps
file it can be used to obtain a full memory dump of the process (see Dump memory from /proc)
If you ls
the directory, you will find all the files and their permissions, these are just a few useful ones.
Dump memory from /proc
By combining the maps
and mem
files of a process, one can extract the loaded memory regions to find exactly what is in the memory of the program. This can be used to find secrets or anything that might be loaded in there. Using the following bash functions you can easily dump the memory of a process into the current directory (source):
After defining it like this, you can take a PID and dump it:
/proc/self
/proc/self
This is a special directory, that links to the current process's /proc
folder. If you don't know the PID for example, you can read any files in here like /proc/self/environ
to read it from the process that is executing the file read, without having to guess anything. But note that the Process IDs are very predictable, and can be brute-forced easily with a script to find all processes.
strace
strace
strace is a Linux tool that traces syscalls. You can attach it to a process, and it will print all the syscalls and their parameters that are being called when they happen. This can be incredibly insightful when reverse engineering what a process is doing, as you can interactively see calls that normally happen in the background.
Even better, you can also attach it to other processes just requiring a Process ID (PID). You just need permission to read the necessary files, which only the root user and owner of the process has. If a process is running as your user, but in another terminal you don't have access to for example, this can attach to the process and give you a lot of information.
For extracting useful information from these syscalls, you will often see arguments truncated to 32 characters by default. You can change this limitation using the -s
argument and provide a much larger maximum to get the full data.
/dev/pts
(terminals)
/dev/pts
(terminals)There are pseudo-terminals in the /dev/pts
directory, that you might see the TTY column of a ps
or w
command.
These can give you access to the input of the process, meaning you can read the input that is going through the terminal on the other side, as well as write your own into it.
Due to a race condition of both processes trying to read the same data at the same time, you might not receive all data, as only one can actually receive it
Send STDIN to TTY
Send accepted standard input to a TTY to influence the behavior, or maybe execute commands (source).
TTY Input Pushback (su
)
su
)When logging in as another user with su
, by default, the current pseudo-terminal is reused. This has the effect that the low-privileged user that is logged in to can send input to the TTY.
The trick we abuse is to background the current process programmatically, and then keep sending input to the TTY. After backgrounding the shell will be back to where it previously was: the original high-privileged shell that executed su
in the first place. The input we send will then end up in that higher-up shell thus allowing malicious commands to be written and executed.
In practice, you will create some code in ~/.bashrc
that will do these actions right as the admin or cron job tries to log into your account. Here is an example that creates and compiles a C program with a specific command:
If cc
or another compiler isn't available, try compiling it yourself on another comparable system with cc -static
to link libraries statically
When that payload is placed on the hacker
account for example, and the admin
user tries to log in using su hacker
, this payload executes in their terminal:
If sudo su [username]
was used, you can even reuse sudo
in your payload as the sudo token will still be valid (the timeout not requiring entering a password again)
More stealthy flow
In the above example, an administrator can clearly see that something is up, as the whole payload is shown directly in their screen, twice even. The history files keep this payload, and they can always check the .bashrc
file to find the payload.
To create a more realistic su
experience, the entered commands should be hidden and the sequence should actually end up in a hacker@machine
shell like the administrator expects. These two can both be done relatively easily by just editing the payload to include some more tricks:
Use
\x0C
characters to clear the screen after each command, hiding the processPrefix all commands with a
After backgrounding the process, use
fg
to get back to thehacker@machine
shellRun
clear
to completely clear all previous commands
Other tricks
A few more tricks that may be useful in some cases, highly specific to the type of processing that is running.
Backdoor ~/.bashrc
~/.bashrc
When a victim logs in as a user where you can write their .bashrc file, you can make them execute arbitrary commands before starting their shell (such as a reverse shell). To get a clean log of the STDIN, STDOUT and STDERR combined into one file as output you can use a command like this as the backdoor:
This command won't capture the STDIN of a password input for example, only what is displayed on the screen. If a user or an automated system tries to type into a hidden input like the sudo
prompt, you can try to capture all the input using the cat
command without any arguments:
Enable history files
Sometimes a machine will try to prevent a system from logging executed commands in the history file. In bash, the ~/.bash_history
file for example will contain all the commands executed in an interactive bash shell, which may contain sensitive information like passwords or other secrets.
These can be disabled by symlinking them to /dev/null
, but if we have permission, we can simply delete the history file to unlink the symlink. When the next command is then executed, it will find that there is no file anymore and just create a new one with the history.
This idea of resetting the ~/.bash_history
file may also work for other programs whose history file is symlinked to /dev/null
. This depends on the process, but some interactive ones have their own history file.
Last updated