The following cheatsheets and infos I’m referencing regularly and it should be a helper for everyday’s life for myself and hopefully yours too.
Memory Forensics
Running all basic plugins
To do this I usually run the following command which just runs and outputs all the plugin outputs into a matching textfile. So run it and go grab a coffee 😀
for PLUGIN in pslist psscan pstree modules netscan cmdscan handles scheduled_tasks svclist registry.userassist psxview malfind; do
echo " $PLUGIN"
vol3 -f mydump.dmp windows.$PLUGIN > analysis/$PLUGIN.txt
done
Finding hidden processes:
vol3 -f dump.mem windows.psxview > psxview.txt
# and as soon as it's done
awk 'NR==3 || $4 == "False"' psxview.txt
There is some things to keep in mind:
- If something hits here, search for the path where it is located. If it’s in C:/Windows/System32 it’s not suspicious
- Check the DLLs loaded for this process: Attackers can use techniques like process hollowing or DLL injection to compromise a legitimate process
- Check if the process still has active threads: If it does have active threads but it doesn’t appear in the
pslistresults, it is suspicious. It could be that an attacker is hiding the process - If an active process does not have any threads, it is considered suspicious. Every active process should have at least 1 thread. Attackers can use techniques to alter the threads.
- Check the
Exit Time: If the process really is terminated, it should display anExit Time. If there are still active or orphaned threads linked to that process, it is suspicious. - Dump the process memory and analyze it further (more to that later down)
Finding Process which has no handles
# run psscan plugin of volatility. then:
awk '$5 == "0" || $5 == "-"' psscan.txt
Find open socket connections
vol3 -f memory.mem windows.netscan
Extract file from Linux system
vol3 -f memory.raw linux.pagecache.InodePages --find /etc/dnsmasq.conf --dump
Finding Injected Processes
If you’re searching for processes which could’ve been injected by an attacker run the malfind plugin.
vol3 -f memory.raw windows.malfind
Pay close attention to the output of it. It generally outputs memory pages, which are RWX or RX which means they are Read-(Write)-Executable.
That means, if you pay attention to the hex code, this plugin outputs could hold an MZ or PE section at the beginning. (4D 5A)
Advanced Techniques
Dumping Process and it’s open files
This can be useful if, for example, you have a ram-dump which had a process with a file open you want to retrieve.
There is 2 ways a Process can be dumped. Either into one single file then use:
vol3 -f mempory.mem windows.memmap --pid PROCESSID --dump
Which outputs a file called: pid.PROCESSID.dmp.
This file can be searched using cat & grep.
To output the actual open file and sections it has loaded it can be done like so:
vol3 -f ../memory.mem windows.dumpfiles --pid 5252
I would recommend you make a directory for the process you dump, as it’s going to output a lot of files. The outputs is set together of 3 types of files:
| Feature | ImageSection | DataSection |
| Purpose | Mapped executable image | Mapped Data, Documents open in the Process at the time of ram dump creation. |
| Typical Content | .exe, .dll, injected PE files | Configs, logs, unpacked payloads |
| Holding executable? | yes | normally not |
Yara
Following things I used a lot regarding yara:
Running multiple yara rules over a binary
yara $(find ./rules -name "*.yar") binary.exe
Malware Analysis
Registers
| Description | 64-bit Register (8-bytes) | 8-bit Register (1-bytes) |
|---|---|---|
| Data/Arguments Registers | ||
| Syscall Number/Return value | rax | al |
| Callee Saved | rbx | bl |
| 1st arg | rdi | dil |
| 2nd arg | rsi | sil |
| 3rd arg | rdx | dl |
| 4th arg – Loop Counter | rcx | cl |
| 5th arg | r8 | r8b |
| 6th arg | r9 | r9b |
| Pointer Registers | ||
| Base Stack Pointer | rbp | bpl |
| Current/Top Stack Pointer | rsp | spl |
| Instruction Pointer ‘call only’ | rip | ipl |
Assembly Instructions
| Instruction | Description | Example |
|---|---|---|
| Data Movement | ||
mov | Move data or load immediate data | mov rax, 1 -> rax = 1 |
lea | Load an address pointing to the value | lea rax, [rsp+5] -> rax = rsp+5 |
xchg | Swap data between two registers or addresses | xchg rax, rbx -> rax = rbx, rbx = rax |
| Unary Arithmetic Instructions | ||
inc | Increment by 1 | inc rax -> rax++ or rax += 1 -> rax = 2 |
dec | Decrement by 1 | dec rax -> rax-- or rax -= 1 -> rax = 0 |
| Binary Arithmetic Instructions | ||
add | Add both operands | add rax, rbx -> rax = 1 + 1 -> 2 |
sub | Subtract Source from Destination (i.e rax = rax - rbx) | sub rax, rbx -> rax = 1 - 1 -> 0 |
imul | Multiply both operands | imul rax, rbx -> rax = 1 * 1 -> 1 |
| Bitwise Arithmetic Instructions | ||
not | Bitwise NOT (invert all bits, 0->1 and 1->0) | not rax -> NOT 00000001 -> 11111110 |
and | Bitwise AND (if both bits are 1 -> 1, if bits are different -> 0) | and rax, rbx -> 00000001 AND 00000010 -> 00000000 |
or | Bitwise OR (if either bit is 1 -> 1, if both are 0 -> 0) | or rax, rbx -> 00000001 OR 00000010 -> 00000011 |
xor | Bitwise XOR (if bits are the same -> 0, if bits are different -> 1) | xor rax, rbx -> 00000001 XOR 00000010 -> 00000011 |
| Loops | ||
mov rcx, x | Sets loop (rcx) counter to x | mov rcx, 3 |
loop | Jumps back to the start of loop until counter reaches 0 | loop exampleLoop |
| Branching | ||
jmp | Jumps to specified label, address, or location | jmp loop |
jz | Destination equal to Zero | D = 0 |
jnz | Destination Not equal to Zero | D != 0 |
js | Destination is Negative | D < 0 |
jns | Destination is Not Negative (i.e. 0 or positive) | D >= 0 |
jg | Destination Greater than Source | D > S |
jge | Destination Greater than or Equal Source | D >= S |
jl | Destination Less than Source | D < S |
jle | Destination Less than or Equal Source | D <= S |
cmp | Sets RFLAGS by subtracting second operand from first operand (i.e. first – second) | cmp rax, rbx -> rax - rbx |
| Stack | ||
push | Copies the specified register/address to the top of the stack | push rax |
pop | Moves the item at the top of the stack to the specified register/address | pop rax |
| Functions | ||
call | push the next instruction pointer rip to the stack, then jumps to the specified procedure | call printMessage |
ret | pop the address at rsp into rip, then jump to it | ret |
Syscall Calling Convention
- Save registers to stack
- Set its syscall number in
rax - Set its arguments in the registers
- Use the
syscallassembly instruction to call it
Function Calling Convention
Save Registerson the stack (Caller Saved)- Pass
Function Arguments(like syscalls) - Fix
Stack Alignment - Get Function’s
Return Value(inrax)
Windows Logs and what to look for
User Login
- 4648 (A logon was attempted using explicit credentials) -> Runas
- 4797 (Account attempts to Logon using explicit Credentials)
- 4624 (Successful Logon)
- 4625 (Logon Failed)
- 4672 (Special privileges assigned)
- 4776 (NTLM Authentication -> Domain Controller)
- 4771 (Kerberos Pre-Authentication Failed)
- 4772 (Kerberos Auth ticket request failed)
Firewall Rules
- 2004: A rule has been added to the Windows Firewall exception list.
- 2005: A rule has been modified in the Windows Firewall exception list.
- 2006: A rule has been deleted in the Windows Firewall exception list
- 2010: Network profile changed on an interface
- 2033: All rules have been deleted from mthe Windows Firewall configuration on this computer
- 2051: comes in pair with the 2033
Audit Policy Changed
- 4719: System audit policy was changed
Group Policy Changes
- 5136 : Directory Service Changes
Scheduled tasks
- 4698: Created scheduled Task
Defender alert code:
- 3300: Antimalware platform detected malware / performed an action
- 1116 – MALWAREPROTECTION_STATE_MALWARE_DETECTED
- 1117 – MALWAREPROTECTION_STATE_MALWARE_ACTION_TAKEN
- 5007 – MALWAREPROTECTION_CONFIG_CHANGED
SmartScreen Log:
- 1003 – Logs the final decision SmartScreen makes on an application of file execution
Powershell logs:
Always search if droppped powershells have actually been run
Filter for logs which happened after a certain time: (EvtxEcmd can transform these logs)cat evtx_parsed.json | grep Powershell-Operational.evtx | jq -c 'select(.TimeCreated > "2023-03-27T14:37:09") | .EventId' | sort | uniq -c
- 4103 / 4104 – 03 logs teh start of a session and 04 logs the commands run
Logs Clearing
- 1102 – Logs have been cleared
Service installed
- 4697 A Service was installed in the system
- 7045 (Same but on older Windows server OS)
PDF investigation
Identify potential malicious elements in PDF
To find potentially malicious elements inside a pdf file run pdfid.py tool (available on: https://blog.didierstevens.com/programs/pdf-tools/) on the file you’re trying to find informations for:
python3 pdfid.py my_pdf.pdf
This will output some information. Generally you see which elements are there. The following list is an overview of what could potentially be malicious and why:
Run embedded JavaScript code:
- /JS
- /JavaScript
- /AcroForm
- /XFA
Run embedded Flash Programs:
- /RichMedia
Run external or embedded program:
- Launch
- EmbeddedFiles
Interact with a webpage:
- /URI
- /SubmitForm
Run automatic action on opening of document:
- /OpenAction
- /AA
Extract object identified to be investigated
pdf-parser -o <objectNrToExtract> --filter --raw -d object_to_investigate.out strange_pdf.pdf
Office document investigation
Detonating scripts embedded in the Document
This can be done using ViperMonkey tool (find it at: https://github.com/decalage2/ViperMonkey)
vmonkey attacker3.doc
Find potentially malicious sections
| Command | Description |
|---|---|
py.exe ./oledump.py "/home/r4ruk/test_infection.docm" | Displays different informations about the document given. The lines indicated by m or M are the ones containing macros. (Visible in the screenshot below in the next technique) |
py.exe ./oledump.py -s 3 -v "/home/r4ruk/test_infection.docm" | The element which is shown with a big M in the output before is the number after the -s parameter. the -v outputs the full macro code. |
Searching with yara and oledump
python3 oledump.py --yawa=#d#1.exe attacker3.doc

#s defines that the search is a string search.
#1.exe is the string being searched.
The M marks the element, which has Macros embedded.
