dissect.target icon indicating copy to clipboard operation
dissect.target copied to clipboard

Plugins should be able to expose their parsers independently of a target

Open MaxGroot opened this issue 1 year ago • 0 comments

Problem description

(Chose as generic of a title as I could think of)

Dissect.target has plugins for all kinds of artifacts. It would be nice if you could query plugins even if there isn't a real 'target'. For example, calling the evtx plugin on a .evtx file, parsing a wtmp file, or recovering a file that has been quarantined by Windows Defender.

Currently, the plugin system is not really designed for this. Many plugins have a list of paths to check against, but these paths are not exposed / set via a uniform API. This prevents us from extending / providing the needed paths on the fly. A band-aid solution has been the LogLoader, which remaps paths from the host into a virtual filesystem at a location that makes the check_compatible of the desired plugin pass. This currently only supports a few forensic artifacts. The problem is that improving on this would either require:

  1. Having a very long list of hardcoded paths in the LogLoader;
  2. Requiring the user to manually specify the LogLoader with a path to map to, asking of them to know exactly which path dissect expects for a forensic artifact (proposed in https://github.com/fox-it/dissect.target/pull/787);
  3. Using a dropfolder of sorts (proposed and closed without merge in https://github.com/fox-it/dissect.target/pull/399);

However, all three would run into flexibility constraints when plugins also require a certain os check to be passed, or a file existing in a user's home on the virtual target;

This problem has been discussed more thoroughly in https://github.com/fox-it/dissect.target/pull/399:

Underwater, plugins could use something like get_paths() (that in turn calls the implemented methods of that plugin) but also allows getting "extra" paths from the command line, loader logic, or whatever other API. I can imagine a system like this also making the log loader obsolete, since you would simply be able to execute e.g. the evtx plugin directly on some paths you pass in from the CLI.

  • Ideally, a long-term solution would make the LogLoader obsolete. As stated in #787:

  • We are planning to enhance our plugin functionality so you can query plugins with just target-query.

  • Ideally, the taken route is generic enough that it can also work with registry hives (https://github.com/fox-it/dissect.target/issues/411)

Opinionated suggestion

Something like get_paths() getting / extending the paths for plugins that they need for compatibility is a quick-ish win for most of the plugins. However, maybe there are situations where a plugin wants to have more control of when it accepts a given path / file-handle from the host? Something like a detect(path: Path) and map() like loaders have, but then specifically for plugins? When a plugin implements them, it gives the writer of the plugin full control over how to preprocess a file that hasn't got a target associated with it.

If this approach is too convoluted, a good-old if __name__ == "__main__" such as found in some loaders / containers might also suffice.

MaxGroot avatar Aug 05 '24 18:08 MaxGroot