zoukankan      html  css  js  c++  java
  • win32

    微软文档介绍说,

    安全日志在其他两个重要方面与其他日志不同。首先,在默认配置中,它受到强大的访问控制列表(ACL)和特权检查的保护,这将可以读取其内容的个人的范围限制为本地系统,管理员和安全特权的持有者。其次,也是最重要的一点,只允许一个实体(本地安全机构(LSA))写入安全日志。这实际上意味着,每次尝试为安全日志调用RegisterEventSource API时,即使您以本地系统身份运行,也会收到ACCESS_DENIED错误!这种设计可确保安全日志仅包含来自受信任来源的信息。

    在Windows Server 2003中,安全日志写访问限制在某种程度上得到了放松,而没有通过引入一组特殊的API来更改基本设计(请参见图2)。这些API在内部使用本地过程调用(LPC)与LSA进行交互,指示LSA代表应用程序生成审核日志。该机制优雅而简单。

    首先,应用程序通过调用AuthzRegisterSecurityEventSource向LSA注册安全事件源句柄。此API唯一感兴趣的参数是事件源的名称,该名称可以是几乎任何内容,并受一些限制。例如,它不能命名为“ Security”,因为该名称保留供系统使用。在以下步骤中使用此调用返回的安全事件源句柄。

    接下来,通过调用两个紧密相关的API之一来生成事件:AuthzReportSecurityEvent或AuthzReportSecurityEventFromParams。最后,当应用程序关闭时,它将通过调用AuthzUnregisterSecurityEventSource取消注册安全事件源句柄。

    在编译代码之前,我们需要赋予当前用户相关的权限,也就是Generate Security audits

    具体步骤:

    在开始菜单中,打开Local Security Policy,如下图,

    找到Generate Security audits, 在里面添加当前用户,我们的计算机一般是以管理员身份运行的,所以可以将管理员也添加进来(添加完需要将电脑重启,以使组策略生效)。

    如果是以管理员身份运行的,那么我们在编译代码时,也需要以管理员身份运行代码。不然还是无法获取SeAuditPrivilege权限。

    另外,我们还需要在Audit Policy中Enable Audit object access的Success,Failure, 见下图,

    代码示例:

    #include <stdio.h>
    #include <iostream>
    #include <string>
    #include <strsafe.h>
    #include <windows.h>
    #include <Authz.h>
    #include <Ntsecapi.h>
    
    #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
    
    #pragma comment(lib,"Authz.lib")
    #pragma comment(lib,"Advapi32.lib")
    
    void print_privileges(HANDLE hToken);
    
    BOOL SetPrivilege(
        HANDLE hToken,          // access token handle
        LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
        BOOL bEnablePrivilege   // to enable or disable privilege
    )
    {
        TOKEN_PRIVILEGES tp;
        LUID luid;
    
        if (!LookupPrivilegeValue(
            NULL,            // lookup privilege on local system
            lpszPrivilege,   // privilege to lookup
            &luid))        // receives LUID of privilege
        {
            printf("LookupPrivilegeValue error: %u
    ", GetLastError());
            return FALSE;
        }
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        if (bEnablePrivilege)
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tp.Privileges[0].Attributes = 0;
    
        // Enable the privilege or disable all privileges.
    
        if (!AdjustTokenPrivileges(
            hToken,
            FALSE,
            &tp,
            sizeof(TOKEN_PRIVILEGES),
            (PTOKEN_PRIVILEGES)NULL,
            (PDWORD)NULL))
        {
            printf("AdjustTokenPrivileges error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    
        {
            printf("The token does not have the specified privilege. 
    ");
            return FALSE;
        }
    
        printf("Get the specified privilege! 
    ");
    
        return TRUE;
    }
    
    
    
    
    int main(int argc, const char* argv[])
    {
        // Declare and initialize variables.
    
        BOOL bResult = TRUE;
        DWORD event_id = 4624; 
        AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider = NULL;
        PAUDIT_PARAMS p;
        std::string Source_Name = "Test security audit";
        std::wstring ws;
        std::string pbuf = "What is your purpose ?";
        std::wstring ws_buf;
        int return_code = 0;
        int i = 0;
        // Register the audit provider.
        HANDLE token;
        HANDLE hevent_source;
        ws.assign(Source_Name.begin(), Source_Name.end());
        ws_buf.assign(pbuf.begin(), pbuf.end());
    
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
            return FALSE;
    
        SetPrivilege(token, L"SeAuditPrivilege", true);
        print_privileges(token);
    
        AUTHZ_SOURCE_SCHEMA_REGISTRATION ar;
        memset(&ar, 0, sizeof(ar));
        ar.dwFlags = AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES;
        ar.szEventSourceName = &ws[0];
        ar.szEventMessageFile = &ws_buf[0];
        ar.szEventSourceXmlSchemaFile = NULL;
        ar.szEventAccessStringsFile = &ws_buf[0];
        ar.szExecutableImagePath = NULL;
    
        AuthzInstallSecurityEventSource(0, &ar);
    
        bResult = AuthzRegisterSecurityEventSource(0, ws.c_str(), &hEventProvider);
        int err = GetLastError();
        if (!bResult)
        {
            printf("AuthzRegisterSecurityEventSource failed, error is %d
    ", err);
            return_code = -1;
        } 
    
        SID id;
        if (hEventProvider)
        {
            // Generate the audit.
            while (i < 10) {
                bResult = AuthzReportSecurityEvent(
                    APF_AuditSuccess,
                    hEventProvider,
                    event_id,
                    NULL,
                    3,
                    APT_String, L"Jay Hamlin",
                    APT_String, L"March 21, 1960",
                    APT_Ulong, 45);
                int err1 = GetLastError();
                if (!bResult)
                {
                    printf("AuthzReportSecurityEvent failed, error is %d
    ", err1);
                    return_code = -2;
                    break;
                }
    
                i++;
            }
    
            AuthzUnregisterSecurityEventSource(0, &hEventProvider);
            AuthzUninstallSecurityEventSource(0, &ws[0]);
        }
        std::cout << "Exit  : " << return_code << std::endl;
    
    
        getchar();
    }
    
    void print_privileges(HANDLE hToken)
    {
        DWORD size = 0;
        if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &size) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)malloc(size);
            if (tp != NULL && GetTokenInformation(hToken, TokenPrivileges, tp, size, &size)) {
                size_t i;
                for (i = 0; i < tp->PrivilegeCount; ++i) {
                    char name[64] = "?";
                    DWORD name_size = sizeof name;
                    LookupPrivilegeNameA(0, &tp->Privileges[i].Luid, name, &name_size);
                    PRIVILEGE_SET ps = {
                        1, PRIVILEGE_SET_ALL_NECESSARY, {
                            { { tp->Privileges[i].Luid.LowPart, tp->Privileges[i].Luid.HighPart } }
                        }
                    };
                    BOOL fResult;
                    PrivilegeCheck(hToken, &ps, &fResult);
                    printf("%-*s %s
    ", 32, name, fResult ? "Enabled" : "Disabled");
                }
            }
            free(tp);
        }
    }

    在运行过程中,首先确定是否获取了我们需要的权限。

    如果是Enabled的状态,说明获取权限成功,后面只需要通过AuthzRegisterSecurityEventSource和AuthzReportSecurityEvent这两个api与LSA进行交互,从而写入安全日志。

    最后的结果:

  • 相关阅读:
    Oracle中有大量的sniped会话
    Error 1130: Host '127.0.0.1' is not allowed to connect to this MySQL server
    汉字转换为拼音以及缩写(javascript)
    高效率随机删除数据(不重复)
    vs2010 舒服背景 优雅字体 配置
    mvc中的ViewData用到webfrom中去
    jquery ajax return值 没有返回 的解决方法
    zShowBox (图片放大展示jquery版 兼容性好)
    动感效果的TAB选项卡 jquery 插件
    loading 加载提示······
  • 原文地址:https://www.cnblogs.com/strive-sun/p/13633498.html
Copyright © 2011-2022 走看看