zeek使用——用于网络流量分析IDS,不知道用在tls1.3里是否支持?

写在前面

1)通过zeek读取PCAP格式的原始报文进行行为分析
本例编写脚本,分析PCPA报文中的文件内容,zeek脚本内容如下:
复制代码
event connection_state_remove(c: connection)
    {
    print "connection_state_remove";
    print c$uid;
    print c$id;
    for ( s in c$service )
        print s;
    }

event file_state_remove(f: fa_file)
    {
    print "file_state_remove";
    print f$id;
    for ( cid in f$conns )
        {
        print f$conns[cid]$uid;
        print cid;
        }
    print f$source;
    }
复制代码
执行PCPA文件分析,如下:
[root@Zeek ~]# zeek -r http.pcap file_analysis_01.zeek
 
在不指定日志目录的情况下会在该目录下生成响应的日志,如下图:

安装

今天我们又要来接触一种新的IDS
首先,准备好虚拟机(我使用的是Ubuntu20.04)
进入zeek官网(zeek-lts from security:zeek project)查看安装过程
选择适配的操作系统,点击 " 添加软件源并手动安装 "
在这里插入图片描述
对于 xUbuntu 20.04,请运行以下命令:
Keep in mind that the owner of the key may distribute updates, packages and repositories that your system will trust (more information).

echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_20.04/ /' | sudo tee /etc/apt/sources.list.d/security:zeek.list
curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_20.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null
sudo apt update
sudo apt install zeek-lts
  • 1
  • 2
  • 3
  • 4

在terminal依次输入以上命令即可

如果在安装过程中遇到无法解决的问题,我们还可以用线上编译平台解决燃眉之急


实验

Detection Requirement

  • check http sessions and if a source IP is related to three different user-agents or more
  • output “xxx.xxx.xxx.xxx is a proxy” where xxx.xxx.xxx.xxx is the source IP

You Need

  • a global variable to store the relationship of sourceIP to user-agent
  • write a event which can return you the http header user_agent information
  • you may need to study the datatype of Table, Set, String,
  • to_lower(str) return a lowercase version string of the original one
  • you may use print to output the alert

确定数据结构

首先我们需要确定存储IP和agent对应关系的数据结构
最简单最直接的想法:二维数组,第一维是IP,第二维存储Agent
在根据提示简单查看了Set,Table等数据类型后
我决定使用Set这种数据结构
但是当我开始申请变量的时候,遇到了一点麻烦
set[addr]表示:集合中存储的变量是addr类型,[]里面定义的是集合里面元素的类型
然而我们需要的是set有一个索引,索引是addr类型,set里面存储的是agent(string)
于是我又考虑使用Table类型
table [ type^+ ] of type的定义格式
启发了我结合Table和Set两种类型

global addrToAgent : table[addr] of set[string] = table();
  • 1

处理http头部信息

Zeek Event - HTTP

这里我们选择http_header事件
(实际上我觉得其他事件也是可以的,看下去你就会发现,我们只用到了connection这个参数)
可以看到提供的参数有

ParametersMeaning
C The connection.
Is_orig True if the header was sent by the originator of the TCP connection.
Original_name The name of the header (unaltered).
Name The name of the header (converted to all uppercase).
Value The value of the header.

在我寻找了一万年之后,终于发现了解决方法:
connection实际上是一个record(有一点类似c里面的结构体)
有以下两个操作符
在这里插入图片描述

至于connection里面有什么,我们可以去Zeek Script Index: base/init-bare.zeek: Types: connection看一看
然后我们找到了一个叫做http的成员
在这里,我们终于找到了和agent相关的信息
在这里插入图片描述
我们需要判断connection的http成员中是否存在agent内容
如果存在,则需要提取该agent记录(为了避免大小写的影响,我们需要用to_lower统一格式)
至于如何提取source IP
我们可以找到connection的id成员的orig_h内容

if (c$http?$user_agent) {
	local src_ip=c$id$orig_h;
	local user_agent=to_lower(c$http$user_agent);
}
  • 1
  • 2
  • 3
  • 4

接下来我们要把agent加入到集合中
注意需要分情况处理,因为table在第一次与set建立对应关系的时候,需要特别的初试化

if (src_ip in addrToAgent){
	add (addrToAgent[src_ip])[user_agent];  //set insert
}else{
	addrToAgent[src_ip]=set(user_agent);  //table insert
}
  • 1
  • 2
  • 3
  • 4
  • 5

输出答案

有了之前的经验,这一部分就很简单了
遍历所有ip地址(可以使用index in table的方法)
如果对应的集合大小大于等于3,则输出针对该ip的警报
在这里插入图片描述
需要强调一下addr的类型转换
Zeek Types - addr
在这里插入图片描述
我们可以使用第二种方法(类似c语言比较好理解)把ip地址转换为字符串输出

event zeek_done() {
	for (addr_ip in addrToAgent) {
	    if (|addrToAgent[addr_ip]| >= 3) {
	        print fmt("%s is a proxy", addr_ip);
	    }
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

完整代码

global addrToAgent : table[addr] of set[string] = table();

event http_header (c: connection, is_orig: bool, name: string, value: string){
	if(c$http?$user_agent){
		local src_ip=c$id$orig_h;
		local user_agent=to_lower(c$http$user_agent);
		if(src_ip in addrToAgent){
			add (addrToAgent[src_ip])[user_agent];
		}else{
			addrToAgent[src_ip]=set(user_agent);
		}
	}
}

event zeek_done() {
	for (addr_ip in addrToAgent) {
	    if (|addrToAgent[addr_ip]| >= 3) {
	        print fmt("%s is a proxy", addr_ip);
	    }
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

参考资料

Zeek语法(原网站)
Zeek语法(翻译)

 
posted @   bonelee  阅读(826)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2018-06-06 leetcode 501. Find Mode in Binary Search Tree
2018-06-06 DQN 处理 CartPole 问题——使用强化学习,本质上是训练MLP,预测每一个动作的得分
2018-06-06 fasttext和cnn的比较,使用keras imdb看效果——cnn要慢10倍。
2018-06-06 神经网络卷积层 要回计算output的维度 input 28 卷积是3x3 则output是26 但是channel是卷积核的数量
2018-06-06 keras中无法下载 https://s3.amazonaws.com/img-datasets/mnist.npz 解决方法
2018-06-06 python里混淆矩阵 左下角为漏报,右上角为误报
2018-06-06 ROC曲线是通过样本点分类概率画出的 例如某一个sample预测为1概率为0.6 预测为0概率0.4这样画出来,此外如果曲线不是特别平滑的话,那么很可能存在过拟合的情况
点击右上角即可分享
微信分享提示