Introduction
Gabriel Landau released a post on
Elastic Security here which talks about a technique through which antivirus
evasion was found to be possible. The technique deals with creating a ghost
process which is a term used by the author to describe the mechanism of
deleting the payload from the disk before running it, essentially making it a
ghost.
Table of Content
·
Process Creation and Security Gap
·
Executables, Processes, and Threads
·
Creation of Process
·
Process Ghosting
·
Process Ghosting demo using SharpGhosting
·
Conclusion
Process Creation and Security Gap
In Windows ecosystem, anti-virus
solution developers call APIs (like PsSetCreateProcessNotifyRoutineEx) that can
intimate their AV solution about the execution of a particular process,
however, the callbacks are not sent when the process executes, rather when the
first thread within that process is executed. Hence, this gap between the
creation of process and sending of notification of their creation to the
anti-virus solution is where attackers can implement process ghosting.
Executables, Processes, and Threads
An executable is that
compiled file which contains the program that is to be run by the machine.
Executables can have multiple functions to be performed and when each of these
functions are run, it is called a process.
A process, in the simplest terms, is an executing
program. Each process is linked to a specific PE (exe, dll
etc). There can also be multiple processes from a single executable. This can
be viewed in task manager -> details.
A thread is the basic unit
of a process to which the OS allocates processor time. A thread can execute any
part of the process code. Multiple threads exist in a process. Multi-threading
means multiple threads running the same part of the process code. Windows
supports multi-tasking thus as many threads can be created as many processors
are available to run them simultaneously. It can have three states: running,
ready and blocked.
Creation of Process
A process can be created in
Windows using CreateProcess or NtCreateUserProcess function. This
function is a combination of individually modifyable other functions that can
operate on handles, section images, threads etc.
For example, CreateProcess
(lpApplicationName) defines which application to execute.
Process Ghosting
Now that we have covered basics,
let’s understand how process ghosting works. It is a technique in which an
attacker creates a file (malware), mark it for deletion (delete-pending state),
copies/maps a malware into the memory (image section), close the handle (which deletes
it from the disk), then create a process from the now-fileless section. Before
understanding the attack we must know the following:
·
Handles: Used for memory management, these are references to
a resource in kernel space. These not only hold the information about a
resource but also provides access rights.
int
fh = open("/etc/passwd", O_RDWR);
fh is a file
handle. When we opened a file using open() function it returned a handle to
variable fh. Now fh can be used to perform functions on the file like:
fh.read()
fh.append()
fh.close()
And also, a file
being accessed by fh can’t be read, written in or executed by any other handle
(or by any other process). fh.close() will close the handle to the file, i.e,
file won’t be accessed.
·
Image Section: A section is the mapping of a file into memory.
An image section is a special type of section that corresponds to Portable
Executable (PE) files, and can only be created from PE (EXE, DLL, etc) files.
·
Delete_Pending
State: Like read, write, delete state
that may exist for a file, Delete_Pending is a state in which a file is yet to
be deleted. The file is not deleted yet because a handle may have kept it
opened. As soon as the handle will close, the file will be deleted. No other
process can operate on this file in Delete_Pending state.
Thus, the entire Process
Ghosting flow looks like:
1.
Step 1: Create a file using NtCreateFile() function. This
would create our intended malware. Also, would give us a file handle. like: hFile
= NtCreateFile(C:\Users\a_cha\Desktop\random.exe)
hFile is the
handle for this file
2.
Step 2: Put the file in a delete_pending state. This can be done using NtSetInformationFile() function. By using FileDispositionInformation
flag, file will be put in a delete pending state. We can use hFile to perform this
task on our file.
3.
Step 3: Write the payload (malware) to this newly created
file. Since the file is in delete_pending state, as soon as it closes, the data
will vanish. But we’ll perform Step 4 before it vanishes!
4.
Step 4: Image section of the file is created using function NtCreateSection(hFile,
SEC_IMAGE). It can be done like: hSection = NtCreateSection(hFile, SEC_IMAGE).
This is why our handle was needed, as NtCreateSection() takes in file handle as
input. Now we can delete our handle safely.
5.
Step 5: Delete our newly created handle. This would also
delete our corresponding file (malware) from the disk, however, a copy of it
still exists in the image section.
6.
Step 6: Create a new process from the image section. As the
code exists in virtual memory, new process can be created using NtCreateProcessEx(hSection) function. It
will be done like hProcess = NtCreateProcessEx(hSection)
7.
Step 7: Assign process arguments and environment variables.
This is important as without process arguments and environment variables, OS
won’t execute the process and the code stays in suspended state.
8.
Step 8: Create a thread to execute in the process. Can be
done using CreateThread() function and supplying starting address of the
process to be executed.
Anti-Virus callbacks are invoked
and the file blocked as soon as the thread is created for the malware’s
execution. Since, the thread is created after the file is deleted, anti-virus
callbacks will never be invoked. Any attempts by anti-virus to open this file
will throw STATUS_FILE_DELETED error.
IkerSaint created a proof of
concept for process ghosting attack called “KingHamlet” which can be downloaded
here. This tool first encrypts the file and then perform
the attack. Let’s run a quick demo and see how process ghosting works.
Process Ghosting demo using SharpGhosting
Based on the methodology
explained above, many POCs have come onto the surface since Gabriel’s post on
Elastic Security. In this demo, we will be using a C# implementation of Process
Ghosting developed by Wra7h. Before you try it, it is essential that you have
an older Windows 10 version as Microsoft patched defender detection after this
technique came onto the surface. If you are pentesting and find an older
Windows 10, well you know what to do!
You can read the code on github
repo here.
You can compile this source code
using the following command:
C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe
/out:SharpGhost.exe /unsafe C:\ProcessGhosting\SharpGhosting-main\*.cs
Feel free to change the path as you
please. Also, you’d need .NET framework v3.5 to compile it yourself
To make things simple and save
you the hassle of compilation, I have forked the repo and created an EXE for
you, which can be downloaded here. Once you have downloaded the file, we can continue
with our demo. As you can see, we have defender active and working.
Now, we can launch our ghost
process using the following command:
.\SharpGhost.exe
-real <path>\name.exe
Here, I am launching mimikatz
instance which is detected as a malware by any anti-virus solution imaginable.
The aim is to bypass anti-virus detection during run time.
.\SharpGhost.exe
-real C:\ProcessGhosting\mimikatz.exe
And this command would launch
mimikatz as a ghost process. You can open the Task Manager and go to details to
see a ghost process running. This process has no name because the related EXE
does not exist.
As you can see, defender has not
detected mimikatz as a malware while it is run. This is because when AV
callbacks are invoked and the file blocked as soon as the thread is created for
the malware’s execution. Since, the thread is created after the file is
deleted, anti-virus callbacks will never be invoked.
Conclusion
The article covered an easy to
comprehend theoretical explanation of the nitty-gritty and various coding
functions used while launching Process Ghosting PE injection attacks. Soon
after this technique was released, Microsoft rolled out patches to fix this
issue. This no longer works in latest windows 10 and windows 11, however, older
windows 10 is still being used in organizations and home systems and a smart
attacker can take advantage of this. Hence, one must always keep their systems updated
and latest patch installed in their systems. Hope you liked the article.
Subscribe to the blog to receive daily updates and thanks for reading.
0 comments:
Post a Comment