How does this AppLocker bypass work, exactly? ("Squibblydoo")
Brief introduction to COM
COM is a Microsoft standard for the binary layout of objects in memory.
This standard is independent of the programming language used though is similar to the well-known C++ virtual dispatching through the vtables.
Basically, COM consists of objects and interfaces.
Object are abstract entities, they are a collection of interfaces.
Interfaces are identified by an UUID (known as CLSID) and optionally a more user friendly Program ID (ProgID).
An interface consists of a set of methods and an eventual parent interface.
A programmer never uses objects, only interfaces. They have to somehow get a pointer to an interface and invoke its methods.
At the low level, an interface pointer is just a pointer to a vtable.
If the programmer already have a pointer to any interface of an object, it can get any other interface of the same object because all interfaces inherit from IUnknown
that exposes a QueryInterface
method.
However to get the first interface a side band mechanism is needed.
Particularly, the module where the object (interfaces) implementations reside must be loaded in the calling process address space (if it's an in-process server) or must be started and an IPC/Network channel established (if it's an out-of-process server).
All the work is handled by the CoGetClassObject
API that given a CLSID will do all the hard work and return a pointer to the given interface (eventually through an in-process proxy).
Brief introduction to COM server registration
For CoGetClassObject
to work it need to find the type of server and the associated module (DLL or EXE) from a CLSID or a ProgID.
This information is stored in the registry (Under HKCR
and HKCR\CLSID
), when missing a COM client will fail to invoke methods on the server.
It's the responsibility of the server module to create the right keys. Microsoft developed a convention (or it's a standard?) so that a programmer didn't need to conceive their self with the registration burden: A module will export DllRegisterServer
and DllUnregisterServer
and the installation wizard will call them for each COM component (EXE module may use different names, I don't remember).
The tools performing the registration is regsvr32.exe
, when given the path of a COM module it will load the module and call one of those functions.
Optionally a module can export (DllInstall
) which is used to perform additional installation steps besides the pure COM registration.
This function accepts a boolean parameter to tell installation from uninstallation (note: there is no DllUninstall
, the doc is wrong) and a string denoted as the "command line".
The implementation is free to use it however it wants.
When used with /i
regsvr32
will call DllRegisterServer
and then DllInstall
with the given command line.
If /n
is also passed, DllRegisterServer
is not called (which implies that /n
alone is not valid).
If /i
is not given DllInstall
won't be called.
If /u
is used, the uninstall path is taken (DllUnregisterServer
and DllInstall
with FALSE
).
/s
is for not showing message boxes.
Brief introduction to COM Scriptlet
Writing COM components is easy if you use VB6 or VC++ or Delphi but otherwise is painful.
To enable scripting languages to write COM component Micosoft introduced a new format for the COM server: the COM Scriptlets.
They are XML files with the source code and a bit of metadata.
<?XML version="1.0" ?>
<scriptlet validate="true" error="true" debug="true">
<registration
description="XXX"
progid="YYY"
version="1.00"
classid="ZZZZ"
>
</registration>
The metadata are just the ProgID, the CLSID and a description plus a version.
A full example is here.
The code inside the registration
tag is executed as part of the server registration, unregistration process.
<registration
...
>
<script language="JScript">
<![CDATA[
...
]]>
</script>
</registration>
The scriptlet can (must?) also declare the methods of its COM interface.
The srcobj.dll
I don't know what srcobj.dll
is used for in Windows.
I just fired up IDA and retrieved the DLL's debug symbols to see what's going on.
First, the DLL exports all the COM registration methods:
The DllInstall
method, regardless of the bInstall
parameter, will load the scriptlet given in the command line argument calling RegisterScriptlet
RegisterScriptlet
will in turn create a ComScriptletSite
object to get a ComScriptletConstructor
to invoke LoadFromPath
:
The chain of call is a bit deep from here, it goes like this: LoadFromInput
> ... > CompileScriptlet
> ... > CompileRegistration
.
Later the scriptlet registration code is executed as part of its initialisation.
The bypass
The net effect of loading a scriptlet is that some script code is executed in the context of regsvr32.exe
(as part of the registration phase).
As regsvr32.exe
is a trusted (signed?) executable, this bypass the Windows restriction on allowed executables (AppLocker).
Regsvr32 is a trusted Microsoft binary.
The regsvr32 is a windows command line utility that is used to register and unregister .dll files and ActiveX controls into the registry. Casey Smith discovered that it is possible to bypass AppLocker script rules by calling the regsrv32 utility to execute a command or arbitrary code through .sct files. This utility has many benefits since it is a trusted Microsoft binary, proxy aware, it supports TLS encryption, it follows redirects and it doesn’t leave any trace on the disk.
So as its a signed Microsoft binary Applocker allows it to execute. The code in the SCT file (believe this doesnt have to be an SCT) executes when you unregister using the scrobj.dll
Scrobj.dll is used to register and unregister COM objects which is what is required to trigger this as the SCT is a COM object servlet doo-daa.