Solved

C# wmi security logs

Posted on 2006-06-27
8
1,101 Views
Last Modified: 2011-10-03
Hi, I am using c# WMI to iterate through the application, security and system eventlogs.  This all works fine apart from I cannot enumerate the Security log (I am a local admin on the computer) I use the win32_nteventlog.  How do I get all the events inside the security log?  Thanks.
0
Comment
Question by:AlistairDyer
  • 3
  • 2
8 Comments
 
LVL 41

Expert Comment

by:graye
ID: 16993917
Reading from the Event Logs requries a privilege that is not enabled by default (even for administrators).   You'll have to write a small routine to enable the SeSecurityPrivilege on the current thread.

Here is an example that does precisely that.  (Sorry, it's written in VB.Net, but I'd bet it'd be trivial to convert)

Imports System.Runtime.InteropServices
Public Class SetSeSecurityPrivilege

    <StructLayout(LayoutKind.Sequential, Pack:=4)> _
    Private Structure LUID_AND_ATTRIBUTES
        Dim Luid As Long
        Dim Attributes As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential, Pack:=4)> _
    Private Structure TOKEN_PRIVILEGES
        Dim PrivilegeCount As Integer
        Dim Privilege1 As LUID_AND_ATTRIBUTES
    End Structure

    'BOOL OpenProcessToken(
    '  HANDLE ProcessHandle,
    '  DWORD DesiredAccess,
    '  PHANDLE TokenHandle
    ');
    Private Declare Function OpenProcessToken Lib "advapi32.dll" ( _
        ByVal ProcessHandle As IntPtr, _
        ByVal DesiredAccess As Integer, _
        ByRef TokenHandle As IntPtr _
    ) As Boolean

    'BOOL LookupPrivilegeValue(
    '  LPCTSTR lpSystemName,
    '  LPCTSTR lpName,
    '  PLUID lpLuid
    ');

    Private Declare Auto Function LookupPrivilegeValue Lib "advapi32.dll" ( _
        ByVal lpSystemName As String, _
        ByVal lpName As String, _
        ByRef lpLuid As Long _
    ) As Boolean

    'BOOL AdjustTokenPrivileges(
    '  HANDLE TokenHandle,
    '  BOOL DisableAllPrivileges,
    '  PTOKEN_PRIVILEGES NewState,
    '  DWORD BufferLength,
    '  PTOKEN_PRIVILEGES PreviousState,
    '  PDWORD ReturnLength
    ');
    Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" ( _
        ByVal TokenHandle As IntPtr, _
        ByVal DisableAllPrivileges As Boolean, _
        ByRef NewState As TOKEN_PRIVILEGES, _
        ByVal BufferLength As Integer, _
        ByVal PreviousState As IntPtr, _
        ByVal ReturnLength As IntPtr _
    ) As Boolean

    Private Const TOKEN_QUERY As Integer = &H8
    Private Const TOKEN_ADJUST_PRIVILEGES As Integer = &H20
    Private Const SE_SECURITY_NAME As String = "SeSecurityPrivilege"
    Private Const SE_PRIVILEGE_ENABLED As Integer = &H2
    '
    ' Set the privileges for reading the Security Logs
    '
    Public Function SetPrivileges() As Boolean
        Dim hProc, hToken As IntPtr
        Dim luid_Security As Long
        Dim tp As New TOKEN_PRIVILEGES

        ' Get the current process's token
        hProc = Process.GetCurrentProcess().Handle
        hToken = IntPtr.Zero
        If Not OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) Then
            Return False
        End If

        ' Get the LUIDs for the Security privilege
        luid_Security = 0
        If Not LookupPrivilegeValue(Nothing, SE_SECURITY_NAME, luid_Security) Then
            Return False
        End If

        tp.PrivilegeCount = 1
        tp.Privilege1.Luid = luid_Security
        tp.Privilege1.Attributes = SE_PRIVILEGE_ENABLED

        ' Enable the privileges
        If Not AdjustTokenPrivileges(hToken, False, tp, 0, IntPtr.Zero, IntPtr.Zero) Then
            Return False
        End If

        Return True
    End Function
End Class
0
 
LVL 1

Author Comment

by:AlistairDyer
ID: 17041428
So there is no way to query the security log through WMI?  You have to use a token? I have managed to get the security log from WMI using VB6.0 without an issue...  there must be an easier way of getting the log than this?
0
 
LVL 41

Expert Comment

by:graye
ID: 17043905
Huh?  Sure, there's a way to read the security log through WMI with a managed application!

All you have to do is adjust a security token before you connect via WMI.  After you've performed that little feat of magic, your existing code to read the event logs will now work for the Security log file.  There's nothing else to do.

Did you need help translating the example to C#?
0
 
LVL 1

Author Comment

by:AlistairDyer
ID: 17049025
Yes please :)
0
 
LVL 41

Accepted Solution

by:
graye earned 500 total points
ID: 17050948
Okey dokey....

Here is the class in C#.   You'd use it like this:

            SetSeSecurityPrivilege setPriv = new SetSeSecurityPrivilege();
            setPriv.SetPrivileges();

            // perform the connection to WMI here...

-------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

public class SetSeSecurityPrivilege
{
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct LUID_AND_ATTRIBUTES
    {
        public long Luid;
        public int Attributes;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct TOKEN_PRIVILEGES
    {
        public int PrivilegeCount;
        public LUID_AND_ATTRIBUTES Privilege1;
    }

    [System.Runtime.InteropServices.DllImport("advapi32.dll")]
    private static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);
   
    [System.Runtime.InteropServices.DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    private static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref long lpLuid);
   
    [System.Runtime.InteropServices.DllImport("advapi32.dll")]
    private static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, IntPtr ReturnLength);
   
    private const int TOKEN_QUERY = 8;
    private const int TOKEN_ADJUST_PRIVILEGES = 32;
    private const string SE_SECURITY_NAME = "SeSecurityPrivilege";
    private const int SE_PRIVILEGE_ENABLED = 2;

    public bool SetPrivileges()
    {
        IntPtr hProc;
        IntPtr hToken;
        long luid_Security;    
        TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES();

        // get the process token
        hProc = Process.GetCurrentProcess().Handle;
        hToken = IntPtr.Zero;
        if (!(OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hToken)))
        {
            return false;
        }
       
        // lookup the ID for the privilege we want to enable
        luid_Security = 0;
        if (!(LookupPrivilegeValue(null, SE_SECURITY_NAME, ref luid_Security)))
        {
            return false;
        }
       
        tp.PrivilegeCount = 1;
        tp.Privilege1.Luid = luid_Security;
        tp.Privilege1.Attributes = SE_PRIVILEGE_ENABLED;
       
        // enable the privilege
        if (!(AdjustTokenPrivileges(hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero)))
        {
            return false;
        }
        return true;
    }
}
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now