Thank you very much for being here, and thank you for allowing us to be here.
Our talk is called How to Do You I Do That.
We're visiting here today from Fox IT in the Netherlands, like I said, for I have to
be here.
My name is Leonard Habsma, I'm not much of a developer per se, get I am here.
He is the main developer.
I've been working at Fox IT for 15 years, I worked as the incident handler in the cybersecurity team.
So mostly incident and investigating the store breaches.
Now to work to my former intern, who has been outpacing me technically in any possible way.
Yeah, so I'm still following everywhere it goes, you know, so it's thanks to his butt.
My name is Eric, I've been at Fox IT for 10 years now, so 10 years ago I was his intern.
And I am a security researcher, I'm a security researcher team.
I mostly do R&D, but also to his response, sometimes help at Ratteam, like just do whatever
really crosses my guess.
I am the author of Disact, which is kind of like the framework we're going to be talking about today.
And we'll take it off.
Perfect.
So what is Disact? Does anyone here know Disact or has used Disact in the past?
A few hands, a few hands? Okay, good, good, good.
So then it's good you have a little bit of an introduction.
Disact is a pure Python, no dependencies, open source, forensic investigation framework.
So as said, no dependencies, so everything's implemented purely in Python,
we're trying to support many formats as possible.
And currently, Disact is being developed by Fox IT,
we're part of NC group.
But we are seeing more and more contributions from various parties,
primarily in the Netherlands, but also outside of the Netherlands.
So where would you use Disact 4?
I would like to know more workflow.
It looks something like this.
Or you're an analyst.
You have some investigative material,
and you want to get readable information from that.
But your investigative material is oftentimes in various different formats.
And Disact comes to the rescue to allow you to access all the artifacts,
like high level artifacts like run keys or system services in a way that's readable in records.
We'll get to that a little bit later.
And to go as to have a little specific parser that require an artifact to be in a specific format
as possible, but to have everything working more generic.
So I have a little bit of an example of that, how that would look like.
You have, again, your analyst.
And you have a image called evidence of raw,
which is like a Linux server, for example,
and you would like to know what command line commands were issued on that system.
So we have a plugin for that that will do that.
It's called command history.
And you can run diesect in a way of target query,
which is one of the tools part of the diesect suite.
And with the minus f, like function,
you can run the command history plugin on your raw disk image.
And what will happen in background?
Diesect will see that it is a raw disk image.
And we'll load that disk image.
It will see that it has a certain file system in this case.
It will see that to Linux file system, a Linux operating system,
it will see what it needs to do for the command history plugin in this case.
And once the command history plugin runs,
it will do a number of things.
It will iterate through the existing user.
Users that exist on that system.
It will go through the various history files,
like your batch, and that has probably more that I don't know.
And it will read those files.
And for each line that it finds in those files,
it will return a record.
And a record looks like this.
Basically a key value.
It will say what host name it came from.
It will tell you the command.
The type of batch interpreter that was identified.
The source file where it was located on the system.
And some other information that is enriched and added to it.
So this is a nutshell how dicec works.
But one history in this case is very specific for the one line
interpreter.
I don't even think it has a Windows counterpart at this moment.
Does it involve version?
Okay, the profile is included.
But if you look at how this boot look like on Python,
you can open a target, which could be all sorts of formats.
My favorite way of developing is actually opening.
If I indicate that's running in like a shared folder,
that's actually running.
So you can open the VMDK and do live, live forensics,
but in a passive way, basically.
And then you just say, well, I'm going to list all the users.
And if I want to show you here is it will parse to container.
And based on what it encounters, it will continue parsing.
So if it is antivS, it will start loading antivS.
And if it then finds Windows, it will load Windows.
And for users on the Windows, it will look at some users,
or profile paths history, profile paths in a registry.
And according to that, it will yield user records.
So based on what I say encounters, it will try to, in a uniform way,
return records that are relevant for you.
And behind this are actually Linux user records.
And Windows user records, but they are combined in the end
in like a generic user records.
And this is how dicex works across the board.
I think this next slide is good for you, makes you explain.
Yeah, so a little bit more in-depth.
I already explained some parts to this, which I'll just go a little bit quickly over it.
dicex basically made up a few core components.
On the bottom, we have like loaders and loaders are anything that kind of like a little
glue layer that can interpret, for example.
From machine metadata, say, for example, you have a virtual machine,
which has like five disks attached to it.
And the Windows event logs are like the third disk.
Then automatically, we can just add that at all of those five disks to kind of like target
and resolve where that, where does the event also store it?
So we don't, there's no manual action needed from the analyst to figure out where the event looks
stored, but also anything like any of your custom formats.
Sometimes we have like a one-off collection script for some kind of like special assignment.
And it's in some non-standard format.
We can use loaders to use some of the dicex APIs to glue together kind of like the state of a system.
So say you have like, you know, the registry hive that you collected through some means like an
or agent maybe and then the event logs you collected through a logical copy for whatever reason
then you conclude them together and a loader.
Next layer is containers.
It's basically anything that looks like a disk image is not much more to it.
And then we just implement most of the comma ones that you'll probably ever encounter.
It's almost like we've volumes, which again, just your regular volumes,
but also things like full volume encryption like Lux and BitLoker.
We support that transparently, so there's no need to wait, you know, like 24 hours for one terabyte drive to unlock.
Using, for example, the target query tool or target shell tool where you can just drop in for like a virtual shelf target.
You can just specify the BitLoker recovery key or the raw BitLoker key or the Lux key.
And you just immediately within a second to drop into like an interactive shelf that system,
purely from like the parsed information from that disk.
Also rate, like automatic rate recovery, basically from Linux rate and Delrate.
We just interpret the metadata, there's no need to manually piece together, you know, how the rate combines.
We just do it for you.
File systems, forced your comma ones, some of your exotic ones as well, but also anything that looks like a file system.
Like is it file, you know, basically a file system, an SMB connection, basically a file system.
Yes, a reverse net called shell, you know, can also be a file system.
You can just, you know, invoke LS and then you get a list directory listing.
And we can piece all of this together into whatever kind of crazy combination you can come up with.
And on top of that, we build kind of like our parsers, like our plugins to interpret or to interact with the target.
So this is your, you know, general artifacts you to think of that you would like to extract from the system.
But also more like very specific stuff to a certain type of system.
So we try to kind of like make an abstraction for anything that all systems usually have.
Like, for example, basically every system that exists has like a host name.
So we provide like a host name plugin.
But for example, for an eZXI hypervisor, we would also like to know what the registered version machines are on that hypervisor.
So in a little bit more of a flashy slide, I would say, a little bit of a recap was what Leonard always talked about.
We have a whole bunch of tools and we just query any artifact we want.
You know, some common ones or, you know, whole bunch of other whatever kind of you can think of.
Again, it's anything which is kind of like the.
The key of dissect, we try to make it as frictionless as possible, you just give it your source data and there's zero kind of like added.
Processing needed to start getting actionable artifacts from your source data.
We want to go from whatever source material you have immediately to.
artifacts, you as an analyst can interpret, so you spend as little time as possible on the boring stuff and as much time as possible actually investigating what matters.
So just, you know, whole bunch of different kind of formats.
Some exotic ones as well.
So we had once and then.
The important thing about dice as well is every artifact we output is kind of like an structured.
It's media format like the key value format Leonard mentioned.
And we can basically, you know, shape this to whatever other format we want.
So you can output it to a JSON file.
CSV can even do it Excel if you want.
But also to, for example, Splunk or Alessic search or Dr. B.
And just immediately start investigating your stuff there.
So this is a little overview of kind of like the different tools we have available within dicec.
A choir is, well, it's acquisition tool.
The fun part about choir is that it uses everything about about dicec to do the acquisition.
So it supports the exact same kind of like.
The exact same target, so the exact same file formats as dicec does.
So it doesn't just work on a live system.
It also works on the VMD case, virtual machines, back up, etc.
So in the case, you have like 90 terabytes of data you want to investigate.
Maybe it's a little bit too much.
You just run a choir against a nine terabytes.
Suddenly you only have a few hundred gigabytes of data to analyze.
It like a cape ish like like format.
Like a lightweight collection package.
And then suddenly you just your amount of data you have to to to to put on your expensive flesh storage, you know, to to quickly analyze that stuff.
It becomes a lot more feasible.
Some like regular common utilities we use.
Some of these are actually community contribute, which is very cool to see.
Like target diff and target info.
And also some more other utility tools that you'll probably use a little bit less, but are also just fun to play around with.
Little microphone dance.
So now we're going to talk a little bit about some of the nesting capabilities of dicec.
But hypervisors or how we call them inside of dicec.
The cold children.
I'm not sure who or why we picked that name.
I don't really know.
A choir.
Children's health and fun.
So what is a.
A child or a sub target.
It's basically what Orioles mentioned.
If you have hypervisor, you have child VMs.
And those VMs you might want to be able to parse.
And maybe you want to do that multiple times.
We use it.
We use dicec a lot.
You build acquisition of data as well.
Like the choir to we mentioned.
We oftentimes run it on the hypervisor to get like a minimal forensic package of all of the sub VMs on the system.
So without having to run code on those systems to acquire data.
We just run it from the hypervisor.
So that is a very useful use case.
And I want to do a small demo on what we use around this.
But first a little bit more of an instruction.
So as said, an example of another multi-layered child is.
For example, a window system running subsystem for Linux.
Which is running Docker, for example, on top of that.
The hypervisor basically transparent to use a user to extend just like all the other layers that Eric explained earlier.
And we currently support actually quite a few hypervisors.
We don't support everything.
But we have parsers for hyperv the various VMware products, virtual box, box, box,
Docker.
And but there are some that we don't support currently.
We don't think we have any sensor for implementation at the moment.
And some container formats we don't fully support yet.
But of course, happy to receive any contributions in that area.
And some hypervisors are making it quite hard to parse things.
Especially VMware.
It's really looking down.
It's management interfaces to execute code.
And I think with TPM it's becoming harder to actually decrypt config files.
That contains some of the file systems.
If you actually want to inspect a ESIX eye machine.
Basically, it makes it quite hard.
So those are sort of like ongoing struggles.
Eric is giving an entire talk.
Actually on the MFS in like an hour or so.
To see what he's been doing his summer holiday.
So child arguments makes a nice for a slide name.
For all the tools that we previously mentioned.
So dark query, target FS, target shell.
Over the last year.
I did some effort to align the functional functionality with shell targets.
Because there were a bit all over place.
Some of the tools supported.
Some of the tools didn't support it or in an unexpected way.
Also at a time.
Dicec didn't really print the shell targets.
It identified.
And that was something I think was very useful as an analyst to be able to see.
Because Dicec did handle parsing of shell data.
But it didn't actually show you as a user.
So that I'll show you some information about that later.
Basically for relevant command name flarks.
Flacks are related to the shell functionality.
It's list children.
Which as a name suggests.
You simply print out what children can find.
The mine mines children.
Actually runs the commands you want to use.
Like the mine's f host name.
For example, it will run on all the children.
It will find.
You can specify specific shell to run things on.
So say you have a hypervisor and you have 100 VMs.
You might only want to run your command on a single machine.
So you can first list all the children.
And then specify a particular VM.
And you can make this recursive.
If you have a lot of time.
Because everything starts getting slower and slower.
More layers you add.
It's a little bit like inception.
Hmm.
So time for a little demo.
One shout out is.
You know, standing on the shoulders of giants.
A lot of these contributions for these various hypervisors came from.
Actually different organizations.
And different people.
So shout out to them for contributing this.
My network has been mainly on.
The high level stuff to align all of the functionality.
So let's run targets query.
We're going to.
Make it quiet so we don't get too much debug information.
We're going to specify virtual box image here.
We're going to list the children that we can find.
These are total level children.
And we can find a singular WSL instance running there.
That we can specify child zero because there's like an index at the front.
And we can print its host name version OS.
You see it's like a galley image.
And you can also run things like command history to see what kind of batch commands were issued, for example.
You get a whole bunch of records back from that.
It's a bit hard to read.
So let's use our dumb to actually only print the command field to make it a little more readable.
And you see here actually some Docker references in my commands.
So let's see there's actually another child in there.
So we're still specifying the first child.
And then we're going to list children again.
And here you'll see that there's actually a Docker running.
But you don't have to do this like multiple times.
You can actually just go to the main image.
Say list children and type recursive.
And here you'll see that you actually have a nested image.
Then you can simply specify this second layer.
And by this one child zero point zero.
And actually again, just run functions on that.
Subsheld.
I was named version OS.
And you can see what has been running there.
This guy's it's a Ubuntu Docker container.
And here again, you can run command history and all the other plugins that were flashing by the screen.
A few slides ago.
But you can also do other commands like printing the users that exist on this system, which is a
very default set of users.
So that's one simple demo of how to interact with the use dissect.
When I first started working on this, I thought, well, how deep and how far can you go with this?
Well, so I wrote a little code.
And it did some effort.
Preparing a demo.
What I'm doing here is actually running on a personal type ofizer.
I'm opening the local target, which is like a magic word to say, or you're running on a target.
Open that target.
And print the six child and print some relevant information.
You actually have the example output record that you would get out of that.
And then recursively start printing the children of that six child.
And then the output that you get.
And this is quite some effort to build actually.
You're going to get parents.
You're going to get a type of hypervizer.
So it's like a box box type ofizer.
Running ESIX eye, running virtual books, running keymer, running hyperv.
Running VML workstation, running VML workstation.
Running virtual books, running WZL, running Docker.
And it's actually alternating as much as possible.
Windows and Linux.
And it's actually Linux.
Windows versions from Windows 11 going back to Windows 7.
Which was quite hard to find the virtual works that you could download.
That's still worked.
And instead of having like a slide.
And there's some relevant names.
Like a VM has like a name.
If you have like your VM list.
And you have of course host names.
So it puts them effort into making sure they were aligned.
So even on the example of saying like great.
The level image is actually in the exact eye host.
And you can't run regaft on that.
Regaft is our registry parser.
Which will recursively print out all of the registry keys.
It finds.
But that of course doesn't have registry because it's a Linux system.
But what you can do is then say mind, mind, mind,
children actually say look for a child that has it.
In this case, I'm limiting to one record for each child that finds.
And you can see that using this.
And actually if you specify to print on the host name and you sort
unique it.
You can see that it will find for each of those host names.
It will find like a million registry keys.
So it is recursively parsing.
As key cinema makes it look very nice.
But this took actually quite a long time on my single host.
Approximo system parsing a million records into dissect multiple times.
Is of course not the fastest.
And then doing the same thing here for the command history.
To actually print like unique host names for which it found.
Yeah, batch history commands within all of those with within all those layers.
And this is roughly how we use dissect to
parse large sets of targets at scale.
We use it for enterprise forensics,
like ransomware case or big breaches,
where we process thousands of systems based on
choir to collect artifacts.
And we run them for all of the plugins.
You can do like minus F wildcard.
I can actually just specify the directory filled with target.
And we scale that up.
That's how we use it.
Back to this.
You're not leaving me much time.
One of the kind of like big pillars around dissect is that we
believe the code is a product.
So we don't just want to see a like to work.
We want the code to be.
Well, it's like like that libraries first class citizen.
And all the CLI tools should just call into the library.
We do this to really promote custom tool development.
But also so it's easy to extend.
Right?
We kind of like develop dissect or architect dissect around
very familiar Python APIs.
So the naming is basically exactly the same.
The arguments are the same.
You maybe just need to like put a little namespace prefix on it
to make it a dissect API.
But kind of the goal we wanted to have is that if you're an analyst,
you know some Python, you know how to write some Python code
to analyze something on your local system.
You can just make it to be able to just like add a few keywords.
Make it a dissect script instead.
And it'll just work against any source data that we support
in dissect.
So instead of just on your local file, just on your local system.
It now works on the family case,
females,
females, and through all the high profiles of layers as well.
However,
it comes to change with this,
which means that we can't just you know blindly merge
every pool quest that we get.
They actually need quite a lot of attention to make sure
that all the code is in consistent quality,
consistent styling,
consistently high level of quality.
The little quick screenshot,
what kind of like a standard interaction or a
injection with a system could look like.
So with target shell,
if you don't specify Python,
you just drop into like a batch like shell.
But with Python,
you know,
well, it's minus p as well.
We call pro mode.
You kind of drop into this Python shell,
and you can interact with the target object,
and you can just interact with it like a regular normal Python object.
But also we want to make it easy.
We don't want to hide any kind of like off the details of
the system,
so we want to make it very easy to drill down
into the lower layers of the target as well.
So we really want to,
we don't want to hide what an eye note looks like,
or what the fields are of an eye note.
We want you to be able to very easily interact with that as well,
and inspect it if necessary.
So we open sourced few years ago,
or kind of like a company model,
it's like four more scarce society.
And we've been you know,
standing again kind of like on the on the shoulders of giants.
We've been using so much open sourced tweeting over there,
know,
the existence of our company.
We feel like it's time to give back as well.
Since we open sourced,
we really see a high adoption rate.
A number of contributors really picking up every,
every time, like every week,
sometimes every month at least we see like,
like a new contributor, for example, or one or two.
And it's all over the place as well.
Like we see some government contributions from our competitors.
I think basically almost every compared to the Netherlands,
use the dissect and most of them also contribute back.
But also students, just random research on the internet,
it's quite nice to see.
And so some incredible,
it's not just like fixing a typo,
you know, like we're fixing a grammar mistake,
so some very high quality contributions we get.
I would have a with open sourcing comes new challenge as well.
Very nice is that, you know,
the rate of finding bugs is a lot higher.
Your exposure is bigger,
but unfortunately the rate of fixing is only,
like slightly higher.
Because again, like I said,
not everyone is also a suitable core contributor.
And the videos, they quite a lot of time.
So we have quite a lot of,
well, open issue with Google Quest as well.
And we just, it's just hard to kind of keep up with,
a bit of flow sometimes.
So if anyone has any chip tricks,
you can find us later,
or maybe we can exchange some ideas.
Actually pretty fun,
the slide from NFI.
We kind of feel a similar,
we kind of have a similar problem as well.
Like we try to push hard on unit testing of all of our parsers.
But unit testing only gets you so far.
It only works like specific versions,
specific stage that you have your just data in at that moment.
And we currently don't really have a nice method to stay up to date
with like operating system updates,
false system updates, stuff like up.
So if anyone's working on this space,
or knows who is working in this space,
please head us up.
Very quickly.
A few community use cases.
We've seen that actually go beyond,
kind of like the forensic,
or incident response use case,
is actor investigation.
It's a skill.
We see this from like,
government institutions,
and law enforcement institutions.
But also OT security and compliance at skill.
Very quickly,
could the actor tracking like,
instead of just,
you know,
trying to investigate a breach.
You can also investigate a system from a
tread actor.
And kind of like use the traces that are available on that
to,
for example,
correlate multiple systems together,
cluster them together,
try to determine what the system
might be used for,
or just keep tabs on what the tread actor is doing.
And some of the key benefits,
we've got them back as feedback from our,
from our,
wouldn't say part of it,
but from our users, I guess,
is that they're really like kind of the approach we've taken with,
kind of like the familiarity around Python,
the same APIs,
and kind of like having a strict output format as well,
instead of having a bunch of different Python scripts that output in,
like a bajillion different formats,
they're not like a centralized knowledge hub
of all of their plugins that work on any current and future source data
that they might encounter.
Similarly,
okay, insights,
someone in the OT world came to us and said,
like, hey,
we actually have a,
like a big problem,
we have a lot of OT systems that we counterrun security software on,
but we still want to get some security insight in there,
also just compliance stuff,
you know,
we're unused,
we're used these sticks,
we're used the wrongly,
and now they can just,
oh, sorry,
current solution was a kind of golf cart,
and the current solution we have is to make backups,
and then they investigate,
dissect,
we're using,
dissect the investigators,
backups,
and extract the same information.
We are out of time,
but basically what I just said,
about centralized repository,
and thank you.
Thank you.