๐Ÿค” How Do I Spot Malware?

Created: 27.06.2023

The number or applications installed or present on a device can sometimes be frightening. Not all of them are installed with the userโ€™s consent. Some of them might be malicious. How does one spot these little pesky rodents?

System faults, errors and crashes can be spotted via System (errors, warnings and critical) and application events.

SANS Six-Part Methodology

  • Identify rogue processes
  • Analyse DLLs and handles.
  • Review network artefacts
  • Look for code injection.
  • Check for any signs of a rootkit.
  • Dump suspicious processes and drivers.

Windows

๐Ÿชต Event logs: โš™๏ธ System, ๐Ÿ“ฑApplication

๐Ÿบ Artefact ๐Ÿ“ Comment
๐Ÿชต Event logs โš™๏ธ errors, warning and critical๐Ÿ“ฑ1000 (error), 1001 (WER), 1002 (hanging)
๐Ÿ“‘ WER ๐Ÿ“‚ C:\Microsoft\Windows\WER ๐Ÿ› ๏ธ NinjaCopy can collect that.

๐Ÿ’ญ RAM

The best place to find malware is in RAM. At some point, it needs to run. Either get the RAM copy or some alternative like a hiberfil.sys. There are several techniques to use to identify malware in the RAM image: signature-based search (like with most AV), contradictions (something is not right there), heuristic/behavioural (the system or a process is behaving weirdly and unexpectedly).

Deviations = investigative leads. Core Processes - essential for Win, run on any Win system under examination.

standart-proc-win

Parents and Children

  • check names
  • parent (for example, svchost.exe is started by services.exe)
  • expected path
  • Singleton?
  • Account (local system, mane, users)
  • start time (boot time, later)
  • Security identifier (SID)

svchost.exe - the most abused process. Check for the above deviations in the result.

One thing to do is compare the output from both psllist and psscan plugins to see if any rootkits are hiding. pslist relies on the doubly-linked EPROCESS list where each node represents a processโ€™s meta and points to the next EPROCESS. The problem is that with the DKOM technique (Direct Kernel Object Manipulation), an attacker can unlink the rogue process from the EPROCESS list, thus hiding it from the OS eye.

Here is what the EPROCESS list looks like (roughly):

img And here is what happens when the process is unlinked:

img

As you can see, now the ๐ŸŒด process is โ€œinvisibleโ€ to the operating system. pstree plugin also relies on the same data structure, so, the only difference is in the presentation: you see a tree (child-parent relationships) instead of a list which is helpful too. psscan, on the other hand, doesnโ€™t rely on the EPROCESS list; it scans the whole image for these EPROCESS objects (their signatures), whether they are linked to each other or not, and thus identifies the rogue processes. It can also identify terminated processes (and marks them as such).

โ—๏ธOne very important thing to note is that pslist shows the virtual address of the EPROCESS structure (when it was in memory), whereas the psscan shows the physical offset (from the raw image start). 32-bit virtual address consists of the following parts: 10b for page index, 10b for page table index, 12b for byte index. Additionally, pslist shows ๐Ÿพ number of threads, ๐Ÿพ number of handles, while psscan additionally notes ๐Ÿพ page directory base offset (PDB) and ๐Ÿพ exit time. pstree has the same info but in a different representation.

Both plugins also show the following data:

๐Ÿพ Process name ๐Ÿพ PID ๐Ÿพ PPID (parent PID) ๐Ÿพ Start time

๐Ÿ›  EchoTrail is an excellent online tool for insights into the Windows core processes (expected boot time, children and parents etc).

You can use the ๐Ÿ›  pstree plugin to create a diagram in .dot format, which can later be used to create a png

๐Ÿ“˜ vol.py -f imagename --profile prof pstree --output=dot --output-file=pstree.dot
๐Ÿ“˜ dot -Tpng pstree.dot -o pstree.png

Check parent processes of core processes:

๐Ÿ“˜ grep -E -i "(system|wininit|lsass|lsm|services|sms|taskhost|winlogon|iexplore|explorer|svchost|csrss)" pslist.txt > pslist-all-core.txt
๐Ÿ“˜ grep -E -i "(system|wininit|lsass|lsm|services|sms|taskhost|winlogon|iexplore|explorer|svchost|csrss)" psscan.txt > psscan-all-core.txt

We have the result of pslist:

pslist-results

We have several suspicious processes here: scvhost.exe (misspelled svchost.exe), some xminer.exe and a process with an intriguing name 3.exe. But these are the processes that we could have seen, should we use a Task Manager on a live system. What about terminated or unlinked processes?

To answer that we run psscan:

psscan-results

We saw the same 3.exe in the list. But also we see q.exe which was run for about a minute and during that time another processes was spawned - xmcminer.exe. q.exe was terminated thatโ€™s why we donโ€™t see it in pslist results. But xmcminer.exe was not terminated but we still donโ€™t see it in pslist. That means that the process was unlinked from a doubly-linked list of processes in memory (aka hidden).

Take unique process names, sort and count:

๐Ÿ“˜ cut -d " " -f 2 'psscan.txt' | sort | uniq -c | sort > 'psscan_proc_sorted.txt'

Also, think about what the attackers are likely to run. Some remote tools, for example? Like, WMI or PowerShell. When PowerShell remoting is used, wsmprovhost.exe process is running in RAM on the target (when ComputreName option is specified). Or if itโ€™s an IIS server, there will be a w3wp.exe running in RAM. If the attacker manages to run a web shell, this process will spawn the tools that this web shell invokes, like net.exe or sc.exe.

๐Ÿคจ If the user launches PowerShell, its parent will be explorer.exe. If admin - svchost.exe. PowerShell as a parent of cmd.exe is not necessarily suspicious but could be. ๐Ÿคจ wmiprvse.exe is the one running WMI. If you see wmiprvse.exe spawns cmd.exe which does something with the registry or service could be something worth looking into. ๐Ÿคจ Such processes like mshta, word or excel running PowerShell is also not a good thing. ๐Ÿคจ ActiveScriptEventConsumer WMI spawns a rare process - scrcons.exe.

WinCore vs Non-Core

Check names of non-win processes:

๐Ÿ“˜ grep -E -i -v "(system|wininit|lsass|lsm|services|sms|taskhost|winlogon|iexplore|explorer|svchost|csrss)"  pslist.txt > pslist-all-non-wincore.txt
๐Ÿ“˜ grep -E -i -v "(system|wininit|lsass|lsm|services|sms|taskhost|winlogon|iexplore|explorer|svchost|csrss)"  psscan.txt > psscan-all-non-wincore.txt

Singletons

Check known singletons

๐Ÿ“˜ grep -E -i "(system|wininit|lsass|services|lsm)" pslist.txt > pslist-all-singletons.txt
๐Ÿ“˜ grep -E -i "(system|wininit|lsass|services|lsm)" psscan.txt > psscan-all-singletons.txt

pslist-singletons

In the example above there are two lsass.exe processes which is nonsense. Obviously, some investigative lead.

Boot Times

Check boot times:

๐Ÿ“˜ grep -E -i "(system|wininit|lsass|services|sms|lsm|csrss)" pslist.txt > pslist-all-boot.txt
๐Ÿ“˜ grep -E -i "(system|wininit|lsass|services|sms|lsm|csrss)" psscan.txt > psscan-all-boot.txt

System is a pivot point. Other processes that should start at boot, should have roughly the same starting date and time. pslist is pulling the information of a doubly-linked list (like a Task Manager). psscan - unallocated space (processes terminated or unlinked from this double-linked list).

Also, get all processes that did not start at boot time:

๐Ÿ“˜ grep -E -i -v 2019-01-20 'pslist.txt' > pslist_not_boottime.txt
๐Ÿ“˜ grep -E -i -v 2019-01-20 'psscan.txt' > psscan_not_boottime.txt

Processes

Processes consist of the following elements that reside in RAM:

๐Ÿบ dlls and command line information ๐Ÿ› ๏ธ dlllist ๐Ÿ› ๏ธ dlldump ๐Ÿ› ๏ธ ldrmodules ๐Ÿบ handles (files, directories, registry keys, mutants, semaphores, events such as threat notifications) ๐Ÿ› ๏ธ handles ๐Ÿ› ๏ธ mutantscan (gives more information than handles). ๐Ÿบ threads ๐Ÿบ memory sections ๐Ÿ› ๏ธ getsids ๐Ÿบ sockets (ports and connections) ๐Ÿบ command line arguments and output

โ—๏ธEPROCESS structure only allows 16 bytes for the name. So, to see the full path and name see PEB.

You can dump the whole memory with ๐Ÿ› ๏ธ memdump or just a specific process with ๐Ÿ› ๏ธ procdump. ๐Ÿ› ๏ธ vaddump can also be of help (a separate file for each section).

๐Ÿ“˜ vol.py -f image memdump -p PID --dump-dir=./some/
๐Ÿ“˜ strings -a -t d -e l file >> strings.txt # bstrings.exe
๐Ÿ“˜ sort strings.txt > sorted_str.txt
๐Ÿ“˜ grep 
Deviations

Another helpful plugin to use would be the malfind, which tries to identify rogue processes looking for specific attack patterns automatically. And one of the most useful (at least, in my humble opinion) is the processbl which stands for process baseline and means you can compare the processes and DLLs in your image with some baseline image.

The baseline plugin has three parts: processbl, drivebl and servicebl.

โš™๏ธ processbl compares processes and their loaded DLLs (relies on the same structure as pslist) โš™๏ธ drivebl compares the drivers โš™๏ธ servicebl compares the services

๐Ÿ“˜ vol.py -f imagefile --profile=prof -B ./baseline.img processbl -U 2 > error.log #  -U - shows what's different and -K - what's not

Since this plugin does NOT compare the executable paths, only the names, itโ€™s a good practice to use both -U and -K switches to see whatโ€™s really out of place.

Command line

๐Ÿ› ๏ธ consoles (prints commands and outputs, looking for CONSOLE_INFORMATION) and ๐Ÿ› ๏ธ cmdscan (information from the command history buffer).

On WinXP csrss.exe and Win7+ - conhost.exe is responsible for command line history, which is stored in their memory, searching the VAD for DOSKEY structure (๐Ÿ› ๏ธ cmdscan). By default, cmd.exe only keeps 50 entries in the buffer.

๐Ÿ› ๏ธ cmdscan has the following list of data:

๐Ÿพ command process containing the cmd history ๐Ÿพ PID ๐Ÿพ Command History (its offset) ๐Ÿพ Application ๐Ÿพ Flags ๐Ÿพ First command (location) ๐Ÿพ CommandCountMax (size of the buffer) ๐Ÿพ LastAdded (entry last added to buffer) ๐Ÿพ LastDisplayed ๐Ÿพ Process Handle (the app handle number) ๐Ÿพ Command list

๐Ÿ› ๏ธ consoles

๐Ÿพ Console process containing CONSOLE_INFORMATION structure ๐Ÿพ PID ๐Ÿพ Console (offset in process memory) ๐Ÿพ Offset where the console was found ๐Ÿพ CommandHistorySize (default number of commands kept in the buffer) ๐Ÿพ HistoryBufferCount ๐Ÿพ HistoryBufferMax ๐Ÿพ OriginalTitle (first title of console window) ๐Ÿพ Title (current title) ๐Ÿพ AttachedProcess (process name, PID and handle ID running within this process) ๐Ÿพ Command list ๐Ÿพ Screen (coordinates of console window) ๐Ÿพ Dump (console screen output)

Files

๐Ÿ› ๏ธ filescan helps to identify files, ๐Ÿ› ๏ธ handles with -t set to File can also be used. Then, ๐Ÿ› ๏ธ dumpfiles can be used to get those files for further analysis. Scans for File_Objects from memory. Itโ€™s recommended to narrow down the output with -Q (offset) or -r (regex). Each File_Objects contains three Section_Object_Pointers: ImageSectonObject (memory-mapped binaries), DataSectonObject (memory-mapped files), and SharedCachedMap (parts cached by Windows Cache manager).

๐Ÿ“˜ vol.py -f image dumpfiles -n -i -r \\.exe --dump-dir=./path/ # use the original name when printing the output, -i - ignore case, -r - regex 

โ—๏ธThe ๐Ÿ› ๏ธ dumpfiles plugin will only look for FILE_OBJECTS within the VAD tree or in process handles. So it will not recover maliciously manipulated files. Also, special files like $MFT or $LogFile are not in VAD. Use ๐Ÿ› ๏ธ filescan to find interesting things and then ๐Ÿ› ๏ธ dumpfiles to dump them.

Shimcache

๐Ÿ› ๏ธ shimcachemem. ๐Ÿบ Shimcache updates are not writing updates to disk until the system is shut down or rebooted. So, some saucy stuff can be there.

๐Ÿ“˜ vol.py -f image --output=csv --output-file=name -P # -P print the VA and PA offsets.
DLLs

๐Ÿ› ๏ธ dlllist relies heavily on PEB and shows the following data:

๐Ÿพ Base offset (used to dump the DLL with ๐Ÿ› ๏ธ dlldump later) ๐Ÿพ DLL size ๐Ÿพ Load count (statically or dynamically loaded) ๐Ÿพ Load time (you can spot if the DLL was loaded after runtime giving out possible injection) ๐Ÿพ DLL file path (useful to spot deviations) ๐Ÿพ Command line

โ—๏ธThere can be lots of DLLs loaded into the processes, better run with the -p switch.

Use ๐Ÿ› ๏ธ dlldump to dump the DLL of interest. If no parameters are provided, it will dump EVERYTHING. But if you want to narrow down the analysis, use both -p PID and -b baseoffset. You can also use -r regex to find the DLL by name. The base offset can be provided by the ๐Ÿ› ๏ธ dlllist.

Handles

There are many handles, and it would be nearly impossible to analyse them ALL in time. To ease up your investigation, keep in mind that there are several types of handles that can be passed to the handles volatility plugin as a -t switch value:

๐Ÿซณ๐Ÿผ process ๐Ÿซณ๐Ÿผ file ๐Ÿซณ๐Ÿผ thread ๐Ÿซณ๐Ÿผ event ๐Ÿซณ๐Ÿผ key ๐Ÿซณ๐Ÿผ port ๐Ÿซณ๐Ÿผ wmiguid ๐Ÿซณ๐Ÿผ timer ๐Ÿซณ๐Ÿผ iocompletion ๐Ÿซณ๐Ÿผ windowstation ๐Ÿซณ๐Ÿผ directory ๐Ÿซณ๐Ÿผ token ๐Ÿซณ๐Ÿผ semaphore ๐Ÿซณ๐Ÿผ mutant

filescan (scan for FILE_OBJECTS) and mutantscan (scan for _KMUTANT) plugins can scan the entire image for different handle types, which is useful when finding unallocated data.

๐Ÿ“˜ vol.py -f image --profile=prof -t File
Drivers

๐Ÿ› ๏ธ modules, ๐Ÿ› ๏ธ modscan and ๐Ÿ› ๏ธ driverbl give us a list (hopefully) of suspicious drivers. To get its base offset, use ๐Ÿ› ๏ธ modscan or ๐Ÿ› ๏ธ modules. Once we have the base offset of the nefarious driver, use ๐Ÿ› ๏ธ moddump to retrieve it for further inspection.

๐Ÿพ driver name ๐Ÿพ base offset ๐Ÿพ output filename

โ—๏ธ The offset provided by the ๐Ÿ› ๏ธ ssdt plugin is the function offset, not that of the driver!

๐Ÿ“˜ vol.py -f image ssdt | egrep -v `(ntoskrnl|win32k)`
๐Ÿ“˜ vol.py -f image modules | grep something
๐Ÿ“˜ vol.py -f image moddump -b offset --dump-dir=./filename
Permissions

Permissions on Windows are specified with the tokens and SIDs. ๐Ÿ› ๏ธ getsid volatility plugin can display the security identifiers for the given process.

Network

There are three main data to look out for when analysing network artefacts:

๐Ÿบ ports. Look out for non-browser processes listening on 443, 80, 8080 or browsers listening on anything other than that. RDP (3389) is something to look closer at if this type of connection is uncommon for this machine. PowerShell remoting - 5985. ๐Ÿบ connections. Check the IP for nefariousness. DNS requests to unusual domains or TXT records. Workstation-to-workstation connections are not usually common and often show lateral movement. RDP to the local host is especially suspicious (VPN?).
๐Ÿบ processes (those responsible for that network connection)

โ—๏ธ Network sockets have creation times, and terminated processes can be recovered.

Volatility plugins follow the single-linked list (for older machines): ๐Ÿ› ๏ธ connections (active, open), ๐Ÿ› ๏ธ sockets (active). Volatility plugins scan the image for known structures (for older machines): ๐Ÿ› ๏ธ connscan, ๐Ÿ› ๏ธ sockscan (_ADDRESS_OBJECT).

๐Ÿ› ๏ธ netscan combines the functionality of the above plugins and can be used against Vista+. Shows the following data:

๐Ÿพ memory offset ๐Ÿพ protocol ๐Ÿพ local IP ๐Ÿพ state (for TCP) ๐Ÿพ PID ๐Ÿพ process owner name ๐Ÿพ creation time

Injections

Most information is taken from here, but more visualisation is added. The screenshots from IDA Pro are also copied from that blog post. I will start with a brief overview of the volatility plugins used to analyse injection, and you can see the list below for more detailed analysis instructions. For more, see the Attacks DB -> Binary -> Injections article.

๐Ÿ› ๏ธ Get-InjectedThread to do live analysis for injections and ๐Ÿ› ๏ธ hollows_hunter to spot more advanced techniques, also live.

  1. Classic. A malicious DLLโ€™s path is copied in the memory space of a legitimate running process to be loaded in runtime.
  2. PE injection. A malicious DLL itself is copied into the memory space of a legitimate running process.
  3. Process Hollowing. An already loaded good process is fully overwritten with something that could be better. Imagine that the legit code was scooped out.
  4. SIR (Suspend, Inject, Resume). EIP registerโ€™s value of a running thread is substituted. This is the chain of function calls needed for this attack.
  5. Hook. Uses SetWindowsHookEx() API function.
  6. Registry poisoning. Using the registry to inject. These are the keys that can be used for injection.
    1. Upon User32.dll load mal.dll will be loaded (whenever CreateProcess(), CreateProcessAsUser(), CreateProcessWithLogonW(), CreateProcessWithTokenW(), WinExec() are called, mal.dll will be called):
      1. ๐Ÿ”‘ HKLM/Software/Microsoft/WindowsNT/CurrentVersion/Windows/Appinit_Dlls
      2. ๐Ÿ”‘ HKLM/Software/Wow6432Node/Microsoft/WindowsNT/CurrentVersion/Windows/Appinit_Dlls
      3. ๐Ÿ”‘ HKLM/System/CurrentControlSet/Control/Session Manager/AppCertDlls
    2. IFEO - usually used to attach a debugger. The value of the Debugger Value is changed.
      1. ๐Ÿ”‘ HKLM/Software/Wow6432Node/Microsoft/WindowsNT/CurrentVersion/image file execution options
    3. โ—๏ธ mal.dll needs to be present on disk.
    4. โ—๏ธ There are โ€œsmithereensโ€ left in the registry that can be a good lead in an investigation.
  7. APC.
  8. EWMI with SetWindowLong()
  9. SHIMS. My favourite and the most useful for malware: DisableNX, DisableSEH, InjectDLL.
  10. Userland rootkit. Rootkits are usually associated with the kernel space. However, there are also userland rootkits out there. There are two main techniques known: IAT and inline. When the IAT hooking technique is used, malware changes the import address table. This way, when a good application calls some function from this tampered DLL, the replaced function is executed instead. With inline hooking, the malware modifies the functionโ€™s body itself.
  11. Reflective. This means not using LoadLibrary or Windows Loader to load the code. This allows the malware to avoid being tracked by the system. The code can be injected directly from memory. The only legit way to load code is from disk and only sections with code are supposed to be marked as Page_Execute_ReadWrite. So, the memory analysis process to identify this is as follows:
    1. Walk through the VAD and inspect each section.
    2. Detect unusual permissions like Page_Execute_ReadWrite, and if it is mapped to disk.

๐Ÿ› ๏ธ ldrmodule. Detects unlinked and unmapped processes. It checks and follows these three doubly-linked lists in the PEB and the VAD, then scans the image for the structures, comparing the results from VAD and PEB. Such plugins as dlllist will show only whatโ€™s not unlinked, and ldrmodule will highlight deviations.

๐Ÿพ PID ๐Ÿพ p_name ๐Ÿพ base offset (location in the image) ๐Ÿพ PEB InLoadOrderModule list (InLoad) - doubly-linked list ๐Ÿพ PEB InInitializationOrderModule list (InInit) - doubly-linked list ๐Ÿพ PEB InMemoryOrderModule list (InMem) - doubly-linked list ๐Ÿพ VAD Tree MappedPath โ—๏ธIn case you donโ€™t see anything here, the program was not loaded from the disk, which is almost always suspicious even if all the three PEB lists show True for this process.

๐Ÿ“˜ vol.py -f image ldrmodules -p PID

Classic and PE injection techniques use CreateRemoteThread, and classic uses LoadLibraryA WinAPI call. Since WinAPI was used, it will look very similar to a legit process. The best bet would be to check the MappedPath column for unusual locations.

โ—๏ธdlllist will also show this info since the malware is not hiding itself with this technique, just injecting.

๐Ÿ”Ž If MappedPath is empty and all three PEB lists are empty, the file was not loaded from the disk, which is an excellent indication of injection. ๐Ÿ”Ž When MappedPath is empty for the memory section that is supposed to belong to the executable itself - process hollowing.

๐Ÿ”Ž Using this module, โœ๏ธ You can grep for False to narrow the search. ๐Ÿ”Ž False positives: unloaded DLLs not yet removed from memory until FreeLibrary is called; strange extensions like .fon, .mui etc. will not be present in the PEB lists but in the VAD. Since they are all PE files, they will appear suspicious when they are not; PEB is only about exe and dll.

Three PEB doubly-linked lists are useful for detecting injections. โ€œGoodโ€ programs will be present in all three, showing True in the corresponding columns in the output. Some legit programs (a limited number) will be absent from some lists. Also, process executables will always be missing from the InInit list. Sometimes unloaded DLLs that werenโ€™t yet removed from the process memory might also be showing there.

๐Ÿ› ๏ธ malfind. Find hidden and injected code and dumps interesting parts of memory. It can help identify more advanced injection techniques like reflective injection.

๐Ÿพ p_name ๐Ÿพ PID ๐Ÿพ Starting offset ๐Ÿพ Ending offset ๐Ÿพ Tag (type of memory section) ๐Ÿพ Hits (from YARA) ๐Ÿพ Protect (memory permissions)

It also dumps some starting portions of the memory section (64 bytes) so the analyst can easily spot the MZ header or the shellcode. Sometimes, the malware gets very clever, padding the section with something malicious with ADD [EAX], AL that looks like garbage for the analyst, or overwrites the MZ header, clears the entire MZ header or jumps to the code placed later. The best approach here is to dump this section and review it fully.

๐Ÿ› ๏ธ hollowfind. Identifies main hollowing techniques. Compares PEB with VAD, looks for unusual section permissions (similar to malfind).

๐Ÿ› ๏ธ threadmap. Analyse threads and find process hollowing countermeasures. Each threat is mapped to its corresponding VAD entry; the plugin test this entry and the code contained to identify anomalies. Harder to hide and manipulate, there always needs to be a threat pointing to the injected code.

Hooks

SSDT. The system Service Descriptor Table hooks the system calls. This technique involves patching one or more pointers that point to the lookup table for system functions. Legit calls are always either to ntoskrnl.exe or win32k.sys.

๐Ÿ› ๏ธ ssdt. It helps identify SSDT hooking by looking for references other than ntoskrnl.exe or win32k.sys. In order to remove legit hooks, use the following grep:

๐Ÿ“˜ ssdt_output | egrep -v `(ntoskrnl\.exe | win32k\.sys)`

On Vista+ this technique is harder to pull off since the Kernel Patch Protection (PatchGuard) will crash the processes attempting to do this (unless there is a vulnerability).

๐Ÿพ Tables entry ๐Ÿพ function offset ๐Ÿพ function ๐Ÿพ function owner

Note the hooked functions, as they can give a clue to the malwareโ€™s function.

๐Ÿ› ๏ธ ssdt_ex can be used to identify and dump SSDT entries.

IDT (Interrupt Descriptor Table). Not very common in modern systems. ๐Ÿ› ๏ธ idt. Helps identify IDT technique.

IAT (Import Address Table) and Inline API. User-mode DLL function hooking can be spotted with ๐Ÿ› ๏ธ volatility apihooks plugin. As the output can be overwhelming, use -Q to only scan critical processes or/and -R to skip kernel mode checks.

โœ๏ธ False positives to eliminate: setupapi.dll, mswsock.dll, sfc_os.dll, adsldpc.dll, advapi32.dll, secur32.dll, ws2_32.dll, iphlpapi.dll, ntdll.dll, kernel32.dll, user32.dll, gdi32.dll.

Unknown in the Hooking module shows that it is jumping into a memory section thatโ€™s not mapped to disk.

IRP (I/O Request Packets) for driver hooking, low-level stuff. ๐Ÿ› ๏ธ driverirp. It helps in identifying the IRP technique.

Use ๐Ÿ› ๏ธ psxview plugin for the cross-view analysis. Eliminate false positives by using -R (known good). It includes the data from the following plugins: pslist, psscan, pspcid (keeps track of processes and PIDs), thrdproc (reviews all threads in memory and collects processes using thread parent id), csrss (csrss.exe keeps a handle to each process started after it), session (process for each logon session), deskthrd (identify processes via threads attached to each Windows desktop).

โœ๏ธ If you see False in all the columns except for ๐Ÿ› ๏ธ psscan -> the process was terminated.

๐Ÿ› ๏ธ modscan (scanning the memory image) and ๐Ÿ› ๏ธ modules (uses the list). This plugin looks for loaded kernel modules and drivers. Run both to see the difference, then you might use ๐Ÿ› ๏ธ devicetree to see the same info better visualised. Also, use the plugins for hooking identifications and then, you can either use a baseline image with ๐Ÿ› ๏ธ driverbl plugin or dump the memory area with the ๐Ÿ› ๏ธ moddump.

DKOM

Direct Kernel Object Manipulation. Unlinks the process from the EPROCESS doubly-linked list. Process unlinked in this way wonโ€™t be visible to pslist plugin or tasklist.exe.

Metadata

Use ๐Ÿ› ๏ธ yara for malware signatures, ๐Ÿ› ๏ธ sigcheck for digital signature verification, ๐Ÿ› ๏ธ DensityScout () to check entropy to identify packed files, and ๐Ÿ› ๏ธ capa to run an initial automated malware analysis against the file.

๐Ÿ“˜ yara64.exe -C compiled-rules [directory or file]
๐Ÿ“˜ densityscout -pe -r -p 0.1 -o results # -pe include all PE, -p max density coefficient to show packed files
๐Ÿ“˜ sigcheck -c -e -hv [directory or file] > results.csv # -c to output in a csv file, -e to only scan exe, -h to show hashes and v for verbose mode.
๐Ÿ“˜ capa [options] [file]

Zone.Identifier ADS on NTFS shows where the file came from and can be of particular interest to the investigation. For example, ZoneId=3 indicates that the files were downloaded from the Internet. What files are ok to be downloaded from the Internet? Would you expect svchost.exe to be one of them? Or any other file that is found in the C:\Windows\System32 folder?

img

Common Malware

Cobalt Strike

CS usually spawns a child process for each activity to make itself more persistent. These are called sacrificial processes. A good approach would be to look for exited child processes under PowerShell or WmiPrvSE.

IOCs

๐Ÿ› ๏ธ openioc_scan, ๐Ÿ› ๏ธ yarascan (vol plugin) and ๐Ÿ› ๏ธ page_brute.py.

References

Expandโ€ฆ Something here