Update: Read Part 2 Here.
"The wind does not act to deceive. Gravity and rust do not go 'low and slow’ to evade detection. Rain does not customize its raindrops to bypass umbrellas. But sentient attackers do change to evade defenses and reach their goal." Alex Hutton
A safe cracker has his tools: lock picks to open doors leading to the safe, gloves, balaclava, escape route and a time table. Tools are the key to a successful intrusion. They are also key to discovery of the intrusion if you know how to look for them and do so on a routine basis.
Similarly, a cyber attacker needs tools in order to access a computer inside your corporate network. The challenge is how to gain and maintain access to the inside without being discovered by perimeter network and endpoint detection controls. The wise attacker must look to establish redundant pathways knowing that the initial compromise could be discovered and taken off the network.
In fact, we are not talking about a single individual going after corporate data, rather teams of attackers working in concert against a set of target companies, often in a specific industry or vertical market.
In my first article in the series, I will be covering methods used to persist access on Windows, Linux and Mac computers. Follow up articles will cover the following:
At the start of an attack, at least one system inside a company is compromised and it's from there that they work to expand onto other systems. In years past the attack team would send a spear phish to a list of employees with an enticing subject that is within the area of responsibility for the audience being targeted. Now there is cooperation with botnet catalog operators that list and sell "seats" inside organizations. The risky intrusion work has already been done and they can just pay to access. That isn't to say the old school hacks have gone away. They haven't.
Once inside, there is a mixture of objectives for the attackers at this early stage:
Attackers are vulnerable to discovery in the early stages of the campaign before they have had the opportunity to mature their ability to start using your remote access infrastructure and thus remove or downgrade their use of backdoor Trojans as a primary means of access. Their goal is to remove the risky Trojans and blend in with and become virtually indistinguishable from your legitimate network users.
By watching for signs of this type of this early attack behavior you can take steps to impede them from progressing to stage 3 activities, including data theft and user account creation/manipulation. And they don't use exploits typically as they move to achieve this higher level of sophistication so endpoint antivirus isn't going to help. They will be using administrative tools in much the same way your admin staff does.
The more mature your remote access infrastructure and security controls are, the slower they will make progress toward their goals and the more time you have to detect behavioral indicators and purge them from your network.
After obtaining enough IDs and typable passwords to ensure redundancy whenever users change their passwords, they have to establish a means of capturing password changes so they can maintain access. They do this with the use of keyloggers installed in the most stealthy way possible. They could also use a tool to pull clear-text passwords from RAM if they have Administrative access to a computer on which the user account is used in a manner that caches the password.
Early stage persistence is typically done with registry modifications to run RAT tools as a hosted service and late stage tools are done with less noticeable piggyback module loading. The persistence options available are:
In this article I focus on the registry and how it can be used to configure backdoor Trojans for access.
Registry persistence has the following risks which have increased over the last few years since the media attention has alerted enterprise defenders and security vendors where to focus their attentions in order to find signs of remote access.
|Technique of persistence||Risk Assessment||Usage|
|HKLM\System\CurrentControlSet\Services||Runs as SYSTEM, very stealthy, safe||Used for long-term remote access in early stages and as backup access|
|HKLM\Software run keys||Runs as Administrator, less stealthy||Used for initial compromise|
|HKCU run keys||Early stage droppers & downloaders, noisy and dangerous||Initial exploit, day zero activity|
Attackers love Windows Services because they run under NT AUTHORITY\SYSTEM, which is the highest level of privileged account available permitting them to do almost anything they want on the system and bypasses UAC on Windows 7 and 8. Windows services come in two types: "Own Process" and "Share Process". Own Process services are implemented as stand-alone executables and exist in their own running process. Share Process are "hosted" by the Windows Service Host (svchost.exe) and are implemented as modules, also called Dynamic Link Libraries (DLLs).
Each of these service types is configures slightly differently in the registry under theHKLM\System\CurrentControlSet\services hive. But attackers have a much broader choice of other registry locations in which to hook their code. Just download and run Microsoft Sysinternals utility Autoruns to see the vast array of windows locations where code can be configured to launch automatically and yet remain relatively hidden away from being noticed by all but the most experience administrators.
The keys located here get loaded by the Service Controller at various times during the operation of the computer. Some are loaded at system startup and others are loaded on demand or when triggered by other events. The attackers want to load at startup so that even if no user logs in they can connect to the computer.
This is where the "Share Process" DLLs are configured to be loaded by the host process, SvcHost.exe. This has been the most common location for attackers to locate their remote access tools, often called "RATs" by response investigators. Because Windows ships with 136 hosted DLLs and a number of these are not in use they become locations that can be used to persist malicious code without breaking any existing services.
Here windows implements a sort of role-based access control (RBAC) by grouping services that have similar privilege needs. Services that don't access the network are listed in groups that don't have access to the network. Services that need unfettered access to the network are grouped together and called "netsvcs" as defined in the string array found here. Because RATs need access to the network they hide here, typically in an "empty parking space" as discussed next.
On Windows 7 there are 47 "service names" listed in the netsvcs group list. These "service names" function as pointers to service configurations in the CurrentControlSet\Services hive. On a fresh install of Windows 7 there are 14 of these that are listed in netsvcs but are not implemented under Services. These can be maliciously configured as a means of persistence (See FIGURE 1). To do this the attacker needs to have permission to modify the registry configuration to load their code and only administrator permissions are needed.
Each hosted service can have exactly one DLL listed in a subkey called ServiceDll. In order to load their code they would have to redirect an existing DLL to one of their own which would break the functionality provided by the real DLL and risk them being discovered. Therefore they attack the netsvcs service names that are not in use. This can be done by iterating the names found in the string array for the netsvcs group and testing to see if a key already exists under Services in the CurrentControlSet branch. It there isn't one found then it's a good candidate for using.
As an example, a Windows 7 installation doesn't have an IAS hive by default under Services (FIGURE 2), and since the string array for netsvcs does contain an entry for "Ias", this is a good candidate for using. NOTE: If your organization uses Microsoft Network Policy Server (NPS), then your registry will have the "Ias" settings being used legitimately.
Attackers know this is an opportunity for them to leverage the elevated privilege afforded by having their code launched by svchost.exe and the relative obscurity of having a genuine service name and a ServiceDLL with an almost identical name to the system DLL. FIGURE 3 shows the registry from an attacked machine. The IAS hive has been created by the attacker and populated with various configuration parameters, including the binary path in the ServiceDLL key. The ServiceDLL data type is REG_EXPAND_SZ, which means that environment variables can be used to allow for flexibility of installation. As a registry call requests a value like %SystemRoot%\System32\appinfo.dll, the Registry service will expand and return the correct drive letter for the system drive. Many Citrix server installations install the system on M:\ instead of C:\, so this technique ensures these type of modifications don't break registry configurations. Now notice in FIGURE 3 that our attacker has included the path explicitly. This is a clue that can only be seen by using Registry Editor. Queries using REG QUERY will return the value with the environment variables substituted.
FIGURE 1: The netsvcs hosted service names contained in the string array
FIGURE 2: The Services hive showing absence of IAS on a fresh Windows 7 installation
FIGURE 3: The Services hive with IAS added by an attacker and the subtle difference in DLL names
Notice the DLL name used by our attacker (FIGURE 3) is very close to the name of the real system DLL (inset), which makes detection much more difficult. The name difference is required so they can place their DLL in system32 alongside the genuine DLL and not cause more suspicion with having a service DLL running from a non-system location.
The Services hive contains configuration settings that control how and when services are loaded by the operating system. Take not that a RAT DLL that is configured to start as a service should be a hosted service and therefore a Type code of 0x02 but I've seen "DLLs" that are configured as Type 0x10.
FIGURE 4: Configuration Items For Hosted Service Entries
|0x0||Ignore||No warning displayed and start up proceeds (in the case of a driver failure during bootup).|
|0x1||Normal||Startup should proceed but a warning is displayed (driver)|
|0x0 (boot)||Kernel||Used by the boot loader to start the driver stack|
|0x1 (system)||I/O Subsystem||Drivers loaded during kernel init phase|
|0x2 (auto)||SCM||SCM starts these services automatically at startup|
|0x3 (demand)||SCM||SCM starts these upon demand|
|0x4 (disabled)||SCM||SCM will not start services configured this way|
|0x1||Kernel device driver|
|0x2||File system driver|
|0x4||Set of arguments for an adapter|
|0x10||Own Process service (EXE)|
|0x20||Share Process service (DLL)|
The AppInit_DLLs registry key has been around for a very long time (Windows NT and post Windows 95) and is a popular attack vector for persistence. It makes every process that executes load USER32.dll. Almost all processes load this DLL and this makes it a great means of loading malicious code.
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows"
|AppInit_DLLs||REG_SZ||Space and comma delimited list of system DLLs and paths to non-system DLLs to load with every executable launched in the logon session|
|LoadAppInit_DLLs||REG_DWORD||0x1 = use them (default); 0x0 = don't use them|
|RequireSignedAppInit_DLLs||REG_DWORD||0x0 = Load any DLLs; 0x1 = 0 Load only code-signed DLLs
Windows 7 allows non-signed DLLs by default for compatibility reasons so this value doesn't exist and must be created in Windows 7
Server 2008 and newer require signed DLLs by default and set this value to 0x1
"All the DLLs that are specified in this value are loaded by each Microsoft Windows-based application that is running in the current log on session. The AppInit DLLs are loaded by using the LoadLibrary() function during the DLL_PROCESS_ATTACH process of User32.dll. Therefore, executables that do not link with User32.dll do not load the AppInit DLLs. There are very few executables that do not link with User32.dll. " Microsoft TechNet
The AppInit_DLLs value is type "REG_SZ." This value has to specify a NULL-terminated string of DLLs that is delimited by spaces or by commas. Because spaces are used as delimiters, do not use long file names. The system does not recognize semicolons as delimiters for these DLLs. Microsoft TechNet
Note: All processes that load USER32.dll do so with the uppercase name and only the RPCSS image of svchost.exe (C:\Windows\system32\svchost.exe -k RPCSS) uses the lowercase name, user32.dll. On the filesystem, the name is lowercase.
In the second article I will cover the Run keys and Search Order Tricks
|Service Name||Path to DLL|