-
MSOffice Malware in Memory
-
Macros
-
Useful Win32 APIs
-
3 from Kernel32.dll
- VirtualAlloc
- RtlMoveMemory
- CreateThread
- Check MSDN Function Prototypes
-
Good To Know
-
LPDWORD
- (C) Pointer or Ref to a DWORD
-
LPSTR
- (C) Pointer to a String
-
Download Cradle + IEX
-
Powershell
- Win32 APIs
- (C#) DllImportAttribute
- C data types to C# data types translation
- P/Invoke APIs
- System namespace
- System.Runtime.InteropServices namespace
- www.pinvoke.net might help
- Add-Type
- RtlMoveMemory
- System.Runtime.InteropServices.Marshal
- .NET Copy
- Allows data to be copied from a managed array to an unmanaged memory pointer
- WaitSingleObject
- Artifacts
- CSC: C# Command Line Compiler
- List loaded assemblies
- Add-Type
- [appdomain]::currentdomain.getassemblies()
- In this case, could be flagged by antivirus
- Dynamic Lookup
- Add-Type
- System.dll
- Microsoft.Win32.UnsafeNativeMethods class
- GetModuleHandle
- GetProcAddress
- Create the .NET assembly in memory instead of writing code to disk and compiling it. These methods are only meant to be used internally by the .NET code. Therefore it's impossible to call them directly from Powershell or C#. - Check UnsafeNativeMethods branch -
- Create New Assemblies
- GetAssemblies
- ForEach-Object
- GetTypes
- Get-Member
- Static Flag
- Where-Object
- Unsafe Keyword in TypeName
- Search for preloaded assemblies that could match our criteria
- UnsafeNativeMethods
- Assembly filtering
- GlobalAssemblyCache
- Location
- List of all native and registered assemblies on Windows: this is what we want
- Last part of the file path must be “System.dll”
- Reference to System.dll
- GetType
- $dllvar.GetType('Microsoft.Win32.UnsafeNativeMethods')
- GetMethod
- Invoke
- GetMethod function to obtain a reference to the internal GetModuleHandle method
- Use the internal Invoke method to call GetModuleHandle and obtain the base address of an unmanaged DLL
- .NET Reflection
- GetMethods vs GetMethod
- GetProcAddress
- Locate GetProcAddress to resolve arbitrary APIs
- Delegate Type Reflection
- (C#) delegate
- Creation using Reflection
- Create New Assembly
- AssemblyName Class
- Access mode
- DefineDynamicAssembly
- System.Reflection.Emit.AssemblyBuilderAccess namespace - Value set to RUN
- Access mode configuration: no disk access and executable
- Creating Content
- DefineDynamicModule
- DefineType
- Custom Name
- Attributes
- Class
- Public
- Sealed
- AnsiClass
- AutoClass
- Check MS Doc
- MulticastDelegate class
- Inside an assembly the main building bloc is a Module
- DefineType takes 3 args
- Construct our Custom Delegate Type
- DefineConstructor
- MethodAttributes Enum
- [System.Reflection.CallingConventions]::Standard
- Types of the Constructor
- Constructor Call
- SetImplementationFlags
- Runtime
- Managed
- Invoke
- DefineMethod
- Method Name
- Method Attributes
- Return Type
- Array of Arg Types
- Takes 4 args
- MethodImplAttributes Enum
- Delegate Type Instantiation
- CreateType
- 2004 Blog post
- Generate Shellcode
- ps1 format
- 32bit architecture (cf. MS Office arch)
- Use of msfvenom (shortcut)
- Copy it with .NET Copy method
- Use System Proxy (optional)
- Natively not accessible in Powershell. Thank you .NET -> C#
- Invoke functions in unmanaged
dynamic link libraries
- Once translation done: use of the .NET framework to compile and create objects containing the structures, values, functions, or code inside the Add-Type statement
- Avoid Powershell termination before Shell fully executed.
- Be aware, closing MSOffice will kill the Shellcode - Check advanced attack with Powershell
-
Client Side Code Execution With Windows Script Host
-
Must Read
- TrickBot
- Emotet
-
Jscript
- DotNetToJscript
-
C#
-
Win32 APIs
-
C data types to C# data types translation
- pinvoke
-
dllImport
- System.Diagnostics namespace
- System.Runtime.InteropServices namespace
- Mandatory
-
Shellcode
-
dllImport
- VirtualAlloc
- CreateThread
- WaitForSingleObject
- Back Link To First Topic
- Back Link To First Topic
- Marshal.Copy
- Back Link To First Topic
-
Process Injection and Migration
-
Shellcode Home
- explorer.exe
- svchost.exe
- Or any other Process that is unlikely to Terminate
-
Win32 APIs
-
OpenProcess
- Security Descriptor
- Integrity level
- VirtualAllocEx
- WriteProcessMemory
- CreateRemoteThread
- Be aware of Security Permission when it comes to call OpenProcess
- Note the "Ex" - Stand for Expanded - Mandatory to reach any Process, under our control, outside the current Process
-
Build the Injection
-
pinvoke
-
Opening the Channel
- System.Runtime.InteropServices namespace
- OpenProcess Args
- dwDesiredAccess
- bInheritHandle
- dwProcessId
- Targeted Access Rights
- Created child process can inherit this handle (y/n)
- Process ID of the Shellcode Home
-
Allocating Memory
- VirtualAllocEx Args
- hProcess
- lpAddress
- (dwSize, flAllocationType, flProtect)
- Handle to the process obtained from OpenProcess
- Address of the allocation in the remote process
- Mirror the VirtualAlloc API
-
WriteProcessMemory
- hProcess
- lpBaseAddress
- lpBuffer
- nSize
- lpNumberOfBytesWritten
- Shellcode/Malicious Program
- Size of the Shellcode/Mal
- Pointer to a location in memory to output how much data was copied. - arg prepended by the "out" keyword
-
Executing the Shellcode
- CreateRemoteThread
- hProcess
- lpThreadAttributes
- dwStackSize
- lpStartAddress
- lpParameter
- dwCreationFlags
- lpThreadId
- = address of the buffer allocated for our Shellcode
- Parameters of our Shellcode if required
- Ignore this
- Allowed stack size: set it to 0 to accept default value
-
DLL Injection
-
Writing the DLL
- C
- C#
- Unmanaged
- Restrictions
-
LoadLibrary API
- Remote Process
- lpLibFileName
-
Recall CreateRemoteThread
- lpStartAddress
- lpParameter
- Address of LoadLibraryA given as the fourth argument to CreateRemoteThread
- Allocate a buffer inside the remote process and copy the name and path of the DLL into it. Address of this buffer is given as the fifth argument to CreateRemoteThread
-
Call of DllMain
- fdwReason
- lpvReserved
- Put the Shellcode within the DLL_PROCESS_ATTACH switch case, where it will be executed when LoadLibrary calls DllMain - Read again MSDN doc
- Ignore this
- Only one parameter required
-
Injecting the DLL
- new WebClient();
- Resolve Shellcode home address
- Allocate memory in the remote process
- Copy the path and name of the DLL
into the allocated memory
-
Resolve the memory address of LoadLibrayA inside the remote process
- GetModuleHandle
- GetProcAddress
- Recall GetModuleHandle from MSOffice deception topic
- Recall GetProcAddress from MSOffice deception topic
-
Invoke CreateRemoteThread
- lpStartAddress
- lpParameter
- Return of VirtualAllocEx
- Return of GetProcAddress
- The DLL must be written to disk (once created, download it to the victim machine)
- Recall OpenProcess
- Recall VirtualAllocEx
- Recall WriteProcessMemory
-
Reflective DLL Injection: avoid disk writing
- MUST READ - Parsing the fields: DLL's Portable Executable (PE)
- PowerShell reflective DLL injection code
-
Process Hollowing
-
Avoid Network Noise
-
svchost.exe
- Migration
- SYSTEM integrity level restriction
- Launch and modify before it starts executing
-
Important Step
-
Process Creation
- CREATE_SUSPENDED flag
- Process.Start
-
CreateProcess API
- Creates the virtual memory space for the new process
-
Allocates the stack along with
- Thread Environment Block (TEB)
- Process Environment Block (PEB)
- Loads the required DLLs and the EXE into memory
-
Thread Creation to execute code starting at the EntryPoint of the executable
-
Supplying CREATE_SUSPENDED flag
- Thread execution halted before it runs the EXE’s first instruction
-
Locating the EntryPoint
- Overwrite its content
- Continue execution with our Shellcode
-
Locating the EntryPoint
- ASLR
-
ZwQueryInformationProcess API
- Various info
-
ProcessInformationClass
- ProcessBasicInformation
- PebBaseAddress (PEB)
- Points to a PEB structure
- Process Base Address
- Parsing the PE headers
- Locating the EntryPoint
-
Read the EXE base address
- REMOTE: ZwQueryInformationProcess -> address of the PEB
- ReadProcessMemory API
-
Analyzing the remote process PE header
-
ReadProcessMemory
- e_lfanew field
- EntryPoint Relative Virtual Address (RVA)
- Offset from the beginning of the PE to the PE Header
- RVA is just an offset: it helps to obtain the absolute virtual memory address of the EntryPoint
-
Overwriting the Content of the EntryPoint with our Malicious Code
- WriteProcessMemory
- Let the execution of the thread in the remote Process
-
C# Code Building Steps
- DllImport
-
CreateProcessW
- System.Threading namespace
-
10 arguments
- lpApplicationName
- lpCommandLine
- lpProcessAttributes
- lpThreadAttributes
- dwCreationFlags
- lpEnvironment
- lpCurrentDirectory
- lpStartupInfo
- lpProcessInformation
- Name of the application to be executed - can be set to NULL
- Full command line to be executed
- Security descriptor: go with the default
- Ignore this: false
- 0x4 for CREATE_SUSPENDED
- Ignore this: NULL
- Process window configuration
- Structure that is populated by CreateProcessW
-
Invoke the Call to the API
-
Object Instantiation
- STARTUPINFO
- PROCESS_INFORMATION
- Supplied to CreateProcessW
-
disclosing the PEB
-
ZwQueryInformationProcess
- Nt
- Zw
- Low Level API in ntdll.dll
- Indicates that the API can be called by either a user-mode program or by a kernel driver
- Returns an hexadecimal value directly from the kernel
- Pointer to Image Base
-
ReadProcessMemory
- hProcess
- lpBaseAddress
- lpBuffer
- nSize
- lpNumberOfBytesRead
- Process handle
- Address to read from
- Buffer to copy the content into
- Number of bytes to read
- Variable to contain the number of bytes actually read
-
Pointer to svchost
- Bit Conversion Required
- Then IntPtr cast
- Code Sample
- Pointer
-
Locating the EntryPoint
-
PE Header Parsing
- ReadProcessMemory
- 0x200 bytes buffer size
- PE Start
- e_lfanew at Offset 0x3C
- PE Start + e_lfanew + 0x28
- PE header: offset from the image base to the PE header structure
- Code EntryPoint: offset from the image base to the EntryPoint
-
EntryPoint Full Memory Address =
- EntryPoint RVA
- Image Base
- +
-
Triggering the Malicious Code
-
Overwriting the existing code at the EntryPoint
- WriteProcessMemory
-
CreateRemoteThread
- ResumeThread API
-
Let the suspended thread of a remote process continue its execution
- Recall PROCESS_INFORMATION
- hThread
- Variable that should contain a pointer to the image base of svchost.exe in the suspended process
- Avoid: do not allow us to create a suspended process