首页 > 系统相关 >使用Python解析Windows系统日志

使用Python解析Windows系统日志

时间:2022-12-11 23:11:16浏览次数:80  
标签:node xml evtx Python list Windows Provider Security 系统日志

目标要求:对Windows系统日志进行处理,并生成统计文件

1. 如何找到Windows系统日志?

通常情况下,我们都是在Windows系统自带的事件查看器查看系统日志(使用 win + x 可以快速找到事件查看器)。所有系统日志都存在C:\Windows\System32\winevt\Logs目录中。这里我们采用Setup日志
(即Setup.evtx),然后将这个文件拷贝到工作目录。
image.png

2. 查看日志的主要结构

通过事件查看器,我们可以简单了解每条日志包含的信息。如图是该条日志的常规信息,然后我们切换到详细信息
image.png
如图,详细信息分为友好视图、XML视图。可见它包含了System和Userdata两个数据块
image.png
切到XML视图,我们发现内部结构是这样的,接下来的工作就是要提取我们需要的字段了

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
	<System>
		<Provider 
			Name="Microsoft-Windows-Servicing" Guid="{bd12f3b8-fc40-4a61-a307-b7a013a069c1}" />
		<EventID>2</EventID>
		<Version>0</Version>
		<Level>0</Level>
		<Task>1</Task>
		<Opcode>0</Opcode>
		<Keywords>0x8000000000000000</Keywords>
		<TimeCreated SystemTime="2022-11-19T15:15:05.7275237Z" />
		<EventRecordID>323</EventRecordID>
		<Correlation />
		<Execution ProcessID="3628" ThreadID="3820" />
		<Channel>Setup</Channel>
		<Computer>DESKTOP-P16J0BP</Computer>
		<Security UserID="S-1-5-18" />
	</System>
	<UserData>
		<CbsPackageChangeState 
			xmlns="http://manifests.microsoft.com/win/2004/08/windows/setup_provider">
			<PackageIdentifier>KB5015684</PackageIdentifier>
			<IntendedPackageState>5112</IntendedPackageState>
			<IntendedPackageStateTextized>Installed</IntendedPackageStateTextized>
			<ErrorCode>0x0</ErrorCode>
			<Client>UpdateAgentLCU</Client>
		</CbsPackageChangeState>
	</UserData>
</Event>

3. 正式处理文件

首先,先导入需要的包,这里使用了python-extv库处理.evtx文件,用Python内置的xml库。使用mmap申请内存块、contextlib 用于上下文处理,openpyxl处理excel文档

import mmap
import contextlib
import openpyxl
from Evtx.Evtx import FileHeader
from Evtx.Views import evtx_file_xml_view
from xml.dom import minidom

然后开始写处理函数func()EvtxPath是要处理的 evtx 文件路径,然后用只读方法打开文件。使用上下文处理器contextlib.closing管理文件,并使用mmap.mmap方法将文件映射到内存中。查看python-evtx的源码,发现Evtx.Views.evtx_file_xml_view方法是返回两个参数:文档字符串record_str,地址record

def func():
    EvtxPath = "E:\desktop\test\Setup.evtx"
    with open(EvtxPath, 'r') as f:
        with contextlib.closing(
			mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)) as buf:
            p = FileHeader(buf, 0)
            for xml, record in evtx_file_xml_view(p):
                xmldoc = minidom.parseString(xml)
                root_node = xmldoc.documentElement
def evtx_file_xml_view(file_header):
    """
    Generate XML representations of the records in an EVTX file.

    Does not include the XML <?xml... header.
    Records are ordered by file_header.chunks(), and then by chunk.records()

    Args:
      chunk (Evtx.FileHeader): the file header to render.

    Yields:
      tuple[str, Evtx.Record]: the rendered XML document and the raw record.
    """
    for chunk in file_header.chunks():
        for record in chunk.records():
            record_str = evtx_record_xml_view(record)
            yield record_str, record

然后使用xml.dom.mindom方法读取这个xml串,并用documentElement方法获取xml的根结点

关于xml的操作参考
https://www.runoob.com/dom/prop-document-xmlversion.html
https://blog.csdn.net/m0_37102093/article/details/109622710

然后根据需求,使用getElementsByTagName方法提取需要的结点即可

4. 补充和拓展

解析完,我们发现竟然没有事件摘要,我查阅了很多资料但没得到解决。如果想要获取事件摘要,可以在Windows事件查看器中将文件导出为XML文件
image.pngimage.png
如何解析XML文件呢?思路和前边一致,我就直接粘贴代码了,如下:

import openpyxl
from xml.dom import minidom

def Func():
    EvtxPath = "E:\desktop\Setup.xml"
    xmldoc = minidom.parse(EvtxPath)
    root_node = xmldoc.documentElement
    # 事件
    Message_node_list = root_node.getElementsByTagName('Message')
    Message_list = []
    for Message_node in Message_node_list:
        Message_list.append(Message_node.firstChild.nodeValue)
    # 时间
    TimeCreated_node_list = root_node.getElementsByTagName('TimeCreated')
    TimeCreated_list = []
    for TimeCreated_node in TimeCreated_node_list:
        TimeCreated_list.append(TimeCreated_node.getAttribute('SystemTime'))
    # Provider
    Provider_node_list = root_node.getElementsByTagName('Provider')
    Provider_list = []
    for Provider_node in Provider_node_list:
        if Provider_node.firstChild is not None:
            Provider_list.append(Provider_node.firstChild.nodeValue)
        else:
            Provider_list.append(Provider_node.firstChild)
    # PC name
    Computer_node_list = root_node.getElementsByTagName('Computer')
    Computer_list = []
    for Computer_node in Computer_node_list:
        Computer_list.append(Computer_node.firstChild.nodeValue)
    # Security user_id
    Security_node_list = root_node.getElementsByTagName('Security')
    Security_list = []
    for Security_node in Security_node_list:
        Security_list.append(Security_node.getAttribute('UserID'))

    writer = openpyxl.load_workbook('E:\desktop\out2.xlsx')
    sheet = writer['Sheet1']
    sheet.append(['事件', '时间', '服务提供者', '服务主机', 'Security user_id'])
    for i in range(len(Message_list)):
        temp = [
            Message_list[i], TimeCreated_list[i], Provider_list[i], Computer_list[i],Security_list[i]
        ]
        sheet.append(temp)
    writer.save('E:\desktop\out2.xlsx')

Func()

然后查看生成文件:
image.png

标签:node,xml,evtx,Python,list,Windows,Provider,Security,系统日志
From: https://www.cnblogs.com/nixwl/p/16974836.html

相关文章