20 mins slides, 5 mins demo, 5 mins Q&A
welcome to our presentations "Evolving Threat Detection at Runtime" I am Mikhail and this is my co-presenter Salman We are going to talk about how we at Mimic use WebAssembly to dynamically update behavior in the windows kernel
Transition:
let me tell you a little about Mimic
~ 2 minutes
Mikhail
we are a member of the BytecodeAlliance that specializes in...
the technology we are developing allows us to rapidly react to ongoing attacks from adversaries
- Modifying it often is even riskier
Transition:
We use Wasm to mitigate some of this risk through sandboxing
~ 2 minutes
Mikhail
Our product monitors system events from the core of the operating system, the kernel, to the cloud to detect threats.
and we use Wasm for safe customization and dynamic updates
Wasm allows us to customize the product to meet the individual needs of our customer's environment
We use Wasm to rapidly configure and update our product
we do this by leveraging the Component Model at mimic
we built a modular ecosystem using the Component Model for our product
Virtualization with the Componen Model allows us to reuse code across platforms
Transition:
One of the places we deploy this kind of dynamic logic is in the operating system's Kernel
~ 1 minute
Salman
eBPF allows safe customization and dynamic updates in the Linux kernel
But in Windows...
Transition:
So...
2 minutes
Salman
our own safe space inside a hostile kernel environment
restriction v.s. sandboxing
we have full control on a running instance of Wasm
Transition:
Kernel programming is notoriously hard
getting Wasm working in the kernel wasn't easy
~ 1 minute
Mikhail
first, we don't have access to all the tools we get in the standard library
second ... you can't run random wasn binaries in the Kernel <!-- only code that has been reviewed and signed by microsoft can run with standard security policies
hypervisor kernel mode integrity windows
and ... that means we also can't to JIT compilation
Transition:
thus, we decided to interpret Wasm
2 minutes
Mikhail
constrained environment
we wanted Wasm interpreters that supported no_std environment
Pulley, by the way is an optimized bytecode format and interpreter for Wasmtime
these were the high level results of OUR micro-benchmarking, Wasmi was the fastest one
Interpreting was an magnitude slower for OUR micro-benchmarks than JIT
interpreted Wasmi is faster
Transition:
BUT we still chose Wasmtime+Pulley instead of Wasmi
Salman
~ 1 minute
capability-based Compatibility
technology independence is important for building ecosystems
compatibility enables workload migration
Component Model is difficult to adopt
we wish there were more implementations that handled the Component Model
Transition:
So how do we make wasmtime run in the kernel...
2 minutes
Salman
Technical Details
?? We should expand the following sections.
We embed wasmtime as a minifilter in the kernel
TODO should be a keynote and have a simpler bullet point
- minifilters provide a way for developers to monitor and modify file system operations
without needing to interact directly with lower-level file system drivers
- we are not supporting Wasi but we are implementing the host functions in the kernel
- the host functions interact with the kernel and need to be fully tested
this "unsafe" portion of our code
we compile modules in user space
what we are deploying is not standard wasm, it's optimized pulley bytecode
2 minutes
Salman
When you are in no_std you have to implement the C API
Wasmtime was still pulling in the standard library with no_std
talk about "respect `std` PR" #11152
shoutout to Alex C for the quick turnaround
IRQLs limits what you can and cannot do based on your level
performing wrong operation at wrong IRQL causes BSoD
Transition:
we wanted our hosts to run multiple Wasm components at once
2 minutes
Mikhail
when we tried spawning multiple worker threads, wasmtime panicking on contention
Wasmtime needed the std to provide synchronization primitives to avoid contention
we modified Wasmtime to allow the host to provide synchronization primitives through C API
Transition:
We also had to implement our own thread-local storage (TLS)
2 minutes
Mikhail
In computer programming, thread-local storage (TLS) is a lock-free memory management method
that gives each thread its own copy of a global variable. <!-- When the thread exits, its copied variables are destroyed
Solution
we use stack pinning to ensure that allocated memory does not shift when thread scopes are passed around
and that their IDs stay relevant even after leaving the current scope
we use a registry pattern to link threads to their parents and the resources they own
...now we can can run multiple components at once
Transition:
What does this get us
1 minutes
Salman
we allowed WebAssembly to handle dynamic updates in the kernel without restart
This allows us and our customers to safely write logic for the kernel
it meets our business use cases
logic restriction v.s. sandboxing
Interpreting Wasm comes at a cost
Wasm solution should not be used on the hot path
Transition:
We will now show you a demo to see our solution in practice...