Skip to content

Commit 168ba66

Browse files
mgreen27scudette
andauthored
Create DotnetDumper.yaml (Velocidex#1258)
A response artifact to triage windows .net process and collect .net assemblies from memory using DotnetDumper --------- Co-authored-by: Mike Cohen <mike@velocidex.com>
1 parent b1d7c45 commit 168ba66

5 files changed

Lines changed: 191 additions & 5 deletions

File tree

config.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
baseURL: https://docs.velociraptor.app/
2-
languageCode: en-us
2+
locale: en-us
33
title: "Velociraptor - Digging deeper!"
44

55
theme: "hugo-theme-learn"
66
disqusShortname: velocidex-velociraptor
7-
#security:
7+
security:
8+
allowContent:
9+
- text/html
10+
- text/markdown
811
# enableInlineShortcodes: true
912

1013
enableGitInfo: true
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
name: Windows.Memory.DotnetDumper
2+
author: Matt Green - @mgreen27
3+
description: |
4+
Response artifact to triage Windows .NET processes and collect .NET assemblies from
5+
memory using DotnetDumper.
6+
7+
Collected output includes recovered .NET assemblies, suspicious managed strings,
8+
full managed string listings, loaded module details, and patch detection findings.
9+
These results support DFIR workflows focused on inspecting potentially malicious
10+
or tampered managed code executing in memory.
11+
12+
The original process dump can optionally be uploaded.
13+
14+
NOTE: this artifact writes a process dump to the Velociraptor temporary directory
15+
before analysis. Dump files may be large, similar to standard Velociraptor process
16+
dump collection.
17+
18+
tools:
19+
- name: DotNetDumper
20+
url: https://github.com/mgreen27/DotnetDumper/releases/download/continuous/DotnetDumper.exe
21+
serve_locally: true
22+
expected_hash: c7cfb900675e5394548ee3c1da39c0d3a365235b40d5566b26d89f22cc4ca3bd
23+
- name: DotNetDumper_x86
24+
url: https://github.com/mgreen27/DotnetDumper/releases/download/continuous/DotnetDumper_x86.exe
25+
serve_locally: true
26+
expected_hash: 1b7d6fabd150eda572522e3fce351452517abff071d1bbf6346790b5e032fd48
27+
- name: DotNetDumper_arm64
28+
url: https://github.com/mgreen27/DotnetDumper/releases/download/continuous/DotnetDumper_arm64.exe
29+
serve_locally: true
30+
expected_hash: 4b4f9f4bf42ad4758d4c51e62c7be92267c7f0612ee2f9b6608bc847634eb68e
31+
32+
implied_permissions:
33+
- EXECVE
34+
- FILESYSTEM_WRITE
35+
36+
precondition: SELECT OS From info() where OS = 'windows'
37+
38+
parameters:
39+
- name: ProcessRegex
40+
default: notepad
41+
type: regex
42+
- name: PidRegex
43+
default: .
44+
type: regex
45+
- name: EncodeKey
46+
default: infected
47+
- name: UploadDmp
48+
type: bool
49+
description: |
50+
If specified we upload process dump in addition to Dotnetdumper triage results
51+
52+
sources:
53+
- query: |
54+
LET tempfolder <= str(str=tempdir())
55+
56+
LET processes <= SELECT
57+
Name AS ProcessName,
58+
ImagePathName AS Exe,
59+
CommandLine,
60+
Pid,
61+
Env.PROCESSOR_ARCHITECTURE AS Type,
62+
path_join(components=[tempfolder, str(str=Pid)]) AS OutPath,
63+
parse_pe(file=ImagePathName) AS __PEInfo
64+
FROM Artifact.Windows.Memory.ProcessInfo(
65+
ProcessNameRegex=ProcessRegex,
66+
PidRegex=PidRegex)
67+
WHERE __PEInfo.Imports =~ 'mscoree' OR __PEInfo.Directories.DotNet_Directory
68+
69+
LET fetch_x64 <= SELECT *
70+
FROM if(condition=processes.Type =~ "AMD64",
71+
then={
72+
SELECT *
73+
FROM Artifact.Generic.Utils.FetchBinary(ToolName="DotNetDumper")
74+
},
75+
else=FALSE)
76+
77+
LET fetch_x86 <= SELECT *
78+
FROM if(condition=processes.Type =~ "x86",
79+
then={
80+
SELECT *
81+
FROM Artifact.Generic.Utils.FetchBinary(ToolName="DotNetDumper_x86")
82+
},
83+
else=FALSE)
84+
85+
LET fetch_arm64 <= SELECT *
86+
FROM if(condition=processes.Type =~ "ARM64",
87+
then={
88+
SELECT *
89+
FROM Artifact.Generic.Utils.FetchBinary(ToolName="DotNetDumper_arm64")
90+
},
91+
else=FALSE)
92+
93+
LET find_arch(type) = get(member=type,
94+
item=dict(AMD64=fetch_x64[0].OSPath,
95+
x86=fetch_x86[0].OSPath,
96+
ARM64=fetch_arm64[0].OSPath))
97+
98+
LET collection <= SELECT *
99+
FROM foreach(row=processes,
100+
query={
101+
SELECT *, Type,
102+
ProcessName,
103+
Pid,
104+
Exe,
105+
CommandLine,
106+
OutPath
107+
FROM execve(argv=[find_arch(type=Type), "--pid",
108+
Pid, OutPath, "--json", "--encode",EncodeKey],
109+
length=999999999)
110+
})
111+
112+
LET find_dmp(path) = SELECT * FROM glob(globs="*.dmp",root=path)
113+
114+
LET results <= SELECT
115+
*, parse_json(data=read_file(filename=path_join(
116+
components=[OutPath, "modules.json"]))) AS Modules,
117+
parse_json(
118+
data=read_file(
119+
filename=path_join(
120+
components=[OutPath, "patch_detection.json"]))) AS PatchDetection
121+
FROM collection
122+
123+
LET list_assemblies(path) = SELECT
124+
Name,
125+
upload(
126+
accessor='data',
127+
file=crypto_rc4(key=EncodeKey, string=read_file(filename=OSPath)),
128+
name=Name ) as Assembly
129+
FROM glob(globs="assemblies/*", root=path)
130+
131+
LET final = SELECT
132+
Pid,
133+
ProcessName,
134+
CommandLine,
135+
Type,
136+
list_assemblies(path=OutPath).Assembly AS Assemblies,
137+
upload(name="managed_strings_suspicious.txt",
138+
file=path_join(
139+
components=[OutPath, "managed_strings_suspicious.txt"])) AS SuspiciousManagedStrings,
140+
upload(
141+
name="managed_strings_all.txt",
142+
file=path_join(
143+
components=[OutPath, "managed_strings_all.txt"])) AS AllManagedStrings,
144+
OutPath as __Outpath
145+
FROM results
146+
147+
LET upload_dmp = SELECT *, upload(file=find_dmp(path=__Outpath)[0].OSPath) as Dmp
148+
FROM final
149+
150+
SELECT * FROM if(condition= UploadDmp,
151+
then= upload_dmp,
152+
else= final )
153+
154+
- name: Modules
155+
query: |
156+
SELECT *
157+
FROM foreach(row=results,
158+
query={
159+
SELECT Pid,
160+
ProcessName,
161+
*
162+
FROM Modules.modules
163+
})
164+
- name: PatchDetection
165+
query: |
166+
LET lookup <= SELECT *
167+
FROM results
168+
169+
SELECT *
170+
FROM foreach(row=results,
171+
query={
172+
SELECT Pid,
173+
ProcessName,
174+
*
175+
FROM PatchDetection.findings
176+
})
177+
column_types:
178+
- name: SuspiciousManagedStrings
179+
type: preview_upload
180+
- name: AllManagedStrings
181+
type: preview_upload
182+
- name: Dmp
183+
type: preview_upload

layouts/404.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html lang="{{ .Page.Language | default "en" }}" class="js csstransforms3d">
33

44
<head>
5-
<meta charset="utf-8"> {{ partial "meta.html" . }} {{ partial "favicon.html" . }} {{ .Scratch.Add "title" "" }}{{ if eq .Site.Data.titles .Title }}{{ .Scratch.Set "title" (index .Site.Data.titles .Title).title }}{{ else }}{{ .Scratch.Set "title" .Title}}{{end}}
5+
<meta charset="utf-8"> {{ partial "meta.html" . }} {{ partial "favicon.html" . }} {{ .Scratch.Add "title" "" }}{{ if eq hugo.Data.titles .Title }}{{ .Scratch.Set "title" (index hugo.Data.titles .Title).title }}{{ else }}{{ .Scratch.Set "title" .Title}}{{end}}
66
<title>{{ .Scratch.Get "title" }}</title>
77

88
{{ $assetBusting := not .Site.Params.disableAssetsBusting }}

layouts/_default/rss.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<link>{{ .Permalink }}</link>
3333
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
3434
<generator>Hugo</generator>
35-
<language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
35+
<language>{{ site.Language.Locale }}</language>{{ with $authorEmail }}
3636
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
3737
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
3838
<copyright>{{ . }}</copyright>{{ end }}{{ if not .Date.IsZero }}

layouts/shortcodes/release_download.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{ $r := .Page.Params.release }}
22
{{ $br := .Page.Params.base_release }}
3-
{{ $brands := $.Site.Data.icons.brands }}
3+
{{ $brands := hugo.Data.icons.brands }}
44

55
<h3>Release {{ $r }}</h3>
66

0 commit comments

Comments
 (0)