пятница, 24 июля 2020 г.

_TlgProvider_t

let's continue to dissect ETW and consider one of the many usermode tracing structures - _TlgProvider_t. It is even officially documented in platform sdk in header TraceLoggingProvider.h (sample of using):
struct _TlgProvider_t
{
    UINT32 LevelPlus1;
    UINT16 const UNALIGNED* ProviderMetadataPtr; // Points to the RemainingSize member of provider metadata.
    ULONGLONG KeywordAny;
    ULONGLONG KeywordAll;
    REGHANDLE RegHandle;
    TLG_PENABLECALLBACK EnableCallback;
    PVOID CallbackContext;
};


purpose of the fields is pretty obvious except RegHandle - it's not real HANDLE but some structure with address to ETW_REGISTRATION_ENTRY.

How we can find it? Field ProviderMetadataPtr is pointer to _TlgProviderMetadata_t:
struct _TlgProviderMetadata_t
{
    UINT8 Type; // = _TlgBlobProvider3
    GUID ProviderId;
#define _TLG_PROVIDER_METADATA_PREAMBLE 16 // = sizeof(ProviderId)
    UINT16 RemainingSize; // = sizeof(RemainingSize + ProviderName)
    /*
    char ProviderName[sizeof("providerName")]; // UTF-8 nul-terminated provider name
    for each additional chunk of metadata {
        UINT16 ChunkSize;
        UINT8 ChunkType;
        UINT8 ChunkData[ChunkSize - 3];
    }
    */
};

actually it points to _TlgProviderMetadata_t.RemainingSize. Algo is simple - if you know provider GUID you can locate _TlgProviderMetadata_t.ProviderId by signature (usually located in .text or .rdata sections) and then find in .data section _TlgProvider_t whose ProviderMetadataPtr points to _TlgProviderMetadata_t.RemainingSize. I made simple PoC for arm64

How we can abuse it? Let`s see how this structures used for example in combase.dll:

  cmp     _Tlgg_hCombaseTraceLoggingProviderProv.LevelPlus1, 5
  jbe     skip_logging
  push    useTimer                      ; keyword
  push    useTimer                      ; hProvider
  call    __TlgKeywordOn@12             ; _TlgKeywordOn(x,x,x)
  test    al, al
  jz      skip_logging


One obvious way is just zero LevelPlus1. Lets see inside TlgKeywordOn:
BOOLEAN _TlgKeywordOn(
    TraceLoggingHProvider _In_ hProvider,
    ULONGLONG keyword)
    TLG_NOEXCEPT
{
    return keyword == 0 || (
        (keyword & hProvider->KeywordAny) &&
        (keyword & hProvider->KeywordAll) == hProvider->KeywordAll);
}


So perhaps we can also zero any of KeywordAny/KeywordAll fields. And finally we can just zero RegHandle. So if you have enough rights (or driver) you can disable tracing in any running process (for example services.exe, lsass, RPC Service, DCom Server etc)

Комментариев нет:

Отправить комментарий