Having fun while learning about and pivoting into the world of DFIR.
by ogmini
Just submitted an Artifact to the Velociraptor Artifact Exchange for Windows Notepad that leverages my WindowsNotepadParser. I’m pretty sure the YAML can be significantly improved. I’m hoping for some feedback and suggestions. It works fine; but requires creating a folder on the client to save the csv files. There should be a way to save them to the temp directory. I wasn’t able to get that to work though.
name: Windows.Forensics.WindowsNotepadParser
description: |
Runs the WindowsNotepadParser (https://github.com/ogmini/Notepad-State-Library) tool to collect and parse
forensic artifacts related to Windows Notepad on Windows 11.
Documentation and details about the artifacts can be found at - https://github.com/ogmini/Notepad-State-Library
### History
- 1.0 - Creation
reference:
- https://github.com/ogmini/Notepad-State-Library
- https://ogmini.github.io/tags.html#Windows-Notepad
author: ogmini https://ogmini.github.io/
required_permissions:
- EXECVE
- FILESYSTEM_WRITE
type: CLIENT
tools:
- name: WindowsNotepadParser
url: https://github.com/ogmini/Notepad-State-Library/releases/download/v1.0.4/WindowsNotepadParser-Minimal-v1.0.4-standalone.zip
version: 1.0.4
parameters:
- name: outputDirectory
default: "C:\\Velociraptor\\WindowsNotepadParser\\"
description: Output directory for the csv files generated by the tool.
precondition: SELECT OS From info() where OS = 'windows'
sources:
- name: FileTabs
description: These tabs have been saved to disk or have been opened from a file on disk.
query: |
-- get context on target binary
LET windowsnotepadparserpackage <= SELECT * FROM Artifact.Generic.Utils.FetchBinary(
ToolName="WindowsNotepadParser", IsExecutable=FALSE)
-- build tempfolder for output
LET tmpdir <= tempdir()
-- decompress utility
LET payload = SELECT *
FROM unzip(filename=windowsnotepadparserpackage[0].FullPath,
output_directory=tmpdir) WHERE OriginalPath =~ "WindowsNotepadParser-Minimal.exe"
-- execute payload
LET deploy <= SELECT *
FROM execve(argv=[payload.NewPath[0], "-o", outputDirectory])
SELECT *
FROM parse_csv(filename=outputDirectory + "NoFileTabs.csv")
- name: NoFileTabs
description: These tabs have not been saved to disk and have not been opened from a file on disk. They only exist in the *.bin files.
query: |
SELECT *
FROM parse_csv(filename=outputDirectory + "NoFileTabs.csv")
- name: StateTabs
description: These are the *.0.bin and *.1.bin files and store extra information about the related matching GUID *.bin.
query: |
SELECT *
FROM parse_csv(filename=outputDirectory + "StateTabs.csv")
- name: WindowStateTabs
description: The windowstate files store information about opened windows of Windows Notepad and files are created for each opened window.
query: |
SELECT *
FROM parse_csv(filename=outputDirectory + "WindowStateTabs.csv")
- name: UnsavedBufferChunks
description: Unsaved changes to a tab. Will only exist while Windows Notepad is open.
query: |
SELECT * FROM foreach(row={
SELECT OSPath
FROM glob(globs="*-UnsavedBufferChunks.csv", root=outputDirectory)
}, query={
SELECT *
FROM parse_csv(filename=OSPath)
})
Ideally, Velociraptor should not need WindowsNotepadParser as it has a built in Binary Parser and the Artifact would be able to do everything natively. Currently the Binary Parser does not appear to support ULEB128/LEB128. I’ve started to poke around to see if that can be added with the caveat being that I have no experience with Go. I believe I’d have to make changes/contributions to https://github.com/Velocidex/vtypes.
tags: #DFIR #Windows-Notepad #Velociraptor