其实大部分都是文档翻译的(也许是全部)
https://docs.zeek.org/en/current/examples/scripting/index.html
扩展名为.zeek
默认目录:share/zeek
放在share/zeek/site
的不会在升级时被覆盖或者修改
zeek生成的事件可以参考:base/bif/event.bif.zeek
*.bif
是zeek的内建函数文件,也是生成在线文档的基础。
zeek脚本语法参考:https://docs.zeek.org/en/current/script-reference/index.html
框架参考:https://docs.zeek.org/en/current/frameworks/index.html
定义脚本使用的库
@load base/frameworks/files
@load base/frameworks/notice
@load frameworks/files/hash-all-files
确保zeek加载了文件框架,通知框架和hash所有文件的脚本
定义命名空间
module TeamCymruMalwareHashRegistry;
解释自定义变量,作为脚本命令空间的一部分
export {
redef enum Notice::Type += {
## The hash value of a file transferred over HTTP matched in the
## malware hash registry.
Match
};
## File types to attempt matching against the Malware Hash Registry.
option match_file_types = /application\/x-dosexec/ |
/application\/vnd.ms-cab-compressed/ |
/application\/pdf/ |
/application\/x-shockwave-flash/ |
/application\/x-java-applet/ |
/application\/jar/ |
/video\/mp4/;
## The Match notice has a sub message with a URL where you can get more
## information about the file. The %s will be replaced with the SHA-1
## hash of the file.
option match_sub_url = "https://www.virustotal.com/en/search/?query=%s";
## The malware hash registry runs each malware sample through several
## A/V engines. Team Cymru returns a percentage to indicate how
## many A/V engines flagged the sample as malicious. This threshold
## allows you to require a minimum detection rate.
option notice_threshold = 10;
}
重新定义了一个可枚举的常量,描述了将使用通知框架生成的通知类型。
定义一些常量用作阈值等
函数
function do_mhr_lookup(hash: string, fi: Notice::FileInfo)
{
local hash_domain = fmt("%s.malware.hash.cymru.com", hash);
when ( local MHR_result = lookup_hostname_txt(hash_domain) )
{
# Data is returned as "<dateFirstDetected> <detectionRate>"
local MHR_answer = split_string1(MHR_result, / /);
if ( |MHR_answer| == 2 )
{
local mhr_detect_rate = to_count(MHR_answer[1]);
if ( mhr_detect_rate >= notice_threshold )
{
local mhr_first_detected = double_to_time(to_double(MHR_answer[0]));
local readable_first_detected = strftime("%Y-%m-%d %H:%M:%S", mhr_first_detected);
local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected);
local virustotal_url = fmt(match_sub_url, hash);
# We don't have the full fa_file record here in order to
# avoid the "when" statement cloning it (expensive!).
local n: Notice::Info = Notice::Info($note=Match, $msg=message, $sub=virustotal_url);
Notice::populate_file_info2(fi, n);
NOTICE(n);
}
}
}
}
针对特定事件执行的内容
event file_hash(f: fa_file, kind: string, hash: string)
{
if ( kind == "sha1" && f?$info && f$info?$mime_type &&
match_file_types in f$info$mime_type )
do_mhr_lookup(hash, Notice::create_file_info(f));
file_hash事件处理程序,传递file,哈希算法的种类,哈希值
zeek执行异步操作不影响性能时使用when语句块
zeek的脚本语言是事件驱动的,zeek的核心功能是把事件放入有序的事件队列中,允许事件处理程序在先到先服务的基础上处理事件。
当zeek检测到发起的dns请求时,触发dns_request事件,并传递数据
声明变量的两种形式:
scope name: type
scope name = expression
local a:int
local a=10
当脚本使用module
关键字提供了命名空间时,必须更加注意全局声明以确保预期的效果。
在带有命名空间的脚本中声明全局变量时,两种可能的结果:
export
块中声明了全局变量,可以通过<module name>::<variable name>
来对其他脚本生效const
关键字,使用&redef
的话,只能在解析时设置或者更改常量,以后(运行时)不可更改。redef
常量不能在事件处理程序中更改。
举例:
base/protocols/http/main.zeek
文件中:
module HTTP;
export {
## This setting changes if passwords used in Basic-Auth are captured or
## not.
const default_capture_password = F &redef;
}
如果想打开这个default_capture_password
设置,需要在启动zeek之前在site/local.zeek
添加如下行:
@load base/protocols/http
redef HTTP::default_capture_password = T;
函数function
内定义的local
的局部变量,在函数结束后会被销毁。同理事件event
中的变量在事件结束后会被销毁。
Data Type | Description | zh-cn |
---|---|---|
int | 64 bit signed integer | 64位有符号整数 |
count | 64 bit unsigned integer | 64位无符号整数 |
double | double precision floating precision | 双精度浮点 |
bool | boolean (T/F) | 布尔类型 |
addr | IP address, IPv4 and IPv6 | IP地址 |
port | transport layer port | 传输层端口 |
subnet | CIDR subnet mask | CIDR格式子网掩码 |
time | absolute epoch time | 绝对时间 |
interval | a time interval | 时间间隔 |
pattern | regular expression | 正则表达式 |
储存相同数据类型的唯一元素。
可用的方法:add
,delete
,for ( i in ssl_ports )
for循环无法保证集合遍历的顺序
类似python字典,键-值映射,值不唯一,键唯一
local ssl_services: table[string] of port;
ssl_services = table(["SSH"] = 22/tcp, ["HTTPS"] = 443/tcp);
类似python列表,有序
local v1: vector of count;
local v2 = vector(1, 2, 3, 4);
记录数据类型:结合type关键词和record可以生成复合类型
type Service: record {
name: string;
ports: set[port];
rfc: count;
};
简单的使用更具描述性的名称定义数据结构:type string_array: table[count] of string;
https://docs.zeek.org/en/current/examples/scripting/index.html#custom-logging
https://docs.zeek.org/en/current/examples/scripting/index.html#raising-notices