diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 25598349b..cea7ba557 100755 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -4,7 +4,7 @@ -# fibratus 2.3.0 +# fibratus 2.4.0 > Adversary tradecraft detection, protection, and hunting diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 0134d95e1..74c8de9dd 100755 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -14,6 +14,7 @@ * [Registry](kevents/registry.md) * [Network](kevents/network.md) * [Handle](kevents/handle.md) + * [Object](kevents/object.md) * [Driver](kevents/driver.md) * [Memory](kevents/mem.md) * Filters and Rules @@ -21,7 +22,7 @@ * [Prefiltering](filters/prefiltering.md) * [Filtering](filters/filtering.md) * [Operators](filters/operators.md) - * [Paths](filters/paths.md) + * [Iterators](filters/iterators.md) * [Functions](filters/functions.md) * [Rules](filters/rules.md) * [Fields](filters/fields.md) diff --git a/docs/filters/fields.md b/docs/filters/fields.md index ce4c86f78..2fb7fb61a 100755 --- a/docs/filters/fields.md +++ b/docs/filters/fields.md @@ -115,6 +115,31 @@ The following tables summarize available field names that can be used in filter | thread.access.mask.names | Thread access human-readable rights | `thread.access.mask.names in ('QUERY_LIMITED_INFORMATION')` | | thread.access.status | Thread access status | `thread.access.status = 'Success'` | | thread.teb_address | The base address of the thread environment block | `thread.teb_address = '8f30893000'` | +| thread.start_address.symbol | Thread start address symbol | `thread.start_address.symbol = 'LoadImage'` | +| thread.start_address.module | Thread start address module | `thread.start_address.module endswith 'kernel32.dll'` | + + +### Threadpool + +| Field Name | Description | Example | +| :--- | :---- | :---: | +| threadpool.id | Thread pool identifier | `threadpool.id = '20f5fc02440'` | +| threadpool.task.id | Thread pool task identifier | `threadpool.task.id = '20f7ecd21f8'` | +| threadpool.callback.address | Thread pool callback address | `threadpool.callback.address = '7ff868739ed0'` | +| threadpool.callback.symbol | Thread pool callback address symbol | `threadpool.callback.symbol = 'RtlDestroyQueryDebugBuffer'` | +| threadpool.callback.module | Thread pool callback address module | `threadpool.callback.module contains 'ntdll.dll'` | +| threadpool.callback.context | Thread pool callback context address | `threadpool.callback.context = '1df41e07bd0'` | +| threadpool.callback.context.rip | Thread pool callback thread context instruction pointer | `threadpool.callback.context.rip = '1df42ffc1f8'` | +| threadpool.callback.context.rip.symbol | Thread pool callback thread context instruction pointer symbol | `threadpool.callback.context.rip.symbol = 'VirtualProtect'` | +| threadpool.callback.context.rip.module | Thread pool callback thread context instruction pointer module | `threadpool.callback.context.rip.module contains 'ntdll.dll'` | +| threadpool.subprocess_tag | Thread pool service identifier | `threadpool.subprocess_tag = '10d'` | +| threadpool.timer.duetime | Thread pool timer due time | `threadpool.timer.duetime > 10` | +| threadpool.timer.subqueue | Thread pool timer subqueue address | `threadpool.timer.subqueue = '1db401703e8'` | +| threadpool.timer.address | Thread pool timer address | `threadpool.timer.address = '3e8'` | +| threadpool.timer.period | Thread pool timer period | `threadpool.timer.period = 0` | +| threadpool.timer.window | Thread pool timer tolerate period | `threadpool.timer.window = 0` | +| threadpool.timer.is_absolute | Indicates if the thread pool timer is absolute or relative | `threadpool.timer.is_absolute = true` | + ### Callstack | Field Name | Description | Example | @@ -128,12 +153,23 @@ The following tables summarize available field names that can be used in filter | thread.callstack.callsite_leading_assembly | Callsite leading assembly instructions | `thread.callstack.callsite_leading_assembly in ('mov r10,rcx', 'syscall')` | | thread.callstack.callsite_trailing_assembly | Callsite trailing assembly instructions | `thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')` | | thread.callstack.is_unbacked | Indicates if the callstack contains unbacked regions | `thread.callstack.is_unbacked` | - +| thread.callstack.addresses | List of all callstack return addresses | `thread.callstack.addresses in ('7ffb5c1d0396')` | +| thread.callstack.final_user_module.name | The final user module name | `thread.callstack.final_user_module.name != 'ntdll.dll'` | +| thread.callstack.final_user_module.path | The final user module path | `thread.callstack.final_user_module.path imatches '?:\\Windows\\System32\\ntdll.dll'` | +| thread.callstack.final_user_symbol.name | The final user symbol name | `thread.callstack.final_user_symbol.name imatches 'CreateProcess*'` | +| thread.callstack.final_kernel_module.name | The final kernel module name | `thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'` | +| thread.callstack.final_kernel_module.path | The final kernel module path | `thread.callstack.final_kernel_module.path imatches '?:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'` | +| thread.callstack.final_kernel_symbol.name | The final kernel symbol name | `thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'` | +| 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` | +| 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` | +| 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*'` | +| 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*'` | ### Image | Field Name | Description | Example | | :--- | :---- | :---: | -| image.name | Full image path | `image.name = 'C:\\Windows\\System32\\advapi32.dll'` | +| image.path | Full image path | `image.name = 'C:\\Windows\\System32\\advapi32.dll'` | +| image.name | Image name | `image.name = 'advapi32.dll'` | | image.base.address | Base address of the process in which the image is loaded | `image.base.address = 'a65d800000'` | | image.checksum | Image checksum | `image.checksum = 746424` | | image.size | Image size | `image.size > 1024` | @@ -156,7 +192,8 @@ The following tables summarize available field names that can be used in filter | Field Name | Description | Example | | :--- | :---- | :---: | | file.object | File object address in the kernel space | `file.object = 18446738026482168384` | -| file.name | Full file name | `file.name = 'C:\\Windows\\Sytem32\\regedit.exe'` | +| file.path | Full file path | `file.name = 'C:\\Windows\\Sytem32\\regedit.exe'` | +| file.name | File name | `file.name = 'regedit.exe'` | | file.operation | Operation performed on the file or I/O device | `file.operation = 'OPEN'` | | file.share.mask | File share mask | `file.share.mask = 'READ'` | | 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 ### Registry | Field Name | Description | Example | | :--- | :---- | :---: | -| registry.key.name | Fully qualified key name | `registry.key.name = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services'` | +| registry.path | Fully qualified registry path | `registry.path = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services'` | +| registry.key.name | Base registry key name | `registry.key.name = 'Services'` | | registry.key.handle | Registry key object address | `registry.key.handle = 'FFFFB905D60C2268'` | | registry.value | Registry value content | `registry.value = '%SystemRoot%\\system32'` | | registry.value.type | Registry value type | `registry.value.type = 'REG_SZ'` | diff --git a/docs/filters/functions.md b/docs/filters/functions.md index 492f4ca03..ca551a39d 100644 --- a/docs/filters/functions.md +++ b/docs/filters/functions.md @@ -237,7 +237,7 @@ Additionally, some functions may return a collection of values. Function names a ``` - `string`: Input string - `start`: Substring start index - - `end`: Substring end index + - `end`: Substring end index (optional) - `return` a substring contained within start and end indices - **Examples** @@ -246,6 +246,7 @@ Additionally, some functions may return a collection of values. Function names a ``` substr(file.name, indexof(file.name, '\\'), indexof(file.name, '\\Hard')) = '\\Device' + substr(file.name, indexof(file.name, 'system32')) = 'system32\\user32.dll' ``` #### entropy diff --git a/docs/filters/iterators.md b/docs/filters/iterators.md new file mode 100644 index 000000000..f3933a135 --- /dev/null +++ b/docs/filters/iterators.md @@ -0,0 +1,193 @@ +# Iterators + +`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. + +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. + +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. + +Some examples of the `foreach` usage: + +- Traverses process modules and return true if the module path matches the pattern + +``` +foreach(ps._modules, $mod, $mod.path imatches '?:\\Windows\\System32\\us?r32.dll') +``` + +- 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 + +``` +foreach(ps._ancestors, $proc, $proc.name = 'services.exe' and ps.is_protected, ps.is_protected) +``` + +## Process iterators {docsify-ignore} + +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: + +``` +├───wininit.exe +│ └───services.exe +│ └───svchost.exe +│ └───dllhost.exe +│ ├───cmd.exe +│ └───winword.exe +``` + +- `ps.ancestor[1]` returns `dllhost.exe` +- `ps.ancestor[3]` returns `services.exe` +- `ps.ancestor[4]` returns `wininit.exe` + +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: + +| Segment Name | Description | +| :--- | :---- | +|`pid` | Process identifier | +|`name` | Process name | +|`args` | Process command line arguments as a list of strings | +|`cmdline` | Process command line argument as a raw string | +|`cwd` | Process current working directory | +|`exe` | Process image path | +|`sid` | Process SID (security identifier) | +|`sessionid` | Process session identifier | +|`username` | User name associated with the process security context | +|`domain` | Domain associated with the process security context | + +Examples + +- Check if the ancestor has one of the particular process identifiers and the pid belongs to the `services.exe` process + +``` +foreach(ps._ancestors, $proc, $proc.pid in (2034, 343) and $proc.name = 'services.exe') +``` + +- Check if the ancestor starts with the specific security identifier and the pid belongs to the `svchost.exe` process + +``` +foreach(ps._ancestors, $proc, $proc.sid imatches `S-1-5*` and $proc.name = 'svchost.exe') +``` + + +### Modules {docsify-ignore} + +The `ps._modules` pseudo field returns the process modules iterable. Available module segments are: + + +| Segment Name | Description | +| :--- | :---- | +|`address` | Base address of the process in which the module is loaded| +|`checksum` | Module checksum | +|`size` | Module size in terms of allocated virtual address space | +|`name` | Module name | +|`path` | Full module path | + +Examples + +- Check the virtual memory space size of the specific module + +``` +foreach(ps._modules, $mod, $mod.size >= 212354 and $mod.name imatches '*winhttp.dll') +``` + +### Threads {docsify-ignore} + +The `ps._threads` pseudo field yields all of the process running threads. Available thread segments are: + + +| Segment Name | Description | +| :--- | :---- | +|`tid` | Thread identifier | +|`start_address` | The address of the function executed by the thread | +|`user_stack_base` | The base address of the thread userspace stack | +|`user_stack_limit` | The address denoting the thread userspace stack limit | +|`kernel_stack_base` | The base address of the thread kernel stack | +|`kernel_stack_limit` | he address denoting the thread kernel stack limit | + +### Memory mappings {docsify-ignore} + +Process memory mappings (also known as sections) can be accessed via the `ps._mmaps` pseudo field. Available memory mappings segments are: + +| Segment Name | Description | +| :--- | :---- | +|`address` | Address where the section is mapped within the process address space | +|`type` | The type of the memory mapping. For example, `DATA`. | +|`size` | Size in bytes of the memory mapping | +|`protection` | Protection attributes of the mapped memory section | +|`path` | If the memory mapping is backed by a physical file, indicates the path of the file | + +### Environment variables {docsify-ignore} + +You can access process environment variables by providing the name of the environment variable. Alternatively, you can provide the prefix. + +``` +ps.envs['MOZ_CRASHREPORTER'] = 'C:\\Program Files\\Firefox' +``` + +Or, supplying the prefix + +``` +ps.envs['MOZ_CRASH'] = 'C:\\Program Files\\Firefox' +``` + +It is also possible to retrieve all environment variables as a list of colon separated key/value pairs. Example using the `foreach` idiom: + +``` +foreach(ps.envs, $env, substr($env, 0, indexof($env, ':')) = 'OS') +``` + +## Portable Executable iterators {docsify-ignore} + +[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. + +### Sections {docsify-ignore} + +The `pe._sections` pseudo field yields all of the executable image PE sections. Available section segments are: + +| Segment Name | Description | +| :--- | :---- | +|`name` | Section name. For example, `.debug$` | +|`size` | Section size in bytes | +|`entropy` | Section entropy | +|`md5` | Section MD5 hash | + +### Resources {docsify-ignore} + +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: + +``` +pe.resources iin ('FileDescription:Notepad') +``` + + +## Callstack {docsify-ignore} + +[Stack enrichment](/kevents/anatomy?id=callstack) attaches call frames that can be accessed by the `thread._callstack` pseudo field. Available callstsack segments are: + +| Segment Name | Description | +| :--- | :---- | +|`address` | Symbol address | +|`offset` | Symbol offset | +|`symbol` | Symbol name | +|`module` | Module name containing the frame | +|`allocation_size` | Private allocation size | +|`protection` | Frame protection mask | +|`is_unbacked` | Indicates if the frame is unbacked | +|`callsite_leading_assembly` | Callsite leading assembly instructions | +|`callsite_trailing_assembly` | Callsite trailing assembly instructions| +|`module.signature.is_signed` | Indicates if the frame module is signed | +|`module.signature.is_trusted` | Indicates if the frame module signature is trusted | +|`module.signature.cert.subject` | Frame module signature certificate subject | +|`module.signature.cert.issuer` | Frame module signature certificate issuer | + +Examples: + +- Determine if the frame protection is RWX (Read-Write-Execute) + +``` +foreach(thread._callstack, $frame, $frame.protection = 'RWX') +``` + +- Determine if the frame trailing assembly contain the `syscall` instruction and the frame resides in the floating memory region + +``` +foreach(thread._callstack, $frame, $frame.callsite_trailing_assembly matches '*mov r10, rcx|mov eax, 0x*|syscall*' and $frame.module = 'unbacked') +``` \ No newline at end of file diff --git a/docs/filters/operators.md b/docs/filters/operators.md index e062c5ecb..2d6fc2a83 100755 --- a/docs/filters/operators.md +++ b/docs/filters/operators.md @@ -118,6 +118,19 @@ String operators are applied to string field types or string literals. ``` fibratus run ps.name endswith '.exe' + ``` + +### intersects, iintersects + +`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`. + +- **Example** + + Filter events where the originating process command line arguments contain both `DcomLaunch` and `LSM` arguments + + ``` + fibratus run ps.args intersects ('DcomLaunch', 'LSM') + ``` ### matches, imatches diff --git a/docs/filters/paths.md b/docs/filters/paths.md deleted file mode 100644 index b0e39de0b..000000000 --- a/docs/filters/paths.md +++ /dev/null @@ -1,117 +0,0 @@ -# Paths - -As you may have already noticed, different entities can appear in filter fields. For example, `ps` is the root entity that designates the source of process-related values. To access the value from the entity, the __path__ expression is used as a sequence of period-delimited segments that yield the final value. Thus, the `ps.name` field path gives the process name. Paths can be nested, like `ps.parent.handles`, to collect all handle names of the parent process. - -Paths can also be constructed in combination with array or map indexing. - -### Process ancestry {docsify-ignore} - -Walking the process tree is a useful feature when you want to capture events produced by the process that is a descendant of particular processes. For this purpose, various path segments with map indexing are available. - -#### Depth indexing - -Fetches the ancestor that is located at a specified depth starting from the current process. `ps.ancestor[1]` yields the immediate parent process and it is equivalent to using the `ps.parent` field. Imagine the following process tree: - -``` -├───wininit.exe -│ └───services.exe -│ └───svchost.exe -│ └───dllhost.exe -│ ├───cmd.exe -│ └───winword.exe -``` - -Assuming the `winword.exe` is the current process generating the event, we could write the following filter expression to check its ancestors: - -``` -$ fibratus run --forward ps.ancestor[1].name = 'dllhost.exe' or ps.ancestor[3].name = 'services.exe' -``` - -#### Root indexing - -To filter events where their ancestor process is the root of the process tree, you can employ the `root` key. Considering the same process tree as above, we can construct the following filter: - -``` -$ fibratus run --forward ps.ancestor[root].name = 'wininit.exe' -``` - -#### Any indexing - -If you want to match on multiple ancestors, use the `any` key. The following expression would filter all events where the process generating them has `svchost.exe` or `dllhost.exe` ancestors: - -``` -$ fibratus run --forward ps.ancestor[any].name in ('svchost.exe', 'dllhost.exe') -``` - -Besides the process name, several other path segments are available for returning the ancestor data: - -- `.pid` returns the process identifier -- `.args` gives process command line arguments as a list of strings -- `.comm` returns the process command line argument as a raw string -- `.cwd` fetches the process current working directory -- `.exe` returns the process image path -- `.sid` returns the process user/domain name -- `.sessionid` returns the process session identifier - -!> `any` returns a list of values specified by the path segment, and thus requires operators that evaluate on lists instead of simple primitive values. - -### Portable Executable {docsify-ignore} - -[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. - -#### Section indexing - -You can use the section name as an index to retrieve the data used for filter matching. For example, `ps.pe.sections[.debug$].size` would fetch the size of the `.debug$` section. - -Available path segments: - -- `.entropy` returns the section entropy -- `.md5` returns the section MD5 hash value - -#### Resource indexing - -PE [resources](/pe/resources) are accessed by the resource name. For example, the following filter would match all events where process PE resources contain the `github` company. - -``` -$ fibratus run --forward pe.resources[CompanyName] contains 'github' -``` - -### Modules {docsify-ignore} - -Process modules can be accessed by the module name. The file extension is omitted from the module name. For example: - -``` -$ fibratus run --forward ps.modules['crypt'].size > 1024 -``` - -Other paths segments you can use in modules indexing: - -- `.base.address` returns the base address of the process in which the module is loaded -- `.checksum` returns the checksum of the module file -- `.size` gives the module size -- `.default.address` returns the default image address - -### Callstack {docsify-ignore} - -[Stack enrichment](/kevents/anatomy?id=callstack) attaches call frames that can be accessed by various kinds of indices: - -- `ustart` accesses the first userspace callstack frame. (e.g. `thread.callstack[ustart].address = '2638e59e0a5'`) -- `uend` accesses the last (top-most) userspace callstack frame (e.g. `thread.callstack[uend].address = '7ffb5c1d0396'`) -- `kstart` accesses the first kernel space callstack frame (e.g. `thread.callstack[kstart].address = 'fffff8072ebc1f6f'`) -- `kend` accesses the last (top-most) kernel space callstack frame (e.g. `thread.callstack[kend].address = 'fffff8072eb8961b'`) -- frame index. The index `0` represents the least-recent frame, usually the base thread initialization frame. (e.g. `thread.callstack[2].symbol = 'Java_java_lang_ProcessImpl_create'`) -- module name. Returns the first frame that maps to the given module name. (e.g. `thread.callstack[kernelbase.dll].symbol = 'CreateProcessW'`) - -### Environment variables {docsify-ignore} - -You can access process environment variables by providing the name of the environment variable. Alternatively, you can provide the prefix. - -``` -$ fibratus run --forward ps.envs['MOZ_CRASHREPORTER'] = 'C:\\Program Files\\Firefox' -``` - -Or, supplying the prefix - -``` -$ fibratus run --forward ps.envs['MOZ_CRASH'] = 'C:\\Program Files\\Firefox' -``` \ No newline at end of file diff --git a/docs/filters/prefiltering.md b/docs/filters/prefiltering.md index 3981cca1a..29e26d430 100755 --- a/docs/filters/prefiltering.md +++ b/docs/filters/prefiltering.md @@ -13,6 +13,7 @@ The above is the summary of configuration options that influence the collection - `enable-audit-api` enables/disables kernel audit API calls events - `enable-mem` enables/disables the collection of memory events - `enable-dns` enables/disables DNS telemetry +- `enable-threadpool` enables/disables thread pool telemetry ### Excluding processes or events {docsify-ignore} diff --git a/docs/filters/rules.md b/docs/filters/rules.md index 5eb03c0c7..910593b5c 100644 --- a/docs/filters/rules.md +++ b/docs/filters/rules.md @@ -247,6 +247,17 @@ action: - name: kill ``` +#### Isolating endpoints + +`isolate` action isolates the host by installing **Windows Filtering Platform** (WFP) rules. To revert the effects of the `isolate` action, simply restart the Fibratus service. The action can be combined with other actions. For example, the following snippet will kill the process and isolate the endpoint. + + +```yaml +action: + - name: kill + - name: isolate +``` + ### Advanced patterns Adversaries often employ sophisticated techniques which may be daunting to detect without combining events from different data sources. For example, detecting a remote connection attempt followed by the execution of a command shell by the same process that initiated the connection can't be expressed with a simple rule expecting to match on a single event. Enter `sequence` rules. diff --git a/docs/kevents/anatomy.md b/docs/kevents/anatomy.md index 59db1cedd..2b9ef3199 100755 --- a/docs/kevents/anatomy.md +++ b/docs/kevents/anatomy.md @@ -63,9 +63,17 @@ Stack enrichment is performed for the following event set: - `RegDeleteKey` - `RegSetValue` - `RegDeleteValue` -- `CreateFile` (full symbolization is performed on events where create disposition is different than `OPEN`) +- `CreateFile` - `DeleteFile` - `RenameFile` +- `VirtualAlloc` +- `OpenProcess` +- `OpenThread` +- `CreateSymbolicLinkObject` +- `SubmitThreadpoolWork` +- `SubmitThreadpoolCallback` +- `SetThreadpoolTimer` + To enable stack enrichment for kernel space return addresses, the `symbolize-kernel-addresses` config option needs to be set to `true`. Callstack data is used by [filter fields](/filters/fields?id=callstack) to permit crafting advanced detection rules. diff --git a/docs/kevents/file.md b/docs/kevents/file.md index e406ba791..4234ac20d 100755 --- a/docs/kevents/file.md +++ b/docs/kevents/file.md @@ -20,7 +20,7 @@ The `CreateFile` event is triggered when the kernel serves create/open requests - `create_options` the options to be applied when creating or opening the file, as a compatible combination of the following values: `DIRECTORY_FILE`,`WRITE_THROUGH`, `SEQUENTIAL_ONLY`, `NO_INTERMEDIATE_BUFFERING`, `SYNCHRONOUS_IO_ALERT`, `SYNCHRONOUS_IO_NONALERT`, `NON_DIRECTORY_FILE`, `CREATE_TREE_CONNECTION`, `COMPLETE_IF_OPLOCKED`, `NO_EA_KNOWLEDGE`, `OPEN_REMOTE_INSTANCE`, `RANDOM_ACCESS`, `DELETE_ON_CLOSE`,`OPEN_BY_FILE_ID`, `FOR_BACKUP_INTENT`, `NO_COMPRESSION`, `OPEN_REQUIRING_OPLOCK`,`DISALLOW_EXCLUSIVE`, `RESERVE_OPFILTER`, `OPEN_REPARSE_POINT`, `OPEN_NO_RECALL` and `OPEN_FOR_FREE_SPACE_QUERY`. - `share_mask` specifies the sharing mode of the file or device, which can be the combination of `READ`, `WRITE`, and `DELETE` values. This flag determines the permission granularity which enables a process to share a file or device while another process has the file or device open. - `type` defines the file type. Possible values are `File`, `Directory`, `Pipe`, `Console`, `Mailslot`, `Other`, `Unknown`. -- `attributes` denotes the file attributes. Possible values are `READONLY`, `HIDDEN`, `SYSTEM`, `DIRECTORY`, `COMPRESSED`, `ENCRYPTED`, `HIDDEN`, `JUNCTION`, `SPARSE`,`TEMPORARY`, `DEVICE`, `NORMAL`, `OFFLINE`, `UNINDEXED`, `STREAM`, `VIRTUAL`, `NOSCRUB`, `RECALLOPEN`, `RECALLACCESS`, `PINNED`, `UNPINNED`, `UNKNOWN`. +- `attributes` denotes the file attributes. Possible values are `READONLY`, `HIDDEN`, `SYSTEM`, `DIRECTORY`, `COMPRESSED`, `ENCRYPTED`, `JUNCTION`, `SPARSE`,`TEMPORARY`, `DEVICE`, `NORMAL`, `OFFLINE`, `UNINDEXED`, `STREAM`, `VIRTUAL`, `NOSCRUB`, `RECALLOPEN`, `RECALLACCESS`, `PINNED`, `UNPINNED`, `UNKNOWN`. - `status` represents the system status message (e.g. `Success`) - `is_dll` determines if the created file is a DLL object. Only present when `create_disposition != OPEN`. - `is_driver` determines if the created file is a driver. Only present when `create_disposition != OPEN`. diff --git a/docs/kevents/object.md b/docs/kevents/object.md new file mode 100644 index 000000000..beba65ab3 --- /dev/null +++ b/docs/kevents/object.md @@ -0,0 +1,10 @@ +# Object manager events + +#### CreateSymbolicLinkObject + +`CreateSymbolicLinkObject` event is fired when the symbolic link within the object manager directory. This event has the following parameters: + +- `source` identifies the parameter that represents the source symbolic link object or other kernel object. +- `target` identifies the parameter that represents the target symbolic link object or other kernel object. +- `desired_access` denotes the access rights for the target symbolic link object. Can be the combination of `DELETE`, `READ_CONTROL`, `WRITE_DAC`, `WRITE_OWNER`, `SYNCHRONIZE`, `STANDARD_RIGHTS_REQUIRED`, `STANDARD_RIGHTS_ALL`, `ACCESS_SYSTEM_SECURITY`, `MAXIMUM_ALLOWED`, `GENERIC_READ`, `GENERIC_WRITE`, `GENERIC_EXECUTE`, `GENERIC_ALL`. +- `status` represents the outcome of the operation. \ No newline at end of file diff --git a/docs/kevents/process.md b/docs/kevents/process.md index ad6f2a72b..5bacbb5d6 100755 --- a/docs/kevents/process.md +++ b/docs/kevents/process.md @@ -48,4 +48,5 @@ Process state comprises the following attributes and resources: - threads - modules - handles +- memory mappings - PE metadata diff --git a/docs/kevents/thread.md b/docs/kevents/thread.md index 066a68b29..0e9bf8715 100755 --- a/docs/kevents/thread.md +++ b/docs/kevents/thread.md @@ -15,8 +15,11 @@ Thread events are comprised of the following parameters: - `kstack_base` is the base address of the thread's kernel space stack. - `kstack_limit` is the limit of the thread's kernel space stack. - `start_address` is the start address of the function to be executed by the thread. +- `start_address_symbol` the symbol the represents the thread start address (e.g. `LoadLibraryEx`). Only present in `CreateThread` events. +- `start_address_module` the module that maps to the thread start address (e.g. `ntdll.dll`). Only present in `CreateThread` events. - `teb` is the address of the Thread Environment Block (TEB). + #### OpenThread `OpenProcess` event is triggered when a process opens an existing local thread object. This event contains the following parameters: @@ -34,3 +37,42 @@ Thread events are comprised of the following parameters: `SetThreadContext` sets the thread context. Thread context represents the set of CPU registers. - `status` contains the result of operation. (e.g. `Success`) + +## Thread pool events {docsify-ignore} + +A thread pool is a collection of worker threads that efficiently execute asynchronous callbacks on behalf of the application. The thread pool is primarily used to reduce the number of application threads and provide management of the worker threads. + + +#### SubmitThreadpoolWork + +Enqueues the work item to the thread pool. This event has the following parameters: + +- `pool_id` represents the thread pool identifier. +- `task_id` represents the thread pool task identifier. +- `callback` represents the address of the callback function. +- `context` represents the address of the callback context. +- `subprocess_tag` represents the thread pool identifier. +- `pool_id` represents the service identifier associated with the thread pool. +- `callback_symbol` represents the callback symbol (e.g. `RtlCaputreContext`) +- `callback_module` represents the module containing the callback symbol (e.g. `C:\Windows\System32\ntdll.dll`) +- `context_rip` represents the value of instruction pointer contained in the callback context. +- `context_rip_symbol` represents the symbol name associated with the instruction pointer in callback context. +- `context_rip_module` represents the module name associated with the instruction pointer in callback context. + + +#### SubmitThreadpoolCallback + +Submits the thread pool callback for execution within the work item. This event has the same parameter set as the `SubmitThreadpoolWork` events. + + +#### SetThreadpoolTimer + +Sets the thread pool timer object. This event consists of the following parameters: + +- `duetime` represents the timer due time. +- `subqueue` represents the memory address of the timer subqueue. +- `timer` represents the memory address of the timer object. +- `period` represents the period of the timer. +- `window` represents the timer tolerate period. +- `absolute` indicates if the timer is absolute or relative. + diff --git a/docs/setup/images/fibratus-installer-msi.png b/docs/setup/images/fibratus-installer-msi.png deleted file mode 100644 index 0c8206dfc..000000000 Binary files a/docs/setup/images/fibratus-installer-msi.png and /dev/null differ diff --git a/docs/setup/images/fibratus-msi.png b/docs/setup/images/fibratus-msi.png new file mode 100644 index 000000000..2566deb9e Binary files /dev/null and b/docs/setup/images/fibratus-msi.png differ diff --git a/docs/setup/installation.md b/docs/setup/installation.md index 6b9fc8009..a317f86b7 100755 --- a/docs/setup/installation.md +++ b/docs/setup/installation.md @@ -2,10 +2,10 @@ ### System requirements {docsify-ignore} -- 64-bits Windows operating system starting from Windows 7 +- **Windows 10** and higher or **Windows Server 2016** or higher - 40 MB of free disk space - 1 (V)CPU -- 50 MB of available memory +- 90 MB of available physical memory ### Permission requirements {docsify-ignore} @@ -15,20 +15,20 @@ Fibratus requires **administrator** or **SYSTEM** privileges to capture system e - periodically writes the current event sequence into volatile registry value - writes logs to disk. The default logs directory location is `%PROGRAMFILES%\Fibratus\Logs` - grants the `SeDebugPrivilege` to its process token. However, you can disable granting this privilege by setting the `debug-privilege` option to `false` -- transports event messages over the wire if the eligible output sink is active. +- transports event messages over the wire if the eligible output sink is active - inspects process image [PE](/pe/introduction.md) metadata. Again, you can disable this feature through [config](/pe/introduction) file - executes [YARA](/yara/introduction.md) rules on freshly created process images or other image files when the [YARA scanner](/yara/introduction) is enabled - spins up an embedded Python interpreter to run [filaments](/filaments/introduction) - accesses raw disk devices to read file data -### Deployment {docsify-ignore} +### Installation {docsify-ignore} The easiest way to get started with Fibratus is by downloading the Windows installer. Head over to the [releases](https://github.com/rabbitstack/fibratus/releases) and pick your download. Latest releases are recommended as they ship with new features, bug fixes and tend to improve the performance. Windows installers are automatically built by the CI platform each time new Fibratus release is published.

- +

There are two flavors of Windows MSI installers: @@ -47,7 +47,7 @@ If you're able to see the output like in the snippet above, congratulations! You ### Uninstall {docsify-ignore} -To remove Fibratus from your system, head to the Control Panel > Programs and Features and start the uninstall process. The uninstaller will make sure to stop/remove the Windows Service and get rid of all installation data. +To remove Fibratus from your system, head to the **Control Panel > Programs and Features** and start the uninstall process. The uninstaller will make sure to stop/remove the Windows Service and get rid of all installation data. ## Building from source {docsify-ignore} diff --git a/docs/setup/quick-start.md b/docs/setup/quick-start.md index e09d13e19..4f401b0c0 100644 --- a/docs/setup/quick-start.md +++ b/docs/setup/quick-start.md @@ -8,7 +8,7 @@ By default, Fibratus operates in rule engine mode. It loads the rule set from th $ VaultCmd.exe /listcreds:"Windows Credentials" /all ``` -- `Credential discovery via VaultCmd.exe` rule should trigger displaying the alert in the Eventlog `Application` channel. +- `Credential discovery via VaultCmd tool` rule should trigger displaying the alert in the Eventlog `Application` channel. To learn more about detection rules, head to [rules](/filters/rules).