Skip to content

Commit 6e9efb8

Browse files
committed
docs: Docs changes for 2.4.0
1 parent 0ac4563 commit 6e9efb8

File tree

18 files changed

+335
-133
lines changed

18 files changed

+335
-133
lines changed

docs/_coverpage.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<img src='logo.png' height="800px" width="800px"></img>
55
</div>
66

7-
# fibratus <small>2.3.0</small>
7+
# fibratus <small>2.4.0</small>
88

99
> Adversary tradecraft detection, protection, and hunting
1010

docs/_sidebar.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
* [Registry](kevents/registry.md)
1515
* [Network](kevents/network.md)
1616
* [Handle](kevents/handle.md)
17+
* [Object](kevents/object.md)
1718
* [Driver](kevents/driver.md)
1819
* [Memory](kevents/mem.md)
1920
* <ion-icon name="filter-outline"></ion-icon> Filters and Rules
2021
* [Needle In The Haystack](filters/introduction.md)
2122
* [Prefiltering](filters/prefiltering.md)
2223
* [Filtering](filters/filtering.md)
2324
* [Operators](filters/operators.md)
24-
* [Paths](filters/paths.md)
25+
* [Iterators](filters/iterators.md)
2526
* [Functions](filters/functions.md)
2627
* [Rules](filters/rules.md)
2728
* [Fields](filters/fields.md)

docs/filters/fields.md

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,31 @@ The following tables summarize available field names that can be used in filter
115115
| thread.access.mask.names | Thread access human-readable rights | `thread.access.mask.names in ('QUERY_LIMITED_INFORMATION')` |
116116
| thread.access.status | Thread access status | `thread.access.status = 'Success'` |
117117
| thread.teb_address | The base address of the thread environment block | `thread.teb_address = '8f30893000'` |
118+
| thread.start_address.symbol | Thread start address symbol | `thread.start_address.symbol = 'LoadImage'` |
119+
| thread.start_address.module | Thread start address module | `thread.start_address.module endswith 'kernel32.dll'` |
120+
121+
122+
### Threadpool
123+
124+
| Field Name | Description | Example |
125+
| :--- | :---- | :---: |
126+
| threadpool.id | Thread pool identifier | `threadpool.id = '20f5fc02440'` |
127+
| threadpool.task.id | Thread pool task identifier | `threadpool.task.id = '20f7ecd21f8'` |
128+
| threadpool.callback.address | Thread pool callback address | `threadpool.callback.address = '7ff868739ed0'` |
129+
| threadpool.callback.symbol | Thread pool callback address symbol | `threadpool.callback.symbol = 'RtlDestroyQueryDebugBuffer'` |
130+
| threadpool.callback.module | Thread pool callback address module | `threadpool.callback.module contains 'ntdll.dll'` |
131+
| threadpool.callback.context | Thread pool callback context address | `threadpool.callback.context = '1df41e07bd0'` |
132+
| threadpool.callback.context.rip | Thread pool callback thread context instruction pointer | `threadpool.callback.context.rip = '1df42ffc1f8'` |
133+
| threadpool.callback.context.rip.symbol | Thread pool callback thread context instruction pointer symbol | `threadpool.callback.context.rip.symbol = 'VirtualProtect'` |
134+
| threadpool.callback.context.rip.module | Thread pool callback thread context instruction pointer module | `threadpool.callback.context.rip.module contains 'ntdll.dll'` |
135+
| threadpool.subprocess_tag | Thread pool service identifier | `threadpool.subprocess_tag = '10d'` |
136+
| threadpool.timer.duetime | Thread pool timer due time | `threadpool.timer.duetime > 10` |
137+
| threadpool.timer.subqueue | Thread pool timer subqueue address | `threadpool.timer.subqueue = '1db401703e8'` |
138+
| threadpool.timer.address | Thread pool timer address | `threadpool.timer.address = '3e8'` |
139+
| threadpool.timer.period | Thread pool timer period | `threadpool.timer.period = 0` |
140+
| threadpool.timer.window | Thread pool timer tolerate period | `threadpool.timer.window = 0` |
141+
| threadpool.timer.is_absolute | Indicates if the thread pool timer is absolute or relative | `threadpool.timer.is_absolute = true` |
142+
118143

119144
### Callstack
120145
| Field Name | Description | Example |
@@ -128,12 +153,23 @@ The following tables summarize available field names that can be used in filter
128153
| thread.callstack.callsite_leading_assembly | Callsite leading assembly instructions | `thread.callstack.callsite_leading_assembly in ('mov r10,rcx', 'syscall')` |
129154
| thread.callstack.callsite_trailing_assembly | Callsite trailing assembly instructions | `thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')` |
130155
| thread.callstack.is_unbacked | Indicates if the callstack contains unbacked regions | `thread.callstack.is_unbacked` |
131-
156+
| thread.callstack.addresses | List of all callstack return addresses | `thread.callstack.addresses in ('7ffb5c1d0396')` |
157+
| thread.callstack.final_user_module.name | The final user module name | `thread.callstack.final_user_module.name != 'ntdll.dll'` |
158+
| thread.callstack.final_user_module.path | The final user module path | `thread.callstack.final_user_module.path imatches '?:\\Windows\\System32\\ntdll.dll'` |
159+
| thread.callstack.final_user_symbol.name | The final user symbol name | `thread.callstack.final_user_symbol.name imatches 'CreateProcess*'` |
160+
| thread.callstack.final_kernel_module.name | The final kernel module name | `thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'` |
161+
| thread.callstack.final_kernel_module.path | The final kernel module path | `thread.callstack.final_kernel_module.path imatches '?:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'` |
162+
| thread.callstack.final_kernel_symbol.name | The final kernel symbol name | `thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'` |
163+
| thread.callstack.final_user_module.signature.is_signed | Indicates if the final user module is signed | `thread.callstack.final_user_module.signature.is_signed = true` |
164+
| thread.callstack.final_user_module.signature.is_trusted | Indicates if the final user module signature is trusted | `thread.callstack.final_user_module.signature.is_trusted = true` |
165+
| thread.callstack.final_user_module.signature.cert.issuer | The final user module signature certificate issuer | `thread.callstack.final_user_module.signature.cert.issuer imatches '*Microsoft Corporation*'` |
166+
| thread.callstack.final_user_module.signature.cert.subject | The final user module signature certificate subject | `thread.callstack.final_user_module.signature.cert.subject imatches '*Microsoft Windows*'` |
132167

133168
### Image
134169
| Field Name | Description | Example |
135170
| :--- | :---- | :---: |
136-
| image.name | Full image path | `image.name = 'C:\\Windows\\System32\\advapi32.dll'` |
171+
| image.path | Full image path | `image.name = 'C:\\Windows\\System32\\advapi32.dll'` |
172+
| image.name | Image name | `image.name = 'advapi32.dll'` |
137173
| image.base.address | Base address of the process in which the image is loaded | `image.base.address = 'a65d800000'` |
138174
| image.checksum | Image checksum | `image.checksum = 746424` |
139175
| image.size | Image size | `image.size > 1024` |
@@ -156,7 +192,8 @@ The following tables summarize available field names that can be used in filter
156192
| Field Name | Description | Example |
157193
| :--- | :---- | :---: |
158194
| file.object | File object address in the kernel space | `file.object = 18446738026482168384` |
159-
| file.name | Full file name | `file.name = 'C:\\Windows\\Sytem32\\regedit.exe'` |
195+
| file.path | Full file path | `file.name = 'C:\\Windows\\Sytem32\\regedit.exe'` |
196+
| file.name | File name | `file.name = 'regedit.exe'` |
160197
| file.operation | Operation performed on the file or I/O device | `file.operation = 'OPEN'` |
161198
| file.share.mask | File share mask | `file.share.mask = 'READ'` |
162199
| file.io.size | I/O read/write size | `file.io.size > 512` |
@@ -183,7 +220,8 @@ The following tables summarize available field names that can be used in filter
183220
### Registry
184221
| Field Name | Description | Example |
185222
| :--- | :---- | :---: |
186-
| registry.key.name | Fully qualified key name | `registry.key.name = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services'` |
223+
| registry.path | Fully qualified registry path | `registry.path = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services'` |
224+
| registry.key.name | Base registry key name | `registry.key.name = 'Services'` |
187225
| registry.key.handle | Registry key object address | `registry.key.handle = 'FFFFB905D60C2268'` |
188226
| registry.value | Registry value content | `registry.value = '%SystemRoot%\\system32'` |
189227
| registry.value.type | Registry value type | `registry.value.type = 'REG_SZ'` |

docs/filters/functions.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ Additionally, some functions may return a collection of values. Function names a
237237
```
238238
- `string`: Input string
239239
- `start`: Substring start index
240-
- `end`: Substring end index
240+
- `end`: Substring end index (optional)
241241
- `return` a substring contained within start and end indices
242242
243243
- **Examples**
@@ -246,6 +246,7 @@ Additionally, some functions may return a collection of values. Function names a
246246
247247
```
248248
substr(file.name, indexof(file.name, '\\'), indexof(file.name, '\\Hard')) = '\\Device'
249+
substr(file.name, indexof(file.name, 'system32')) = 'system32\\user32.dll'
249250
```
250251
251252
#### entropy

docs/filters/iterators.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Iterators
2+
3+
`foreach` idiom adds iteration capabilities to the rule language. Under the hood, `foreach` is implemented as a function that accepts three required and multiple optional arguments. The first argument is the `iterable` value typically yielded by the pseudo field.
4+
5+
The function recognizes process internal state collections such as modules, threads, memory mappings, or thread stack frames. Obviously, it is also possible to iterate over simple string slices. The second argument represents the `bound variable` which is an item associated with every element in the slice. The bound variable is accessed in the third argument, the `predicate`. It is usually followed by the `segment` that denotes the accessed value. Unsurprisingly, the predicate is commonly a binary expression that can be formed of `not/paren` expressions, other functions, and so on. The predicate is executed on every item in the slice. If the predicate evaluates to true, the function also returns the true value.
6+
7+
Lastly, foreach function can receive an optional `list of fields` from the outer context, i.e. outside predicate loop. Therefore, for the predicate to access the field not defined within the scope of the iterable, it must capture the field first.
8+
9+
Some examples of the `foreach` usage:
10+
11+
- Traverses process modules and return true if the module path matches the pattern
12+
13+
```
14+
foreach(ps._modules, $mod, $mod.path imatches '?:\\Windows\\System32\\us?r32.dll')
15+
```
16+
17+
- For each process ancestor, check if the ancestor is `services.exe` and the current process is protected. In this example, the `ps.is_protected` field is captured before its usage in the predicate
18+
19+
```
20+
foreach(ps._ancestors, $proc, $proc.name = 'services.exe' and ps.is_protected, ps.is_protected)
21+
```
22+
23+
## Process iterators {docsify-ignore}
24+
25+
The `ps.ancestor` returns all ancestor names of the process generating the event. Alternatively, the filter field can accept an argument. In case of the `ps.ancestor` field, the argument indicates the ancestor level. Given the process tree below and assuming the current process generating the event is `cmd.exe`, the field with an optional level argument yields the values as follows:
26+
27+
```
28+
├───wininit.exe
29+
│ └───services.exe
30+
│ └───svchost.exe
31+
│ └───dllhost.exe
32+
│ ├───cmd.exe
33+
│ └───winword.exe
34+
```
35+
36+
- `ps.ancestor[1]` returns `dllhost.exe`
37+
- `ps.ancestor[3]` returns `services.exe`
38+
- `ps.ancestor[4]` returns `wininit.exe`
39+
40+
If the argument is omitted, the slice with all ancestor names is returned. The `ps.ancestor` field can only yield a single process attribute - process name. To build complex conditions involving different process attribute, we can use the `foreach` construct. The bound variable associated with the `ps._ancestors` pseudo field can have the any of the segments:
41+
42+
| Segment Name | Description |
43+
| :--- | :---- |
44+
|`pid` | Process identifier |
45+
|`name` | Process name |
46+
|`args` | Process command line arguments as a list of strings |
47+
|`cmdline` | Process command line argument as a raw string |
48+
|`cwd` | Process current working directory |
49+
|`exe` | Process image path |
50+
|`sid` | Process SID (security identifier) |
51+
|`sessionid` | Process session identifier |
52+
|`username` | User name associated with the process security context |
53+
|`domain` | Domain associated with the process security context |
54+
55+
Examples
56+
57+
- Check if the ancestor has one of the particular process identifiers and the pid belongs to the `services.exe` process
58+
59+
```
60+
foreach(ps._ancestors, $proc, $proc.pid in (2034, 343) and $proc.name = 'services.exe')
61+
```
62+
63+
- Check if the ancestor starts with the specific security identifier and the pid belongs to the `svchost.exe` process
64+
65+
```
66+
foreach(ps._ancestors, $proc, $proc.sid imatches `S-1-5*` and $proc.name = 'svchost.exe')
67+
```
68+
69+
70+
### Modules {docsify-ignore}
71+
72+
The `ps._modules` pseudo field returns the process modules iterable. Available module segments are:
73+
74+
75+
| Segment Name | Description |
76+
| :--- | :---- |
77+
|`address` | Base address of the process in which the module is loaded|
78+
|`checksum` | Module checksum |
79+
|`size` | Module size in terms of allocated virtual address space |
80+
|`name` | Module name |
81+
|`path` | Full module path |
82+
83+
Examples
84+
85+
- Check the virtual memory space size of the specific module
86+
87+
```
88+
foreach(ps._modules, $mod, $mod.size >= 212354 and $mod.name imatches '*winhttp.dll')
89+
```
90+
91+
### Threads {docsify-ignore}
92+
93+
The `ps._threads` pseudo field yields all of the process running threads. Available thread segments are:
94+
95+
96+
| Segment Name | Description |
97+
| :--- | :---- |
98+
|`tid` | Thread identifier |
99+
|`start_address` | The address of the function executed by the thread |
100+
|`user_stack_base` | The base address of the thread userspace stack |
101+
|`user_stack_limit` | The address denoting the thread userspace stack limit |
102+
|`kernel_stack_base` | The base address of the thread kernel stack |
103+
|`kernel_stack_limit` | he address denoting the thread kernel stack limit |
104+
105+
### Memory mappings {docsify-ignore}
106+
107+
Process memory mappings (also known as sections) can be accessed via the `ps._mmaps` pseudo field. Available memory mappings segments are:
108+
109+
| Segment Name | Description |
110+
| :--- | :---- |
111+
|`address` | Address where the section is mapped within the process address space |
112+
|`type` | The type of the memory mapping. For example, `DATA`. |
113+
|`size` | Size in bytes of the memory mapping |
114+
|`protection` | Protection attributes of the mapped memory section |
115+
|`path` | If the memory mapping is backed by a physical file, indicates the path of the file |
116+
117+
### Environment variables {docsify-ignore}
118+
119+
You can access process environment variables by providing the name of the environment variable. Alternatively, you can provide the prefix.
120+
121+
```
122+
ps.envs['MOZ_CRASHREPORTER'] = 'C:\\Program Files\\Firefox'
123+
```
124+
125+
Or, supplying the prefix
126+
127+
```
128+
ps.envs['MOZ_CRASH'] = 'C:\\Program Files\\Firefox'
129+
```
130+
131+
It is also possible to retrieve all environment variables as a list of colon separated key/value pairs. Example using the `foreach` idiom:
132+
133+
```
134+
foreach(ps.envs, $env, substr($env, 0, indexof($env, ':')) = 'OS')
135+
```
136+
137+
## Portable Executable iterators {docsify-ignore}
138+
139+
[Portable Executable](/pe/introduction) introspection allows for utilizing the PE metadata in filters. See other [fields](filters/fields?id=pe) that can be used to narrow down events by PE data.
140+
141+
### Sections {docsify-ignore}
142+
143+
The `pe._sections` pseudo field yields all of the executable image PE sections. Available section segments are:
144+
145+
| Segment Name | Description |
146+
| :--- | :---- |
147+
|`name` | Section name. For example, `.debug$` |
148+
|`size` | Section size in bytes |
149+
|`entropy` | Section entropy |
150+
|`md5` | Section MD5 hash |
151+
152+
### Resources {docsify-ignore}
153+
154+
PE [resources](/pe/resources) can be accessed by the resource name. Alternatively, it is possible to obtain all the resources as a list separated by the colon delimiter:
155+
156+
```
157+
pe.resources iin ('FileDescription:Notepad')
158+
```
159+
160+
161+
## Callstack {docsify-ignore}
162+
163+
[Stack enrichment](/kevents/anatomy?id=callstack) attaches call frames that can be accessed by the `thread._callstack` pseudo field. Available callstsack segments are:
164+
165+
| Segment Name | Description |
166+
| :--- | :---- |
167+
|`address` | Symbol address |
168+
|`offset` | Symbol offset |
169+
|`symbol` | Symbol name |
170+
|`module` | Module name containing the frame |
171+
|`allocation_size` | Private allocation size |
172+
|`protection` | Frame protection mask |
173+
|`is_unbacked` | Indicates if the frame is unbacked |
174+
|`callsite_leading_assembly` | Callsite leading assembly instructions |
175+
|`callsite_trailing_assembly` | Callsite trailing assembly instructions|
176+
|`module.signature.is_signed` | Indicates if the frame module is signed |
177+
|`module.signature.is_trusted` | Indicates if the frame module signature is trusted |
178+
|`module.signature.cert.subject` | Frame module signature certificate subject |
179+
|`module.signature.cert.issuer` | Frame module signature certificate issuer |
180+
181+
Examples:
182+
183+
- Determine if the frame protection is RWX (Read-Write-Execute)
184+
185+
```
186+
foreach(thread._callstack, $frame, $frame.protection = 'RWX')
187+
```
188+
189+
- Determine if the frame trailing assembly contain the `syscall` instruction and the frame resides in the floating memory region
190+
191+
```
192+
foreach(thread._callstack, $frame, $frame.callsite_trailing_assembly matches '*mov r10, rcx|mov eax, 0x*|syscall*' and $frame.module = 'unbacked')
193+
```

docs/filters/operators.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ String operators are applied to string field types or string literals.
118118

119119
```
120120
fibratus run ps.name endswith '.exe'
121+
```
122+
123+
### intersects, iintersects
124+
125+
`intersects` operator and its case-insensitive `iintersects` variant operate on string slices. If all elements in the RHS slice are present in the slice given by LHS, the operator evaluates to `true`. Otherwise, it evaluates to `false`.
126+
127+
- **Example**
128+
129+
Filter events where the originating process command line arguments contain both `DcomLaunch` and `LSM` arguments
130+
131+
```
132+
fibratus run ps.args intersects ('DcomLaunch', 'LSM')
133+
```
121134
122135
### matches, imatches
123136

0 commit comments

Comments
 (0)