`

OSSEC an open source HIDS --- LogCollector

阅读更多

这些天仔细分析了OSSEC日志收集(LogCollector)部分的细节。

       OSSEC-LogCollector是创建一个无限循环,类似一个监听日志的守护进程,只要监听到日志有变动,就用SOCEKT发送消息给日志分析(analysisd)的守护进程,然后进行解码、匹配等操作。

      

下面先讲OSSEC是如何读取日志的。以读取WINDOWS XP下的事件日志为例。

读取事件日志主要是用到了Windows.h中的几个API:

OpenEventLog,CloseEventLog,ReadEventLog,GetLastError,等。

代码在最下面,我先说明一下每个函数的作用。

int StartEL(char *app, HIDSEL *el) 

打开日志,返回该日志的数目。

char *GetELCategory(int categoryID)

根据类型ID获取日志类型。

char *GetEventDLL(char *evt_name, char *source, char *evt) 

从注册表获取日志的名称。

char *GetELMsg(EVENTLOGRECORD *er,  char *name,  char * source, LPTSTR *elSStr) 

获取该条日志的描述信息。

void ReadEL(HIDSEL *el, int printit)

读取事件日志。注,若只需要读取一次日志,printit设为1即可。OSSEC设置此参数的做法,我想是要忽略已有的日志,只对新产生的日志做处理。

#include "stdio.h"
#include "windows.h"

#define BUFFER_SIZE 2048*256
#define HIDS_MAXSTR 6144
#define HIDS_FLSIZE 256
#define HIDS_LOG_HEADER 256

/*Event logging local structure*/
typedef struct _HIDSEL
{
	int timeOfLast;
	char *name;
	
	EVENTLOGRECORD *er;
	HANDLE h;
	DWORD record;
}HIDSEL;

/*
 *Starts the event logging for each el
 */
int StartEL(char *app, HIDSEL *el)
{
	DWORD recordNum = 0;

	/*Opening the event log*/
	el->h = OpenEventLog(NULL,app);
	if(!el->h)
	{
		printf("HIDS-LogCollecotor ERROR: Uable to open the event log : %s.", app); 
		return (-1);
	}
	
	el->name = app;
	
	if(GetOldestEventLogRecord(el->h, &el->record) == 0)
	{
		/*Unable to read oldest event log record*/
		printf("HIDS-LogCollecotor ERROR: Uable to query last event log from: %s.", app); 
		CloseEventLog(el->h);
		el->h = NULL;
		return(-1);
	}
	
	if(GetNumberOfEventLogRecords(el->h, &recordNum) == 0)
	{		 
		printf("HIDS-LogCollecotor ERROR: Uable to get the number of event logs from: %s.", app); 
		CloseEventLog(el->h);
		el->h = NULL;
		return(-1);
	}
	
	if(recordNum <= 0)
	{
		return 0;
	}
	
	return (int)recordNum;
}

/* 
 * Returns a string related to the category id of the log.
 */
char *GetELCategory(int categoryID)
{
    char *cat;
    switch(categoryID)
    {
        case EVENTLOG_ERROR_TYPE:
            cat = "ERROR";
            break;
        case EVENTLOG_WARNING_TYPE:
            cat = "WARNING";
            break;
        case EVENTLOG_INFORMATION_TYPE:
            cat = "INFORMATION";
            break;
        case EVENTLOG_AUDIT_SUCCESS:
            cat = "AUDIT_SUCCESS";
            break;
        case EVENTLOG_AUDIT_FAILURE:
            cat = "AUDIT_FAILURE";
            break;
        default:
            cat = "Unknown";
            break;
    }
    return	cat;
}


/**
 * Returns the event.
 */
char *GetEventDLL(char *evt_name, char *source, char *evt) 
{
    //char *retStr;
    HKEY key;
    DWORD ret;
    char keyName[512];


    keyName[511] = '\0';

    _snprintf(keyName, 510, 
            "System\\CurrentControlSet\\Services\\EventLog\\%s\\%s", 
            evt_name, 
            source);


    /* Checking if we have it in memory. */
    
    //retStr = OSHash_Get(dll_hash, keyName + 42);
    //if(retStr)
    //{
    //    return(retStr);
    //}
    
    /* Opening registry */	    
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 
                    KEY_ALL_ACCESS, &key) != ERROR_SUCCESS)
    {
        return(NULL);    
    }


    ret = MAX_PATH -1;	
    if (RegQueryValueEx(key, "EventMessageFile", NULL, 
                NULL, (LPBYTE)evt, &ret) != ERROR_SUCCESS)
    {
        evt[0] = '\0';	
        RegCloseKey(key);
        return(NULL);
    }
    else
    {
        /* Adding to memory. */
        char *skey;
        char *sval;

        skey = strdup(keyName + 42);
        sval = strdup(evt);
        
        if(skey && sval)
        {
            //OSHash_Add(dll_hash, skey, sval); 
        }
        else
        {
            printf("Log Collector: ERROR: Not enough Memory. Exiting.");
        }
    }
    
    RegCloseKey(key);
    return(evt);
}


/**
 * Returns a descriptive message of the event.
 */
char *GetELMsg(EVENTLOGRECORD *er,  char *name, 
		    char * source, LPTSTR *elSStr) 
{
    DWORD fmFlags = 0;
    char strTmp[257];
    char event[MAX_PATH +1];
    char *curr_str;
    char *next_str;
    LPSTR message = NULL;

    HMODULE hevt;

    /* Initializing variables */
    event[MAX_PATH] = '\0';
    strTmp[256] = '\0';


    /* Flags for format event */
    fmFlags |= FORMAT_MESSAGE_FROM_HMODULE;
    fmFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER;
    fmFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;



    /* Get the file name from the registry (stored on event) */
    if(!(curr_str = GetEventDLL(name, source, event)))
    {
        return(NULL);	    
    }	    



    /* If our event has multiple libraries, try each one of them */ 
    while((next_str = strchr(curr_str, ';')))
    {
        *next_str = '\0';

        ExpandEnvironmentStrings(curr_str, strTmp, 255);

        /* Reverting back old value. */
        *next_str = ';';
        

        /* Loading library. */
        hevt = LoadLibraryEx(strTmp, NULL, 
                             DONT_RESOLVE_DLL_REFERENCES |
                             LOAD_LIBRARY_AS_DATAFILE);
        if(hevt)
        {
            if(!FormatMessage(fmFlags, hevt, er->EventID, 0,
                              (LPTSTR) &message, 0, elSStr))
            {
                message = NULL;		  
            }
            FreeLibrary(hevt);

            /* If we have a message, we can return it */
            if(message)
                return(message);
        }


        curr_str = next_str +1;
    }

    
    /* Getting last value. */
    ExpandEnvironmentStrings(curr_str, strTmp, 255);
    hevt = LoadLibraryEx(strTmp, NULL, 
                         DONT_RESOLVE_DLL_REFERENCES |
                         LOAD_LIBRARY_AS_DATAFILE);
    if(hevt)
    {
        int hr;    
        if(!(hr = FormatMessage(fmFlags, hevt, er->EventID, 
                        0,
                        (LPTSTR) &message, 0, elSStr)))
        {
            message = NULL;		  
        }
        FreeLibrary(hevt);

        /* If we have a message, we can return it */
        if(message)
            return(message);
    }

    return(NULL);
}


/*
 *Reads the event log.
 */
void ReadEL(HIDSEL *el, int printit)
{
	DWORD _evtid = 65535;
    DWORD nstr;
    DWORD usrSize;
    DWORD domainSize;
    DWORD read, needed;
    int sizeLeft;
    int strSize;
    int id;

    char mbuffer[BUFFER_SIZE +1];
    LPSTR sstr = NULL;

    char *strTmp = NULL;
    char *category;
    char *source;
    char *computerName;
    char *descriptiveMsg;

    char elUsr[HIDS_FLSIZE +1];
    char elDomain[HIDS_FLSIZE +1];
    char elStr[HIDS_MAXSTR +1];
    char finalMsg[HIDS_MAXSTR +1];
    LPSTR elSStr[HIDS_FLSIZE +1];

    /* Er must point to the mbuffer */
    el->er = (EVENTLOGRECORD *) &mbuffer; 

    /* Zeroing the values */
    elStr[HIDS_MAXSTR] = '\0';
    elUsr[HIDS_FLSIZE] = '\0';
    elDomain[HIDS_FLSIZE] = '\0';
    finalMsg[HIDS_MAXSTR] = '\0';
    elSStr[0] = NULL;
    elSStr[HIDS_FLSIZE] = NULL;
    
    /* Event log is not open */
    if(!el->h)
    {
        return;
    }
    
    /* Reading the event log */
    while(ReadEventLog(el->h,
				EVENTLOG_FORWARDS_READ|EVENTLOG_SEQUENTIAL_READ,
				0,
				el->er, BUFFER_SIZE - 1, &read, &needed))
	{
        if(!printit)
        {
            /* Setting er to the beginning of the buffer */
            el->er = (EVENTLOGRECORD *)&mbuffer;
            continue;
        }

        
        while(read > 0)
        {
            /* We need to initialize every variable before the loop */
            category = GetELCategory(el->er->EventType);
            source = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD));
            computerName = source + strlen(source) + 1;
            descriptiveMsg = NULL;

            /* Getting event id. */
            id = (int)el->er->EventID & _evtid;
                            
            /* Initialing domain/user size */
            usrSize = 255; domainSize = 255;
            elDomain[0] = '\0';
            elUsr[0] = '\0';

            /* We must have some description */
            if(el->er->NumStrings)
            {	
                sizeLeft = HIDS_MAXSTR - 1024;	

                sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset);
                elStr[0] = '\0';

                for (nstr = 0;nstr < el->er->NumStrings;nstr++)
                {
                    strSize = strlen(sstr);
                    if(sizeLeft > 1)
					{
                        strncat(elStr, sstr, sizeLeft);
                    }

                    strTmp = strchr(elStr, '\0');
                    if(strTmp)
                    {
                        *strTmp = ' ';		
                        strTmp++; *strTmp = '\0';
                    }
                    else
                    {
                        printf("Log Collector: Invalid application string (size+)");
                    }
                    sizeLeft-=strSize + 2;

                    if(nstr <= 92)
                    {
                        elSStr[nstr] = (LPSTR)sstr;
                        elSStr[nstr +1] = NULL;
                    }

                    sstr = strchr((LPSTR)sstr, '\0');
                    
                    if(sstr)
                        sstr++;
                    else
                        break;     
				}

                /* Get a more descriptive message (if available) */                
                descriptiveMsg = GetELMsg(el->er, 
                                          el->name,
                                          source, 
                                          elSStr);                
                                                        
                if(descriptiveMsg != NULL)
                {
                    /* Remove any \n or \r */
                    /* Replace tabs from the argument field to spaces.
                     * So whenever we have option:\tvalue\t, it will
                     * become option: value\t
                     */
                    strTmp = descriptiveMsg;    
                    while(*strTmp != '\0')
                    {
                        if(*strTmp == '\n')
                            *strTmp = ' ';
                        else if(*strTmp == '\r')
                            *strTmp = ' ';
                        else if((*strTmp == ':') && (strTmp[1] == '\t'))
                        {
                            strTmp[1] = ' ';
                            strTmp++;
                        }
                                    
                        strTmp++;
                    }
                }
            }
            else
            {
                strncpy(elStr, "(no message)", 128);	
            }


            /* Getting username */
            if(el->er->UserSidLength)
            {
                SID_NAME_USE account_type;
                if(!LookupAccountSid(NULL, 
                                    (SID *)((LPSTR)el->er + 
                                    el->er->UserSidOffset),
                                    elUsr, 
                                    &usrSize, 
                                    elDomain, 
                                    &domainSize, 
                                    &account_type))		
                {
                    strncpy(elUsr, "(no user)", 255);
                    strncpy(elDomain, "no domain", 255);
                }

            }
            else
            {
                strncpy(elUsr, "(no user)", 255);	
                strncpy(elDomain, "no domain", 255);	
            }


            if(printit)
            {
                DWORD _evtid = 65535;
                int id = (int)el->er->EventID & _evtid; 
               
                finalMsg[HIDS_MAXSTR - HIDS_LOG_HEADER] = '\0'; 
                finalMsg[HIDS_MAXSTR - HIDS_LOG_HEADER -1] = '\0'; 
                
                printf("WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s\n", 
                        el->name,
                        category, 
                        id,
                        source,
                        elUsr,
                        elDomain,
                        computerName,
                        descriptiveMsg != NULL?descriptiveMsg:elStr);	
                
				/*send msg to server
				 ...................
				 ...................
				 */
            }

            if(descriptiveMsg != NULL)
            {
                LocalFree(descriptiveMsg);
            }

            /* Changing the point to the er */
            read -= el->er->Length;
            el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length);
        }		

        /* Setting er to the beginning of the buffer */	
        el->er = (EVENTLOGRECORD *)&mbuffer;
    }

	
    id = GetLastError();
    if(id == ERROR_HANDLE_EOF)
    {
        return;
    }
    /* Event log was cleared. */
    else if(id == ERROR_EVENTLOG_FILE_CHANGED)
    {
        printf("Log Collector: WARN: Event log cleared: '%s'", el->name);
        
        /* Closing the event log and reopenning. */
        CloseEventLog(el->h);
        el->h = NULL;

        /* Reopening. */
        if(StartEL(el->name, el) < 0)
        {
            printf("Log Collector: ERROR: Unable to reopen event log '%s'", el->name);
        }
    }

    else
    {
        printf("Log Collector: WARN: Error reading event log: %d", id);
    }
}
					  

int main()
{
	HIDSEL hidsEL[3];
	int a,b,c;
	a = StartEL("System",&hidsEL[0]);
	//b = StartEL("Security",&hidsEL[1]);
	//c = StartEL("Application",&hidsEL[2]);
	ReadEL(&hidsEL[0],1);
	//ReadEL(&hidsEL[1],1);
	//ReadEL(&hidsEL[2],1);
	system("pause");
	return 0;
}

 

分享到:
评论

相关推荐

    ossec-hids-3.3.0-pcre2.tar.gz

    "ossec-hids" 指的是 OSSEC(Open Source Security Information and Event Management)主机入侵检测系统,这是一个开源项目,用于监控系统日志、检测异常行为和潜在的攻击。"3.3.0" 是该软件的版本号,表明这是 ...

    ossec2.8.1

    OSSEC是一款开源的基于主机的入侵检测系统,可以简称为HIDS。它具备日志分析,文件完整性检查,策略监控,rootkit检测,实时报警以及联动响应等功能。它支持多种操作系统:Linux、Windows、MacOS、Solaris、HP-UX、...

    ossec-hids-1.6

    OSSEC (Open Source Security Information Management System - 开源安全信息管理系统) 是一款强大的主机入侵检测系统(HIDS),它能够监控和保护操作系统免受恶意活动的影响。版本1.6是该软件的一个早期版本,尽管...

    ossec-hids-2.8.2.zip

    **ossec-hids-2.8.2.zip** 是一个包含OSSEC主机入侵检测系统(Host-based Intrusion Detection System)的版本2.8.2的压缩包。OSSEC是一款开源的、多平台的HIDS,它能提供实时的系统监控、警报以及日志分析功能,...

    ossec-hids-3.6.0 源码

    **ossec-hids-3.6.0 源码详解** OSSEC是开源的入侵检测系统(HIDS,Host-based Intrusion Detection System),它监控系统活动并提供实时告警,帮助用户保护其Linux和Windows服务器免受恶意攻击。3.6.0是该软件的...

    ossec-agent-win32-3.6.0

    WINDOWS下配合OSSEC SERVER的agent,安装方便,与Server段联合使用,可以实现多平台的SEIM功能

    Linux环境下安装OSSEC

    tar -xvzf ossec-hids-&lt;version&gt;.tar.gz cd ossec-hids- ``` 在源代码目录中,执行以下步骤来编译和安装OSSEC: ```bash ./configure make sudo make install ``` 安装完成后,启动OSSEC服务并检查其状态: ```...

    OSSEC-ELK-Application-Servers-Setup:使用Ansible设置OSSEC + ELK + Application Server体系结构

    更改目录cd OSSEC-ELK-Application-Servers-Setup 生成ssh密钥。 您可以将其保存在首选文件中。 ssh-keygen 使用上面生成的ssh密钥的正确路径更新Vagrantfile。 在第19行(私钥)和第20行(公钥)。 我将文件另存...

    ossec-debian:OSSEC HIDS Debian软件包

    这些是用于创建OSSEC-HIDS 2.8版debian软件包的文件,这些文件包含在ossec.net网站和WAZUH存储库中。 您可以在以下位置找到这些软件包: 或直接在以下: : 这些文件可以构建两个不同的程序包: ossec-hids:...

    ossec-agent-win32-2.8.3.exe

    ossec 开源主机威胁检测工具,可以用于在windows系统上收集日志信息,检测攻击行为及文件系统变化等。

    Ossec IDS with Elasticsearch安装部署手册

    其中,开源的OSSEC IDS(Open Source HIDS Security,OSSEC)因其在多平台上的强大功能而受到青睐。本文将详细介绍如何将OSSEC IDS与Elasticsearch和Kibana整合,实现数据存储和呈现的系统部署。 ### OSSEC IDS简介...

    ossec-agent自动安装脚本-linux系统_ossec-agent.zip

    ossec-agent自动安装脚本-linux系统_ossec-agent

    ossec_wui web管理

    ossec(Open Source Security Information Management)是一个开源的、实时的入侵检测系统,它能帮助系统管理员监控和分析系统日志,提供安全警报以及进行系统完整性检查。 **ossec入侵检测系统** ossec是一个多...

    WAZUH-OSSEC:WAZUH-开源安全平台安装

    **WAZUH-OSSEC 开源安全平台安装详解** WAZUH-OSSEC 是一个强大的开源安全监控系统,它提供了实时的入侵检测、主机完整性检查和日志聚合功能。该平台支持多种操作系统,包括 CentOS8,在企业环境中广泛用于提升网络...

    ossec.zip_In It Together_OSSEC_hids_recvfrom

    OSSEC is a full platform to monitor and... It mixes together all the aspects of HIDS (host-based intrusion detection), log monitoring and SIM/SIEM together in a simple, powerful and open source solution.

    OSSEC  &  OSSIM  Unified  Open  Source  Security开源安全框架精要PPT

    OSSEC & OSSIM Unified Open Source Security开源安全框架精要PPT 内容:Why OSSIM ,OSSIM Architecture,OSSIM Embedded Tools,OSSIM Collectors ,OSSIM Collector Anatomy,OSSIM Threat assessment ,OSSIM ...

    OSSEC HIDS 功能有日志分析

    OSSEC HIDS的主要功能有日志分析、完整性检查、rootkit检测、基于时间的警报和主动响应。除了具有入侵检测系统功能外,它还一般被用在SEM/SIM(安全事件管理(SEM: Security Event Management)/安全信息管理(SIM...

    ossec HIDS

    作为一款HIDS,OSSEC应该被安装在一台实施监控的系统中。另外有时候不需要安装完全版本得OSSEC,如果有多台电脑都安装了OSSEC,那么就可以采用客户端/服务器模式来运行。客户机通过客户端程序将数据发回到服务器端...

    风行:入侵检测系统ossec整合

    3. **启动服务**:使用`/usr/local/ossec/bin/ossec-control enable database`命令启用数据库支持,并重启服务。 **客户端(代理)安装**: 1. **下载安装包**:从官方网站下载最新的OSSEC安装包。 2. **解压安装*...

Global site tag (gtag.js) - Google Analytics