概念
网络资产识别规则是一种从大段文本数据或二进制数据中提取网络资产信息的规则文件,该规则文件由人工编写,然后由解析引擎解析,解析引擎通过规则文件中配置的资产提取规则,从数据源中提取关键信息。
大段文本或二进制数据通常来自网络流量、系统配置文件、系统日志等。
网络资产信息通常包括:IP、端口、服务、产品名称、产品版本、产品厂商、系统资源路径等。
背景
在网络安全监测和防御的过程中,精准、可扩展的资产识别系统至关重要,网络攻防是一场持久战,要想百战不殆,首先要知己。了解自己需要防护的东西,才能更好的防护。
目前常用的资产管理系统大都通过流程化方式对资产进行人工的管理,这种方式在信息系统日渐庞大的今天已经显得力不从心。人工管理的方式只能管理基础的信息,例如:IP、操作系统、端口、服务、业务名称,负责人信息等,但对于系统更加深入的资产信息,例如:服务版本、系统框架、系统资产路径等就难以维护了,但这些更加深入的资产信息往往是网络安全中更为重要的信息。当我们掌握了系统的服务版本时,对于严重的漏洞事件就可以及时轻松筛选排查修复;当我们掌握系统所用框架时,对于监测到的网络攻击事件就可以有针对性的进行过滤和重点筛查;当我们掌握了系统所有的资源路径信息甚至是参数模式时,我们甚至可以应用零信任原则将不符合资产记录的其他请求全部拦截。
因此我们想通过自动化的资产探测与识别系统解决资产管理问题,通过实时的流量数据,对流量数据中的资产信息进行识别提取,实时更新资产信息库。并且由于资产信息的复杂多变,我们需要一套标准化的规则,可以让安全运维人员进行编写,动态扩展系统的资产识别能力。
网络安全工作的核心就是做好每个细节,没有捷径可寻,资产识别是其中一小步。
提案
规则文件考虑采用XML格式,相对比较易读,提取的核心方式使用正则表达式进行提取,特别是版本的提取通过正则表达式中的group特性进行提取。
需要支持的数据源包括:
HTTP响应头格式数据
HTML格式数据
XML格式数据
JSON格式数据
单行文本数据。
需要支持的提取场景包括:
HTTP响应头Server字段中的服务名称/服务版本/组件名称/组件版本提取
HTTP响应头X-Powerded-By字段中的框架提取
HTTP响应体Tomcat报错信息中的组件信息提取
Maven配置文件pom.xml中的框架名称/厂家/版本提取
<?xml version="1.0" encoding="UTF-8" ?>
<assets>
<!--
多条规则识别同一资产怎么处理,特别是有模糊提取的规则,有精准提取的规则,是否有优先级
-->
<asset start="Server:" end="\r\n" greedy="true" >
<vendor seq="1">
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product required="true" seq="2">
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1"/>
</product>
<version seq="3">
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1"/>
</version>
</asset>
<asset condition="Server:" greedy="true">
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product required="true">
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1"/>
</product>
<version>
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1"/>
</version>
</asset>
<asset condition="Server:" greedy="false">
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product>
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1">unknown</result>
</product>
<version>
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1">unknown</result>
</version>
</asset>
<asset>
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product>
<condition fromStart="false">Server: nginx</condition>
<result>nginx</result>
</product>
<version>
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1">1.1.1</result>
</version>
</asset>
<asset condition="Server:">
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product>
<condition fromStart="false">nginx</condition>
<result>nginx</result>
</product>
<version>
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version">unknown</result>
</version>
</asset>
<asset condition="Server:">
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product>
<condition fromStart="false">nginx</condition>
<result>nginx</result>
</product>
<version>
<condition fromStart="false">nginx/(\d+\.\d+\.\d+)</condition>
<result groupIndex="1">unknown</result>
</version>
</asset>
</assets>
seq游标顺序匹配机制
<asset start="Server:" end="\r\n" greedy="true" >
<vendor seq="1">
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product required="true" seq="2">
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1"/>
</product>
<version seq="3">
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1"/>
</version>
</asset>
group提取模式
<asset>
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product>
<condition fromStart="false">Server: nginx</condition>
<result>nginx</result>
</product>
<version>
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1">1.1.1</result>
</version>
</asset>
greedy贪婪模式
<asset condition="Server:" greedy="true">
<vendor>
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product required="true">
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1"/>
</product>
<version>
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1"/>
</version>
</asset>
讨论
问题一
资产识别增加协议类型属性?
protocol="http"
dataType="http"
由于不止适用网络数据,建议命名为dataType
dataType字段的功能是前置条件,还是提供后续匹配特殊的功能?还是两者?
<asset start="Server:" end="\r\n" greedy="true" dataType="http">
<vendor seq="1">
<condition fromStart="false"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product required="true" seq="2">
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1"/>
</product>
<version seq="3">
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1"/>
</version>
</asset>
问题二【与问题一合并】
资产识别增加数据类型属性?
与问题一合并
问题三【暂不考虑】
加入网络方向属性?
兼容需要通过请求和响应共同作用的识别方式?
此方式需要规定多种输入字段
request 指定数据方向 client -> server
response 指定数据方向 server -> client
default 未指定默认为default, default优先匹配response,一个输入
由于资产识别数据源并不一定来源网络数据,面向的还是单个文本中的数据提取。而且多个字段输入会破坏seq游标顺序匹配机制。因此该提案暂不考虑。
<asset start="Server:" end="\r\n" greedy="true" dataType="http">
<vendor seq="1">
<condition fromStart="false" field="response"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<result groupName="vendor" groupIndex="1"/>
</vendor>
<product required="true" seq="2">
<condition fromStart="false"><![CDATA[Server:\\s*(?<product>\\w+)]]></condition>
<result groupName="product" groupIndex="1"/>
</product>
<version seq="3">
<condition fromStart="false">nginx/(?<version>\d+\.\d+\.\d+)</condition>
<result groupName="version" groupIndex="1"/>
</version>
</asset>
问题四【暂不考虑】
condition支持多个正则逻辑运算?
为提高准确性以及减少误报
多个正则模式不支持提取模型,只支持匹配模式
由于已经有asset start="Server:" end="\r\n"进行限制,单条正则匹配应可以符合需求,并且多条正则暂没有group提取方案,只能支持匹配模型,因此,该提案暂不考虑。
<vendor seq="1">
<condition fromStart="false" field="response" expression="a+b|c">
<condition fromStart="false" field="response"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
<condition fromStart="false" field="response"><![CDATA[Server:\\s*(?<vendor>\\w+)]]></condition>
</condition>
<result>厂商xxx</result>
</vendor>
问题五
多条规则识别同一资产怎么处理,特别是有模糊提取的规则,有精准提取的规则,是否有优先级
问题六【暂不考虑】
正则有难度数据,能否不写正则,资产的提取还是有一定规律的
使用预定义正则,对于常见的提取方式进行预定义
目前还未投入实际运行,待实际的使用需求出来,再进行预定义
实现
未完待续