7

My task is to make an ETW real-time consumer with events provided by 'Microsoft Windows Security Auditing'.

I made a simple controller and consumer application, basing on this example http://msdn.microsoft.com/en-us/library/windows/desktop/ee441325%28v=vs.85%29.aspx and changing flags to work in real-time mode.

The main function looks this way:

LPTSTR SessionName = L"hahahaaa";
ULONG status = ERROR_SUCCESS;
PEVENT_TRACE_PROPERTIES pSessionProperties = NULL;
EVENT_TRACE_LOGFILE trace;
TRACEHANDLE hTrace = 0;
TRACEHANDLE hSession = 0;
const GUID  providerId = { 0x54849625, 0x5478, 0x4994, { 0xA5, 0xBA, 0x3E, 0x3B, 0x03, 0x28, 0xC3, 0x0D } };
//const GUID  providerId = { 0xA68CA8B7, 0x004F, 0xD7B6, { 0xA6, 0x98, 0x07, 0xE2, 0xDE, 0x0F, 0x1F, 0x5D } };

HANDLE hToken = NULL;
HANDLE hProcess = NULL;
hProcess = GetCurrentProcess();
if (OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) == FALSE)  {
    printf("Error: Couldn't open the process token\n");
    goto cleanup;
}
if(!SetPrivilege(hToken, SE_SECURITY_NAME, TRUE)) goto cleanup;

if (!pSessionProperties) {
    const size_t buffSize = sizeof(EVENT_TRACE_PROPERTIES)+(_tcslen(SessionName) + 1) * sizeof(TCHAR);
    pSessionProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES *>(malloc(buffSize));
    ZeroMemory(pSessionProperties, buffSize);
    pSessionProperties->Wnode.BufferSize = buffSize;
    pSessionProperties->Wnode.ClientContext = 1;
    pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    pSessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
    pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
}

// Create the trace session.
status = StartTrace(&hSession, SessionName, pSessionProperties);
if (ERROR_SUCCESS != status) {
    wprintf(L"StartTrace() failed with %lu\n", status);
    goto cleanup;
}

status = EnableTraceEx2(hSession, &providerId, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL);
if (ERROR_SUCCESS != status) {
    wprintf(L"EnableTrace() failed with %lu\n", status);
    goto cleanup;
}

ZeroMemory(&trace, sizeof(EVENT_TRACE_LOGFILE));
trace.LogFileName = NULL;
trace.LoggerName = SessionName;
trace.CurrentTime = 0;
trace.BuffersRead = 0;
trace.BufferSize = 0;
trace.Filled = 0;
trace.EventsLost = 0;
trace.Context = NULL;
trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)(ProcessEvent);

hTrace = OpenTrace(&trace);
if (INVALID_PROCESSTRACE_HANDLE == hTrace)
{
    wprintf(L"OpenTrace failed with %lu\n", GetLastError());
    goto cleanup;
}

status = ProcessTrace(&hTrace, 1, 0, 0);
if (status != ERROR_SUCCESS && status != ERROR_CANCELLED)
{
    wprintf(L"ProcessTrace failed with %lu\n", status);
    goto cleanup;
}

The application at 'ProcessTrace()' point should wait for incoming events and write to stdout theirs meta-data. But it simply does not. All generated events by me (i.e. I turn on Detailed Tracking - Process Creation and run an application) are shown in EventViewer, but my program shows nothing.

I thought that it might be some privileges problem, and using this example http://msdn.microsoft.com/en-us/library/windows/desktop/aa446619%28v=vs.85%29.aspx I set SE_SECURITY_NAME privilege and of course run application in Administrator's mode. But nothing changed.

Another try was a session name. Maybe it is the same problem as with 'Windows Kernel Trace' which can log only to system session 'NT Kernel Logger'. Only thing which I found was that 'Microsoft Windows Security Auditing' is correlated with 'Eventlog-Security' session, but when I set session name by this I received 'Access Denied' error. I don't know which extra privilege I should set to handle this.

Last try was to use 'logman' and collect events into a file, but everything was the same. When I set session name by 'Eventlog-Security' I received 'Access Denied'. On the other hand, when I set it by something else I only received one event, provided by 'MSNT_SystemTrace', which is the abstract class for other events.

If I change provider to i.e. 'Microsoft Windows Kernel General' (commented GUID) and generate an event (update system clock) everything works as it should (in my application and using 'logman').

I works in Windows 7 Professional x64 and Visual Studio Ultimate 2013.

My question is, what can I do to receive events from 'Microsoft Windows Security Auditing' provider?

Thanks for any help!

EDIT As I wrote in comment, if we set SessionName on Eventlog-Security, the application is shortened to OpenTrace() and ProcessTrace().

EDIT 2 As Luke suggested in comment, I ran my application with LocalSystem privileges, and everything started working.

5
  • Which call fails with ERROR_ACCESS_DENIED?
    – Luke
    Jan 2, 2015 at 22:26
  • @Luke It fails at ProcessTrace() when the session name is set on Eventlog-Security. I didn't write this, but in this case, application is limited to OpenTrace() and ProcessTrace() functions - StartTrace() and EnableTraceEx2() are useless.
    – user4410709
    Jan 2, 2015 at 23:47
  • 1
    Looks like this provider only grants access to LocalSystem, so either you need to run your code as LocalSystem or modify the permissions.
    – Luke
    Jan 3, 2015 at 14:15
  • 1
    @Luke Thank you so much! I ran psexec -s -i cmd.exe which gave me console with system privileges and my application started working :)
    – user4410709
    Jan 3, 2015 at 20:31
  • that comment should have been an answer
    – paulm
    Jan 17, 2015 at 12:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy