(本篇首发于 https://www.freebuf.com/vuls/220646.html)

最近搭建各种蜜罐测试,这篇文章主要分享 HFish V0.4 使用过程中的一些心得。

部署

单节点部署

单点部署官方文档介绍已经很全面了,不过windows 家庭版docker版部署有点坑需要注意的。

systeminfo

家庭版是不能直接安装docker,需要安装docker tool box ,原理是开启vbox 的linux虚拟机,然后在linux虚拟机里面安装docker,所以,在启用docker容器的时候,如果指定 -p 127.0.0.1:22:22 物理机是无法访问蜜罐,只能把容器的端口映射到0.0.0.0的地址上,物理机才可以访问。

eg:

1
docker run -d -p 2222:22 -p 23:23 -p 9001:9001 -e USERNAME=god -e PASSWORD=123456 --name hfish imdevops/hfish:latest

win docker

然后进入linux虚拟机里面,查看虚拟机具体的ip地址

linux ifconfig

成功访问

win master

分布式部署

为了能尽可能全的收集全球攻击数据,这次计划采用分布式部署方式。使用vps供应商为 vultr ,IDC机房分布如下图

IDC机房列表

列表中有9个国家,ubuntu 系统最低配置每个月5美元,每个国家一台vps deploy 也没多少钱。这边有个注意点就是,在deploy时候,可以直接添加自己的ssh key,这样后面管理vps也很方便,因为我忘了我的ssh key 的密码了,就直接用账户密码管理。vps过多,管理起来挺麻烦的,这里我使用python3 的 paramiko 自动化一键配置,主要代码如下:

初始化服务器,并安装docker.io :

初始化

启动 docker 容器:

启动docker

官方分布式部署命令会少些端口,可以根据 config.ini 端口自行增删

这边还有一些需要注意的地方,国内访问国外服务器,可能会丢包,最好是在其中一台vps上面执行初始化脚本

运行完后,查看主节点,成功接收到数据

主节点面板

攻击数据分析

分布式蜜罐部署了几天后,接下来是对捕获的数据进行分析了,下面主要以 SSH 蜜罐攻击行为为例。各位大佬也可以从附件里下载数据库自行分析。往后如果有能力,会定期提供蜜罐捕获数给各位。

攻击字典统计

先来看下数据库 hfish_info 表结构及数据:

sqlite数据库表

可以看到数据库用 && 替换换行符,保存在数据库中,接下来可以写个统计攻击字典脚本。以下为关键部分示例代码:

1
2
3
4
5
6
def __init__(self):
self.hfish_db = './file/hfish.db'
self.hfish_split = '&&'
self.sql = sqlite3.connect(self.hfish_db)
#这里需要注意一下,测试时候发现,有些字符无法用utf-8解码,所以得用bytes
self.sql.text_factory = bytes

搜索 sqlite 数据库中所有 ssh 攻击的类型

搜索SSH类型

然后分割 && ,把用户名密码分割开,并输出到文本里面

输出到文本

打印一下用户名及密码频次

打印字典频次

取用户名及密码出现次数top10

1
2
3
4
5
# 按字典值反序排序,方法一
user = sorted(user_pwd_dic['user'].items(), key=lambda x:x[1],reverse=True)
# 按字典值反序排序,方法二
password = list(user_pwd_dic['pwd'].items())
password.sort(key=lambda x:x[1],reverse=True)

将结果打印

字典频次打印

其实字典具有地域性,可以根据攻击字典地域性,配置下蜜罐,由于默认蜜罐账户密码均为root,不在常见外网爆破攻击字典里,所以后续很多攻击都无法进行。

字典地域性分析

接下来分析一下各个国家的蜜罐收集到的字典差异,主要代码如下:

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
def RegionDic(self):
agent_sql = "select agent from hfish_info"
data = self.sql.execute(agent_sql).fetchall()
agents = []
for agent in list(set(data)):
agents.append(agent[0].decode('utf-8'))

agents_dic = {}
for agent in agents:
agents_dic[agent] = {}
data = self.sql.execute(dic_sql_tpl.format(agent)).fetchall()
for d in data:
if d[0] in agents_dic[agent].keys():
agents_dic[agent][d[0]] = agents_dic[agent][d[0]] + 1
else:
agents_dic[agent][d[0]] = 1

agents_dic[agent] = sorted(agents_dic[agent].items(), key=lambda x:x[1],reverse=True)

for agent in agents:
print(agent)
for i in range(5):
#这里不直接用decode utf-8 是因为捕获到的一些字符无法用utf-8解码,这个在上一节连接数据库里面有提到。
print("%s\t\t%s"%(str(agents_dic[agent][i][0]).replace("b'",'').replace("'",''), agents_dic[agent][i][1]))
print()

得到的结果如下:

字典地域性

使用 pyecharts 生成图表,

1
2
3
4
5
6
7
8
9
    bar = (Bar(options.InitOpts(width='1000px', height='500px'))
.add_xaxis(u_p_dic)
.add_yaxis(agent, u_p_count)
.set_global_opts(
title_opts=options.TitleOpts(title=("%s统计"%agent))
)
)
tab.add(bar, agent)
tab.render()

字典图表

这里墙裂推荐直接看 pyecharts 官方文档,特别详细全面,不要搜CSDN里面的博客,不忍吐槽某些博文。

因为收集时间不长,且子节点和主节点通信莫名中断,此结果不具有普遍性

这里只是简单提取攻击字典,并没有做更深入分析,各位可以通过后面附件下载,自行分析。

后面会根据字典的地域性,在部署蜜罐的时候,修改特定的标致

蜜罐检测

基于流量识别

这里以攻击者在内网,且蜜罐是以分布式部署情况作为示例,拓扑图如下:

内网拓扑图

使用 tcpdump dump数据包,wireshark 打开,可以看到子节点和主节点之间的通信以明文传输,且有明显的特征

wireshark

使用scapy 识别主节点和子节点的地址,主要代码如下

scapy

存在问题的代码在 /core/rpc/client/client.go

report bug

在内网渗透过程中,如果能发现部署的蜜罐,可以降低被发现可能性。

基于高交互蜜罐返回内容识别

hfish 高交互式蜜罐是根据特征字符回显,匹配的规则有限,比如常见的读取 passwd 通常使用 cat /etc/passwd ,在SSH规则里有相应的规则

ssh蜜罐配置

如果变形使用

1
cat /etc/passwd &

或者

1
tail /etc/passwd

在正常的 vps 里面也是可以正常读取到 passwd 的内容,

变形shell

变形shell2

但如果在蜜罐里面,则会显示异常,未修改配置的情况下是 test .

蜜罐回显

基于字符匹配的规则,总会有遗漏的地方,可以尝试变形的命令测试是否是hfish蜜罐。

高交互式蜜罐的配置文件在相应的 libs/蜜罐类型/ 下面,默认default 值在 libs/蜜罐类型/default.hf 。

蜜罐default配置

蜜罐default配置值

基于管理端口返回内容识别

这个很好理解了,如果返回包含管理页面特征字符就可以判断了,这里就直接给出 POC 了。

HFish_http

非授权接口获取信息

问题代码在 /view/url.go 文件中

api_code

可以发现,这里连身份鉴别都没作,当获取到主机点ip及端口后,直接请求uri,就可以获取蜜罐捕获的信息,从而分析蜜罐位置。

验证POC:

1
2
http://ip:port/api/v1/get/ip
http://ip:port/api/v1/get/fish_info

api_bp_1

api_bp_2

蜜罐攻击

非授权攻击

查看下主节点面板查询传输的数据包,用户认证是通过后,is_login 的值就是登陆用户,也就是说我们可以直接爆破这个用户,绕过登陆,直接设置后端各种参数,比如将报警参数置为空。

master_bp

对应的问题源码在 /view/login/view.go 里

问题源码

更新报警邮件的具体配置参数在 /view/setting/view.go 里面,禁止报警 poc 就不给出了,可自行查看对应参数。

报警参数

存储型XSS

这个漏洞是某位不愿提供ID大佬提醒的😏。

因为这漏洞是后台展示的原因,所以任何一个蜜罐都可以触发这个漏洞,这里以 ssh 蜜罐演示。

使用如下payload连接

1
ssh ^<script^>alert^(1234^)^<^/script^>@192.168.99.101 -p 2222

我使用的是window系统,需要用 ^ 转义特殊字符

ssh_payload

提交之后,返回 上钩列表 ,点击查看详情,可以看到成功执行xss。

xss

特性化配置

这里以攻击字典地域性特点及蜜罐检测中的交互式返回内容缺陷,特性化配置蜜罐。

根据地域,特性化蜜罐配置

将用户名、密码修改为统计的字典出现频率最高的值。

1
2
3
# 替换密码和用户名
set_user_tpl = 'sed -i "s/\\"account\\": \\"root\\"/\\"account\\": \\"{}\\"/g" %s'%ssh_conf_path
set_pwd_tpl = 'sed -i "s/\\"password\\": \\"root\\"/\\"password\\": \\"{}\\"/g" %s'%ssh_conf_path

高交互式蜜罐默认返回修改

咱们用一台Ubuntu 的vps测试一下,未知的命令返回:

unknow

也就是说,我们可以把默认返回修改为”command not found”的话,可以稍微改善下返回结果。

1
set_default_tpl = 'sed -i "s/test/: command not found/g" %s'%ssh_default_path

致谢

感谢三斤大佬解惑。

HFish 是一款非常不错的高交互式蜜罐,可扩展性好,可以帮忙点击一下 start,支持一下国产蜜罐。

HFish github

HFish document

附件

sqlite数据库

HFish数据库github地址

攻击用户名字典

攻击密码字典

地域字典统计图表