开源WAF与蜜罐的初尝试

1. 环境准备

写好的两篇博客忘了备份,结果自己捣鼓来捣鼓去不小心删除掉了….而且我没有保留到回收站的习惯,所以找不回来了,于是重新写吧…..

环境准备:

我的部署方式为 SaaS + docker ; 当然也可以用其他方式安装,可以查看官方链接使用相应部署方式

登录牧云主机管理助手(https://rivers.chaitin.cn/app/collie/home),绑定云主机后进入应用市场

绑定云主机

选择雷池社区版安装

选择雷池社区版

根据指引成功安装好WAF,后台web界面如下

雷池后台界面

安装HFish蜜罐,参考链接 https://hfish.net/#/2-1-docker

安装好后蜜罐web管理页面如下

蜜罐web管理页面

到这一步,SaaS + docker的WAF和蜜罐已经搭建好。

2. 如何让低交互蜜罐变得稍微高可信

由于HFish的开源版本中蜜罐大多数都是低交互的,所以当把IP发给朋友的时候,朋友看到80端口为tomcat的时候,说了句:“这一眼看上去就是蜜罐”。 于是蜜罐 “出师未捷身先死”…. 因此需要将低交互蜜罐做的逼真点。

2.1 蜜罐与WAF的配合

2.1.1 缩小蜜罐端口暴露面

HFish有环境模板,尽可能的减少了端口的暴露,使其更像真实环境

环境模板

随意选择一个模板,在其模板的基础上进行调整。关闭了一些TCP常用端口,比如22、23、445、3389等

然后修改高交互Mysql蜜罐的端口,设置默认3306的话,遇到有经验的攻击者会被识别出为蜜罐。

开放蜜罐端口

2.1.2 修改相应的特征

2.1.2.1 修改telnet协议特征或者使用高交互的telnet蜜罐

Hfish 中的低交互telnet蜜罐,默认监听在23端口。模拟的该协议默认无需验证,并且对各个命令的结果都做了响应的模板来做应答。在命令为空或者直接回车换行时,会响应default模板,该模板内容为test。因此可以利用这个特征进行该蜜罐在telnet服务上的检测如图所示。

telnet蜜罐

解决办法:

  1. 修改配置文件中的默认模版内容

  2. 更换为高交互telnet蜜罐

    切换高交互telnet蜜罐

2.1.2.2 修改明显的web特征

HFIsh在默认8080端口实现了一个WordPress登录页面,页面中由一个名为x.js的javascript文件用来记录尝试爆破的登录名密码。直接通过判断wordpress登录页是否存在x.js文件就可判断是否为蜜罐。

HFish蜜罐

x.js文件

解决办法:

  1. 修改x.js的命名和代码内容
  2. 关闭WordPress这个蜜罐,使用其他蜜罐

2.1.3 在部分web蜜罐上设置WAF防护

拿宝塔蜜罐和Zabbix监控蜜罐举例

现在宝塔蜜罐和Zabbix的蜜罐IP为 9224 和 9192

在雷池上设置对宝塔蜜罐和Zabbix蜜罐web页面的防护

宝塔蜜罐页面的防护设置:

宝塔蜜罐的防护

Zabbix蜜罐的防护设置:

Zabbix页面的防护设置

然后分别去访问相应的页面,如:https://<你的域名>:<雷池监听端口>

如果能正常访问,接着测试攻击发现被拦截,即表示两个蜜罐web站点已经被waf防护

被waf防护的蜜罐web页面

攻击测试发现被waf拦截

并且蜜罐也成功检测到攻击:

蜜罐告警

这样的话,攻击者在访问IP的特定web页面的时候发现有WAF,或许在思考自己是否踩中蜜罐的情况下有所迟疑。

另外

在雷池WAF的 防护配置-语义分析中,可以加将 “机器人检测”设置为仅观察,如果策略太严,FOFA、zoomeye、quake等空间测绘的IP节点也会被WAF拦截,这样的话,蜜罐端口就少了一个暴露方向。

机器人检测

3. 从蜜罐上获取高价值IP

思路如下

获取思路

3.1 对踩中蜜罐的攻击IP进行整理分类

注意:以下分类仅代表个人观点 ,如有异议,以你为准。

  1. 踩中蜜罐,并且IP的威胁情报为以下的,可直接在WAF侧进行拉黑封禁

    1
    2
    3
    4
    Scanner-扫描
    Botnet-僵尸网络
    uspicious-可疑
    Mobile-移动基站
  2. 踩中蜜罐,并且IP的威胁情报为以下的,为高价值IP,可尝试进行反制溯源,需不需要放入WAF黑名单视情况(傀儡机通常会进行大量扫描,也可以拉黑)。

    1
    2
    3
    4
    5
    6
    7
    Spam-垃圾邮件
    Zombie-傀儡机
    Exploit-漏洞利用
    IDC-IDC服务器
    Edu-教育
    BTtracker-BT服务器
    Backbone-骨干网

可通过蜜罐的API直接调用,提前需要在 平台管理 ->系统信息 处将 HFish社区云情报计划 勾上

勾选社区云情报计划

然后进入 平台管理 -> 系统配置 -> API配置选择已开放的API,根据使用示例中进行API调用

API配置

API的参数说明

用于在WAF侧进行拉黑封禁的IP,其获取脚本可用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
import json


url = "https://Server_IP/api/v1/attack/ip?api_key=YOUR_API_KEY"

payload = json.dumps(
{
"start_time": 0,
"end_time": 0,
"intranet": 0,
"threat_label": [
"Scanner",
"Botnet",
"uspicious",
"Mobile",
],
}
)
headers = {"Content-Type": "application/json"}

response = requests.request("POST", url, headers=headers, data=payload, verify=False)
print(response.text)

获取高价值可溯源反制IP,API脚本可用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import requests
import json


url = "https://Server_IP/api/v1/attack/ip?api_key=YOUR_API_KEY"

payload = json.dumps(
{
"start_time": 0,
"end_time": 0,
"intranet": 0,
"threat_label": [
"IDC",
"Spam",
"Zombie",
"Exploit",
"Edu",
"BTtracker",
"Backbone",
],
}
)
headers = {"Content-Type": "application/json"}

response = requests.request("POST", url, headers=headers, data=payload, verify=False)
print(response.text)

后续会在对应的脚本上进行添加功能。

3.2 将获取到的IP通过webhook形式发送到飞书

根据之前的脚本进行添加调整,基本的demo已经弄好,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import requests
import json
import re
import logging
import os
import warnings

# 忽略警告
warnings.filterwarnings("ignore")

# 获取当前脚本所在的目录
script_dir = os.path.dirname(os.path.realpath(__file__))

# 设置日志
logging.basicConfig(level=logging.INFO, format="%(message)s")
logger = logging.getLogger(__name__)

# 配置选项
RESULT_DIR = os.path.join(script_dir, "result")

# 检查并创建结果目录
if not os.path.exists(RESULT_DIR):
os.makedirs(RESULT_DIR)

BASE_URL = "https://蜜罐的API链接" # 此处为蜜罐的API
HEADERS = {"Content-Type": "application/json"}
THREAT_LABELS_ATTACK = [
"IDC",
"Spam",
"Zombie",
"Exploit",
"Edu",
"BTtracker",
"Backbone",
]
THREAT_LABELS_SCANNER = ["Scanner", "Botnet", "uspicious", "Mobile"]
IP_REGEX_PATTERN = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"


def fetch_data(payload):
try:
response = requests.post(BASE_URL, headers=HEADERS, data=payload, verify=False)
response.raise_for_status()
return response.text
except requests.exceptions.RequestException as e:
logger.error(f"Error fetching data: {e}")
return ""


def match_ips(data):
return re.findall(IP_REGEX_PATTERN, data)


def find_new_ips(old_ips, new_ips):
return list(set(new_ips) - set(old_ips))


def write_ips_to_file(file_path, ips):
with open(file_path, "w") as file:
file.write("\n".join(ips))


def send_notification(webhook_url, content):
headers = {"Content-Type": "application/json", "Charset": "UTF-8"}
message = {"msg_type": "text", "content": {"text": content}}
response = requests.post(url=webhook_url, headers=headers, data=json.dumps(message))


def main():
attack_webhook = (
"https://open.feishu.cn/open-apis/bot/v2/hook/xxxx" # 接收攻击告警机器人的 webhook
)
scan_webhook = (
"https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx" # 接收扫描告警机器人的 webhook
)

payload_attacker = json.dumps(
{
"start_time": 0,
"end_time": 0,
"intranet": 0,
"source": 0,
"threat_label": THREAT_LABELS_ATTACK,
}
)
payload_scanner = json.dumps(
{
"start_time": 0,
"end_time": 0,
"intranet": 0,
"source": 0,
"threat_label": THREAT_LABELS_SCANNER,
}
)

attack_data = fetch_data(payload_attacker)
scanner_data = fetch_data(payload_scanner)

attacker_ips = match_ips(attack_data)
scanner_ips = match_ips(scanner_data)

attacker_ips_path = os.path.join(RESULT_DIR, "attack_ips.txt")
scan_ips_path = os.path.join(RESULT_DIR, "scan_ips.txt")

previous_attacker_ips = []
previous_scan_ips = []

if os.path.exists(attacker_ips_path):
with open(attacker_ips_path, "r") as file:
previous_attacker_ips = file.read().splitlines()

if os.path.exists(scan_ips_path):
with open(scan_ips_path, "r") as file:
previous_scan_ips = file.read().splitlines()

new_attack_ips = find_new_ips(previous_attacker_ips, attacker_ips)
new_scan_ips = find_new_ips(previous_scan_ips, scanner_ips)

write_ips_to_file(attacker_ips_path, attacker_ips)

if new_attack_ips:
logger.info("有憨包踩蜜罐咯,尝试下溯源吧! hacking!")
logger.info("\n".join(new_attack_ips))
attack_content = "有憨包踩蜜罐咯,尝试下溯源吧! hacking!\n" + "\n".join(new_attack_ips)
else:
logger.info("还没新的憨包踩到蜜罐! 请静待有缘人")
attack_content = "还没新的憨包踩到蜜罐! 请静待有缘人\n"

write_ips_to_file(scan_ips_path, scanner_ips)

if new_scan_ips:
logger.info("快把这些扫描器、爬虫封了!")
logger.info("\n".join(new_scan_ips))
scan_content = "快把这些扫描器、爬虫封了!\n" + "\n".join(new_scan_ips)
else:
logger.info("目前没得需要封禁的IP")
scan_content = "目前没得需要封禁的IP\n"

send_notification(attack_webhook, attack_content)
send_notification(scan_webhook, scan_content)


if __name__ == "__main__":
main()

将代码放置你的云主机服务器上,使用crontab设置定时任务即可。

飞书机器人告警效果

飞书机器人实现效果

4. 参考

  1. http://tttang.com/archive/1832 [企业蜜罐建设实践]
  2. https://www.anquanke.com/post/id/227833#h2-12 [浅析开源蜜罐识别与全网测绘]
  3. https://waf-ce.chaitin.cn/ [长亭雷池WAF社区版]
  4. https://hfish.net/ [开源 HFish 蜜罐]
  5. https://rivers.chaitin.cn/app/collie/home [牧云主机管理助手]
  6. https://docs.rivers.chaitin.cn [长亭百川云平台]

开源WAF与蜜罐的初尝试
https://suiyideali.github.io/2023/08/29/开源WAF与蜜罐的初尝试/
作者
m0ch4z
发布于
2023年8月29日
更新于
2023年12月29日
许可协议