Maltrail 恶意流量检测工具调研

0x00 概述

Maltrail - Malicious traffic detection system,一款轻量级的恶意流量检测系统。

0x01 特性

  • 使用多个开源黑名单 (alientvault, autoshun, badips, sblam etc.)
  • 有大量静态特征可供识别 (domain names, URLs, IP addresses or User-Agent values)
  • 可检测未知威胁的启发式机制
  • 系统采用 流量 –> 传感器 <–> 服务器 <–> 客户端 的架构方式:
    • 传感器(Sensor):负责采集网络流量,更新恶意样本,并进行特征匹配。
    • 服务端(Server):提供 Web 界面以及收集网络中的恶意样本流量。
    • 客户端(Client):访问和检索恶意流量信息。
  • Web 报告页面

0x02 安装

OS:Kali Linux;

使用最小化安装,即 Sensor 和 Server 在同一台机器上;

1.安装依赖库,下载源码包

1
2
sudo apt-get install git python-pcapy
git clone https://github.com/stamparm/maltrail.git

2.启动 Sensor

第一次启动 Sensor 会自动下载各个 IOC 库;

1
2
cd maltrail
sudo python sensor.py

3.启动 Server

1
python server.py

4.测试

1
2
ping -c 1 136.161.101.53
cat /var/log/maltrail/$(date +"%Y-%m-%d").log

5.网页打开 http://127.0.0.1:8338 ,用户名:admin,密码:changeme!

0x03 检测方式

  1. 网络流量实时嗅探分析(默认行为,指定网卡进行数据包捕获)
  2. 离线 pcap 文件分析(指定 “-i” 参数,调用 pcapy 解析 pcap 文件)

0x04 特征源

  • IOC 列表(恶意/可疑)
    • 静态列表:从各种恶意软件报告、论文以及个人研究文档中获取的恶意样本(maltrail/trails/static/malware、maltrail/trails/static/suspicious)
    • 实时订阅源:从各种开源黑样本网站上下载的恶意样本,定期更新(update.py、maltrail/trails/feeds)
    • 用户自定义列表:可以按照指定格式扩展订阅源(maltrail/trails/custom)
  • 高级启发式机制,可以帮助发现未知的威胁。

0x05 核心模块

  • update.py:更新 trails 中的所有订阅源,并将结果保存到 /root/.maltrail/trails.csv,主要使用 update_trails 方法
  • httpd.py:HTTP 入侵检测模块
  • settings.py:控制 Sensor 的嗅探及检测行为
  • sensor.py:传感器主程序
  • server.py:服务端主程序
  • log.py:日志记录模块
  • trails 目录:存放所有与 IOC 有关的信息
  • html 目录:生成 Client Web 页面

0x06 实际应用

1.大规模扫描(Mass Scan)

类似 Shodan 和 ZoomEye 这样的组织会扫描整个网络,并通过他们的搜索引擎(给其他潜在的攻击者)免费提供所有结果(Maltrail 也可以利用这些信息,去溯源攻击者)。

Shodan

2.匿名 Tor 攻击(Anonymous attackers)

Maltrail 利用 Tor 出口节点的公共列表来发现隐藏在 Tor 匿名网络背后的潜在攻击者。

Tor attacker

3.服务攻击(Service attackers)

检测黑域名、黑 IP对组织范围内特定服务的访问情况。

RDP brute force

4.恶意软件(Malware)

如果组织内部受感染的计算机试图连接已知的 C&C 服务器,可以检出威胁并对识别出恶意软件家族(威胁信息)。

beebone malware

5.可疑域名(Suspicious domain lookups)

Maltrail 包含有已知经常参与可疑活动的 TLD 域的静态列表(特征匹配),和由恶意软件生成的 DGA 域名、Tor 域名(启发式检测机制)。

DGA

6.可疑 IPinfo(Suspicious ipinfo requests)

由于许多恶意软件使用某种 ipinfo 服务(例如 ipinfo.io)来查找受害者的互联网 IP 地址,因此,应该对这类请求进行密切监视。

ipinfo filter

7.可疑文件下载(Suspicious direct file downloads)

跟踪所有可疑的文件下载(例如.apk, .chm, .egg, .exe, .hta, .hwp, .ps1, .scr, .sct 文件扩展名),这可能会引发大量误报,但最终可能有助于重建感染链(由于合法的服务提供商,通常使用加密的HTTPS执行此类下载)。

Direct.exe download

8.可疑 HTTP 请求(Suspicious HTTP requests)

可以检出来自外部 Web 应用程序安全扫描程序的可疑请求(如 SQL、XSS、LFI 等)和内部用户对未知 Web 站点的恶意请求(启发式检测机制)。

Vulnerability scan

9.端口扫描(Port scanning)

如果多次的尝试连接大量的不同的 TCP 端口,Maltrail 将警告存在潜在的端口扫描行为(启发式检测机制),能够识别 nmap 等流行的扫描工具。

nmap scan

10.DNS 耗竭攻击(DNS resource exhaustion)

如果有大量的 DNS 递归查询(随机子域名),Maltrail 将警告存在潜在的DDoS攻击行为(启发式检测机制)。

DNS resource exhaustion

11.敏感信息泄露(Data leakage)

有些程序会表现出类似于恶意软件的行为,它们会将潜在的敏感数据发送到远程机器(尤其是基于移动设备的),Maltrail 会试图捕获这样的行为(启发式检测机制)。

Data leakage

12.误报处理(False positives)

与所有其他安全解决方案一样,Maltrail 容易出现”误报“,这时需要管理员投入一些额外的时间,并(以其他方式)检查“可疑 trail”是否确实存在恶意(通过实时关联其他开源情报)。

Google false positive

0x07 关注点

  • IOC 数据采集模块的提取和利用

    • 重点是对 IOC 的收集利用,要建立一套成熟的 OpenIOC 机制;
    • 对搜集到的 IOC 要同时记录其关联的攻击类型、组织信息(而不是仅仅像 IPsum 那样)。
  • 在 Web 平台显示恶意 IP 相关的 whois 信息及威胁信息

附:Maltrail heuristic 判定

1.域名有效长度超长(24个字符)- long domain (suspicious)

1
if len(parts[0]) > SUSPICIOUS_DOMAIN_LENGTH_THRESHOLD and '-' not in parts[0]:

2.SIP 每秒连接 DIP 次数过多(10次) - potential port scanning

1
2
3
4
5
6
7
if sec > connect_sec:
for key in _connect_src_dst:
if len(_connect_src_dst[key]) > PORT_SCANNING_THRESHOLD:
_src_ip, _dst_ip = key.split('~')
if not check_whitelisted(_src_ip):
for _ in _connect_src_details[key]:
log_event((sec, usec, _src_ip, _[2], _dst_ip, _[3], PROTO.TCP, TRAIL.IP, _src_ip, "potential port scanning", "(heuristic)"), packet)

3.TCP 流量命中以下规则 - sinkhole response (malware)、seized domain (suspicious)

1
2
3
4
5
6
7
8
9
if tcp_data.startswith("HTTP/"):
if any(_ in tcp_data[:tcp_data.find("\r\n\r\n")] for _ in ("X-Sinkhole:", "X-Malware-Sinkhole:", "Server: You got served", "Server: Apache 1.0/SinkSoft", "sinkdns.org")) or "\r\n\r\nsinkhole" in tcp_data:
log_event((sec, usec, src_ip, src_port, dst_ip, dst_port, PROTO.TCP, TRAIL.IP, src_ip, "sinkhole response (malware)", "(heuristic)"), packet)
else:
index = tcp_data.find("<title>")
if index >= 0:
title = tcp_data[index + len("<title>"):tcp_data.find("</title>", index)]
if all(_ in title.lower() for _ in ("this domain", "has been seized")):
log_event((sec, usec, src_ip, src_port, dst_ip, dst_port, PROTO.TCP, TRAIL.IP, title, "seized domain (suspicious)", "(heuristic)"), packet)

4.TCP “Content-Type” 中存在以下特征 - content type (suspicious)

1
SUSPICIOUS_CONTENT_TYPES = ("application/vnd.ms-htmlhelp", "application/x-bsh", "application/x-chm", "application/x-sh", "application/x-shellscript", "application/hta", "text/x-scriptlet", "text/x-sh", "text/x-shellscript")

5.HTTP 流量中存在以下特征 - potential proxy probe (suspicious)

1
2
3
4
5
if config.USE_HEURISTICS and dst_port == 80 and path.startswith("http://") and any(_ in path for _ in SUSPICIOUS_PROXY_PROBE_PRE_CONDITION) and not _check_domain_whitelisted(path.split('/')[2]):
trail = re.sub(r"(http://[^/]+/)(.+)", r"\g<1>(\g<2>)", path)
trail = re.sub(r"(http://)([^/(]+)", lambda match: "%s%s" % (match.group(1), match.group(2).split(':')[0].rstrip('.')), trail)

SUSPICIOUS_PROXY_PROBE_PRE_CONDITION = ("probe", "proxy", "echo", "check")

6.HTTP 流量中存在 UA 字段且不在下列白名单中 - user agent (suspicious)

1
WHITELIST_UA_KEYWORDS = ("AntiVir-NGUpd", "TMSPS", "AVGSETUP", "SDDS", "Sophos", "Symantec", "internal dummy connection", "Microsoft-CryptoAPI")

7.如果 HTTP 请求不在下列白名单且包含可疑预处理参数 - (suspicious)

1
2
3
WHITELIST_HTTP_REQUEST_PATHS = ("fql", "yql", "ads", "../images/", "../themes/", "../design/", "../scripts/", "../assets/", "../core/", "../js/", "/gwx/")

SUSPICIOUS_HTTP_REQUEST_PRE_CONDITION = ("?", "..", ".ht", "=", " ", "'")

8.如果文件后缀名在可疑列表中且下载路径不在白名单之中并且请求中不包含“=”且文件名长度小于10个字符 - direct %s download (suspicious)

1
2
3
SUSPICIOUS_DIRECT_DOWNLOAD_EXTENSIONS = set((".apk", ".chm", ".egg", ".exe", ".hta", ".hwp", ".pac", ".ps1", ".scr", ".sct"))

WHITELIST_DIRECT_DOWNLOAD_KEYWORDS = ("cgi", "/scripts/", "/_vti_bin/", "/bin/", "/pub/softpaq/", "/bios/", "/pc-axis/")

9.如果文件名在 webshell 列表中 - potential web shell (suspicious)

1
WEB_SHELLS 是一个set(),在程序运行时动态添加

10.如果文件名符合以下正则表达式 - (suspicious)

1
SUSPICIOUS_HTTP_PATH_REGEXES = (("non-existent page", r"defaultwebpage\.cgi"), ("potential web scan", r"inexistent_file_name\.inexistent|test-for-some-inexistent-file|long_inexistent_path|some-inexistent-website\.acu"))

11.以下内容全部为 DNS 协议启发式检测,源码注释表示引用自 此文章,但目前已经无法访问。与之相关的判定逻辑较为复杂,难以描述清楚,可以在 sensor.py 中以下面的关键字自行查看:

  1. potential dns exhaustion (suspicious)
  2. sinkholed by %s (malware)
  3. parked site (suspicious)
  4. excessive no such domain (suspicious)
  5. consonant threshold no such domain (suspicious)
  6. entropy threshold no such domain (suspicious)

参考资料:
README.md - Real-life cases