Skip to content

Instantly share code, notes, and snippets.

@alexandre-janniaux
Last active November 16, 2020 17:02
Show Gist options
  • Save alexandre-janniaux/abc15b168cea229cf999aa57f0ad96cb to your computer and use it in GitHub Desktop.
Save alexandre-janniaux/abc15b168cea229cf999aa57f0ad96cb to your computer and use it in GitHub Desktop.

First version of the project

The first version of this project is based upon multiple precedent experiments aiming at highlighting the different points needed for the requirements of VLC within a context of sandboxing.

The different prototypes are described below.

Highlight on the second prototype

The second prototype was much different form the first one in the sense it wasn't design from a security point of view, but instead as an evaluation of the software architecture points that will be needed to be addressed by the project.

The goal wasn't about removing right and resource access like the first prototype did, or even about designing a security policy. Instead, we focused on the requirements for the process isolation.

From there, we distinguished multiple models for spreading the VLC pipeline across multiple processes, which sums up into the following points:

  • integration model: proxies or ad-hoc request
  • execution model: how requests are handled across processes
  • resource model: what are the mechanism to transfer system resources

The main point of design was the integration model, which can be summed up as the tradeoff between how easily it is to integrate the previous code while keeping the same paradigms and improving maintenance time versus how easily it is to switch incremental part of the code to be sandboxed.

Bringing history and other references here, COM in the Windows ecosystem is typically an instance of the first kind, with proxy objects mapping a remote state to the current process, with an interface allowing a normal usage of the code. It is strongly object-based, making use of the virtual table indirection to redirect the proxy in a strategy pattern way.

The second point was also important in the design. One property we want to keep is that the relation happens-before for requests happening in a process restricted to the set of events forwarded to another process also respect the same happens-before relation in that other process, ensuring that synchronicity is respected even across multiple processes.

The third point was mostly technical on the Linux side, but led to a complex challenge on the Windows side. Indeed, transferring a system resource needs the use of DuplicateHandle with process handles having the PROCESS_DUP_HANDLE access right on them, allowing a bi-directional transfer of resources and thus potentially allowing one process to steal the access rights on resources belonging to another process if done incorrectly.

Developing a minimal working architecture for each targetted system led to two kinds of possibles architectures:

  • The orchestrator architecture, where a priviledged process sets up the communication channels between two processes but doesn't interfere afterwards and thus define behaviour and security policy at creation time.

  • The broker architecture, where a priviledged process interface with multiple processes, and only exposes a communication channel to itself. It is then responsible to route the messages between the different actors and will need to check the source and destination of each message to avoid attacks, thus defining behaviour and security policy for each interaction.

The first model was very convincing for the following reasons:

  • The communication channel setup between two processes can be seen as an unforgeable token allowing the system to communicate between the two parties involved. It can also be transferrable across processus boundaries. Thus, it joins the concept of capability-based security and allows a more natural approach by letting the access checks, the process boundary integrity and the messaging multiplexing to the operating system. Since the same work is needed from the operating system, it doesn't really reduce the attack surface of the mechanism, but operating systems are expected to have better security audits and stronger usage among a wider list of scenario. Thus it makes sense to remove the maintenance cost from the VLC side given the security stakes.

We can also note that it's always possible to build one model on top of the other as long as we introduce multiplexing, by using this multiplexing layer to build the other. For instance, it's possible to build a capability-based broker by adding new communication channel towards the broker when two processes needs to be able to communicate, instead of multiplexing the one used by the broker.

Highlight on the work-in-progress prototype

Like described in the threat model, the overall goal of the project is to sandbox the multimedia pipeline first. The second prototype focused on the output pipeline, including the decoders and audio/video outputs so this third one started with the beginning of the pipeline.

It benefits the real world situation because most security issues raised are linked to the demux or access parts of the pipeline, so it makes sense to start integrating isolation from there first, especially given that even if access may have access to the filesystem, demux usually needs zero access to any exterior resources.

The goal of this new prototype version is also to consolidate the previous design while formalizing and conceiving reusable parts for the different elements outside VLC.

Its current first step is to move the access into its own process, including IPC, RPC, security rules, interception mechanisms and VLC stubs to find a way to organize all of them together.

The second step will then move the demux into its own process, allowing to have an experimental process where we can try to ensure no resources are available.

A first analysis of the interaction made by the access with the rest of the application led to the following points:

  • LibVLC instance: Used indirectly to create new VLC objects (like the access itself) and use/forward the logger infrastructure to the module.

  • VLC variables: Read-only access to the global configuration and parent variables. There's no need for neither callback support (only v4l2 access is using them) nor write access to parents objects (but maybe to local objects?) and obvious non-working access modules like imem.c where a function pointer address is forwarded from libvlc are excluded from the prototype.

  • vlc_interrupt_t: Mechanism allowing the setup of an interruption context local to a given thread. It's used by the access to determine whether the IO operation must be cancelled. VLC _i11e suffixed IO functions are using this interruption context to abort the IO whenever it's triggered. It also exposes an API to forward the interruption context from one thread to the interruption context of another thread, but there's no multi-processus crossing currently.

  • cache/prefetch: Those stream_filter modules are currently created by the same function creating the access.

  • input_item: The access has read/write access to the input_item_t element, which has an entity semantic and is in particular used by the user interface to display the item information.

This can be summed up with the following diagram.

Layering of the work

Like mentioned in the previous section, being able to reuse components outside of libvlc / VLC is a major design point of the current prototype. The different elements that have been described are developped in this section.

Note that those elements are expected to be reusable:

  • libsandbox layer
  • libinterception layer
  • the RPC layer
  • the IPC layer

But everything still need to be described in VLC, and in particular the link between the RPC interfaces and the VLC API need to be written specifically for VLC.

Global command flow

For the command flow part, we want to translate vlc specific function call into rpc to another process. To make it work, it involves the following layers:

  • The low level platform-specific IPC layer to send payload and handles to a different process.
  • The RPC serialization and deserialization layer.
  • The VLC proxy layer linking the vlc interfaces to the rpc interfaces.

This view doesn't account for security details for now, which will be added later in the page.

One main aspect handled in this view is the schisme between windows and linux handling of resources handles.

[mbu: it would be helpful to inventory the different types of handles and file descriptors required to be passed across privilege domains. restricting object types can be done on windows to avoid type confusions, i don't know yet if it is possible on linux file descriptors.]

libsandbox

In addition to the IPC, RPC and proxyfication layers, we add a libsandbox component whose role is to create, setup and start the sandbox worker/broker processes, and then manage the resource accesses, rights, handle type checks and custom policy in a multiplatform manner.

The policy and mechanisms that libsandbox must typically implement are:

  • how much ambient authority to leave to the process to be created, so that it can directly acquire resources;

  • access checks when trying to acquire new resources using a global identifier (e.g. file or registry key by name, process by pid, etc.) when the ambient authority is not enough;

  • list of resources to be inherited at process creation;

  • process mitigations on windows (e.g. handle bruteforce prevention, etc.);

  • system calls to allow on OSes with system call filtering capabilities (e.g. win32k.sys on windows, seccomp on linux) ;

  • etc.

libinterception

Then the interception framework might also be externalized by providing an initialization method to setup the interception of both syscalls (by intercepting the c function call) or vlc functions (either for proxification or setting up the proxification).

The interception can use different methods to inject its redirection functions.

The first generic one is done at compile time and consists of replacing the function by their redirection one, and expose two global variable to determine whether functions must be redirected and to which handler. Then, it's possible to check this value at each call, thus providing an access-time mechanism.

The second one uses the dynamic linking properties to redirect during the runtime the different function to their proxified counterparts, thus making the check at linking time and never after. This approach can however interfere with other software trying to intercept library and system calls (e.g. antiviruses, debugging and profiling tools, etc.)

Open questions?

  • How to debug and trace within the sandbox?

  • How to report traces when it crashes on the user side? (multiprocess libunwind?)

Project Threat Model

The goal of this page is to describe the limits of the project and the target threat model for the first version of the project.

Global scenario

There are two main "basic" usage of VLC Media player:

  • basic player (double click on file, url -> open with VLC)
  • media center (playlist, preparse, etc.)

The project will focus on the first one scenario: basic player + basic convert/stream output scenario.

The focus is "hardening the playback pipeline" - with vout or sout at the end of the pipeline.

Security scope

OS Versions

As the project is a mid-to-long-term target, it seems reasonable to aim for the latest security API and solution provided by the different OS where the sandbox will be enabled.

Especially:

  • Latest Windows 10 tools/API
  • Latest Linux kernel versions.

Note on macOS

At the beginning of this project (2020-07-01), Apple is starting to big transition on their virtual machine and container stack included in the macOS system. It seems that it would be a good idea to wait for this strategy to become a bit more stable to start investigating on it.

Assets

  • User environment data, including:
    • files stored in home and other directories, which might have very weak ACLs (or no protection, e.g. FAT32 filesystems)
    • other sources of metadata, not necessarily in files (e.g. services exposing RPC interfaces or registry keys leaking user activity on Windows, etc.)
    • data handled by other processes (e.g. web browsers, password managers, window manager)
    • any secret stored in Linux Keyrings, Windows Credential Manager, etc.
    • Single-Sign On capabilities (e.g. Kerberos and NTLM credentials of a Windows logon session)
  • LAN services accessible, including:
    • remote hosts
    • services listening on loopback or local addresses

Impact

  • Confidentiality
    • examples: leaking user environment content
  • Integrity:
    • modifying/corrupting user data
    • changing the state of part of the system, network service.
  • Availability:
    • the assets availability should probably be removed from the project scope: user machine resources over-consumption is extremely easy with a media player (just have to propose a 8k/60fps video format on a low-profile machine will imply severe speed down of the global system (and a lot of memory consumption).
    • apart from the user machine (and network) resources, VLC is not considered as a "service" in this threat model, so availability is not essential. Every permanent availability change should probably be considered as integrity impact (user environment, system, network).

Attacker model

Attack Vector

  • VLC toxic input:
    • URL
    • local file
    • including playlist (so sequential inputs)
  • No VLC configuration file change/dll switch/etc. that would need admin rights on the machine.

Privileges required

  • The attacker is considered as "remote". Except the toxic source given to a local user, the attacker does not have access to the machine.
  • no login rights on the machine (no auth, no admin, etc.)
  • no physical access to the machine or user
  • can have some knowledge on the system (ie OS version)

Targeted Vs Opportunistic

Opportunistic and targeted attacks seem to have very different approach based on their initial knowledge of the user environment: knowing the OS version, providing information/multiple toxic sources, etc. Can make the attacker job easier or access new scenarios.

TODO: define whether we consider the attack as targeted of opportunistic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment