UIDs (User IDs) and GIDs (Group IDs) are integers that form the heart of the discretionary access control model for Linux. Each user is assigned a unique UID and each group is assigned a unique GID. Users can belong to any number of groups with memberships specified in /etc/group. Unless otherwise specified, Linux will also create a new group for each user that is identically named. Log in to the Kali VM and find your account's UID and GID via id.

id

By default, our account is provided access to the sudo command, allowing us to perform commands as the root account. One command we must perform as root is account creation. Using sudo, add a user account named myuser to the system using the useradd command. As part of the command's arguments, we specify the account's home directory in /home and configure bash as the shell.

sudo useradd -m -d /home/myuser -s /bin/bash myuser

After account creation, change the password of the created account.

sudo passwd myuser

Use the su command to switch to the user, entering in the password set above.

su - myuser

Then, examine the account's information using id.

id

By default, useradd assigns an available UID and creates a corresponding group for the user. Note that the account is a member of two groups with two different GIDs and that id indicates the default GID that will be used to create new files.

Finally, exit (Ctrl+d) out of the myuser account returning back into your own account.

A long listing provides information on the ownership and access control for a file or directory. In the listing below, the first field specifies the type of the file and its permissions (-rw-r--r--) with the third and fourth specifying the owner (wuchang) and the group (adm) of the file.

$ ls -ld .bashrc 
-rw-rw-r-- 1 wuchang adm 5551 Apr  9 22:15 .bashrc

Parsing the first field, the initial character (-) indicates a regular file, followed by 3 sets of bits specifying read-write-execute permissions for the user/owner of the file (rw-), for those belonging to the sudo group (rw-) and for any others wishing to access the file (r--). Permissions in Linux are often given as 3 integers from 0 to 7 specifying user, group, and other permissions with each integer representing the state of the 3 bits. In the example above, the permissions of the file would be "664".

Every process has a umask value that determines the default permissions of files or directories that are created by it. The value masks out (e.g. clears) bits of the permissions for a file or directory upon creation. It encodes the mask as 3 integers. For example, a umask value of 077 would ensure that only the owner would have access to any file that is created. Begin by obtaining the value of your shell's umask, creating a file and directory, and examining the resulting permissions before removing both.

umask
mkdir foo; touch foo/bar
ls -ld foo foo/bar
rm -r foo

We can change the umask value in the shell by giving it the integer mask as an argument (e.g. umask 077).

Calculate a umask value that allows full access to the owner, read and execute access to the group, and no access to others. Then, fill it in within the commands below and execute them.

umask <FMI>
mkdir foo; touch foo/bar
ls -ld foo foo/bar

Continue to the next step without deleting the files or logging out.

For files and directories that we own, chmod can be used to modify permissions. We can specify the permissions on a file directly using the 3 integers

We can also specify relative modifications using + and - and the names of the subject and the permission.

A common operation with chmod is to recursively change the permissions of all files in a given directory. The flag for doing so is -R. When performing recursive changes, however, you often want to make directories executable, but not regular files. Specifying the executable permission as an upper-case X does so. Perform a recursive chmod on the directory in the previous step to allow others to read foo/bar as well as read and execute foo.

chmod <FMI> foo
ls -ld foo foo/bar
rm -r foo

Continue to the next step without logging out.

Our user account belongs to several groups. However, when a new file is created, it can only be assigned to one group, the one that we are "logged into". The groups command lists all of the groups our account belongs to, with the first group returned being the one we're "logged into". Run the command below to find this information for your account.

groups

We can use the newgrp command to log into a different group instead. Use the commands below to change groups to adm then run groups again to see what has changed.

newgrp adm
groups

Finally, recreate the contents of foo, and see the difference.

newgrp adm
mkdir foo; touch foo/bar
ls -ld foo foo/bar

If we have already created a set of files and want to change their groups, we can use chgrp to do so (e.g. chgrp adm file.txt changes the group of file.txt to adm). As with chmod, chgrp can also be invoked recursively via -R to change the group of all files under a particular directory. Fill in the command below to change the group for all of the files back to the default group that was created for your account.

chgrp -R <FMI> foo
ls -ld foo foo/bar

Along with the standard permissions for read, write, and execute, there are "setuid" permissions that can be enabled for programs. These permissions allow one to escalate privileges to another user (setuid) or another group (setgid) for the duration of the execution of that program One command that has its setuid bit set is /usr/bin/passwd. A listing of its permissions is shown below:

$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 72424 Mar  3 14:41 /usr/bin/passwd

As the binary shows, anyone can read or execute this program. By virtue of the setuid bit being set on the user/owner's execution permissions, execution of the program is done with the privileges of the owner: the root or administrator account. As a result, it is imperative that the passwd program not have any flaws that would lead to code execution since this would enable complete access to the system as the administrator.

One of the most commonly used setuid programs is sudo. sudo allows anyone in the sudo group to execute arbitrary commands as the root account by entering in their own password. Create two files: one using sudo and one without.

touch sudo1; sudo touch sudo2
ls -l sudo1 sudo2

Then, delete the files. Because one of them is owned by root, you will need to use sudo to remove it.

sudo rm sudo1 sudo2

If an adversary happened to compromise an account that was a member of the sudo group, they would typically use this to exfiltrate sensitive files or to plant malicious ones on the system. One such file would be /etc/shadow: a file containing the password hashes of all of the user accounts. List the file and attempt to dump its contents.

ls -l /etc/shadow
cat /etc/shadow

Similar to chmod and chgrp, one can change the owner and group of a file or directory with the command chown. Changing ownership of a file requires root privileges. Run the commands below to create files owned by the myuser account.

mkdir foo; touch foo/bar
sudo chown -R myuser foo
ls -ld foo foo/bar

Linux has several tools for working with processes that are useful when performing forensics on a machine that might be compromised. To begin with, use the w command to see the users that are logged on as well as information about their logins.

w

We can then use the tty command to identify the information of your current session.

tty

If the output of the tty command was /dev/pts/0, then we can search for all processes that have pts/0 opened. For clarity, the regular expression below can be used if our TTY is pts/0. It retains the first line of ps output that contains the column headings.

ps -ef | egrep "pts/0|PID"

From this output, find the process ID (PID) and the parent process ID (PPID) of the bash shell for our terminal.

The /proc file system gives us a file interface to the running processes of the system and their internal state. If an analyst identifies a suspicious process, they can examine its state via /proc. To show this, fill in the PID of your shell in the command below, then run it to list all of the file descriptors the bash process has open.

ls -l /proc/<PID>/fd

We can also examine the current working directory and the command-line of the bash process using the command below.

ls -l /proc/<PID>/{cwd,cmdline}

Finally, we can examine the state of the process by viewing its status.

less /proc/<PID>/status

Like family ancestry, processes in Linux form a tree rooted in Linux's initial process (with process ID of 1). To begin with, create the following bash script that spawns 4 sleep processes.

sleep.bash

#!/bin/bash
sleep 1000&
sleep 2000&
sleep 3000&
sleep 4000

Add execute permissions on the script, then execute the script and put it immediately in the background via the & shell operator.

chmod +x sleep.bash
./sleep.bash &

Note that if we forget to put the & at the end of the command to background the task, we can simply type Ctrl+z to send it a STOP signal, then type bg to resume it in the background.

When putting a process in the background, the PID of the process is returned. Take this PID, and look for it in the ps listing.

ps -ef | egrep <PID>

Type pstree to see the ancestry that explains the above. Make a note of where the 4 sleep commands are located.

pstree

Kill the sleep.bash process.

kill <PID>

Repeat the pstree listing

Perform a ps and search for the sleep processes.

ps -ef | egrep sleep

We can use the killall command to kill all processes with a particular name. Use killall to clean up all of the sleep processes.

killall sleep

In Linux, environment variables are used to configure a variety of behaviors in processes. The PATH environment variable in particular determines where the shell looks when a user enters a command. The shell searches the PATH in order and executes the first version of the command that it finds.

To begin with, show the current setting for PATH, find out where in the path the shell currently gets the ls command from, and finally find the file type of the command. Then, create a backdoor.sh file in /etc/cron.daily. Show it in a listing of the directory.

echo $PATH
which ls
file <PATH_TO_LS>
touch /etc/cron.daily/backdoor.sh
ls /etc/cron.daily

One sneaky way to trick a victim into executing a trojan command is to add an attacker-controlled directory to the beginning of the PATH and place the trojan versions of the commands within it. Another sneaky way is to place a trojan version of the command earlier in the user's existing PATH. We can do the latter for the ls command by placing a bash script called ls in /usr/local/sbin that calls the original ls with the "--hide" flag to skip all files named backdoor.sh. To avoid confusing ourselves, we'll also output a message letting us know we're using the tampered version. Fill in your OdinID in the script below and create the file.

/usr/local/sbin/ls

#!/bin/bash
echo "OWNED by <OdinID>"
/bin/ls --hide "backdoor.sh" $@

Then, change its permissions so that it is executable and ensure it is picked up by the shell as the "new" ls.

chmod +x /usr/local/sbin/ls
which ls

bash typically creates a hash table of command locations when a user logs in. Unless we logout and log back in, we'll also need to recalculate bash's PATH hash table to pick the command up. Log out of the VM or recalculate the hash manually.

hash -r

Then, list /etc/cron.daily again.

ls /etc/cron.daily

Because ssh is typically used to access machines remotely, it is one of the most heavily attacked. One of the most common techniques against it is ssh brute-forcing where an adversary uses libraries of compromised username and password combinations in order to attempt to log into the service.

The sshd server handles incoming ssh sessions. There are two important settings for an sshd configuration to mitigate the impact of such an attack. The first setting is whether sshd allows remote logins to the root account. Access to root privileges should typically be done only via the sudo command from an unprivileged account to help track and attribute the execution of privileged commands. The second is whether the VM allows one to login from a remote location using the traditional username and password as credentials. Because weak passwords are so prevalent, allowing this opens up the machine to brute-forcing. The more-secure alternative would be to only allow ssh login via ssh keys.

Begin by examining the man pages for sshd on the Kali VM. Find the location of the configuration file for sshd. Then, examine the configuration file.

Join the following room on TryHackMe: https://tryhackme.com/r/room/linuxprocessanalysis. The room walks you through an investigation of a compromised Linux machine, allowing you to practice applying Linux concepts such as processes, cron jobs, services, and system/user auto-start scripts as well as Linux commands such as ps, pstree, top, lsof, systemctl, and crontab.

Complete the exercise.