最近搭建各种蜜罐测试,这篇文章主要分享 HFish V0.4 使用过程中的一些心得。
单点部署官方文档介绍已经很全面了,不过windows 家庭中文版docker部署有点坑需要注意的。
家庭版不能直接安装docker,需要安装docker tool box ,原理是开启vm vbox 的linux虚拟机,然后在linux虚拟机里面安装docker,所以,在启用docker容器的时候,如果指定 -p 127.0.0.1:22:22 物理机是无法访问蜜罐,只能把容器的端口映射到0.0.0.0的地址上,物理机才可以访问。
eg:
docker run -d -p 2222:22 -p 23:23 -p 9001:9001 -e USERNAME=god -e PASSWORD=123456 --name hfish imdevops/hfish:latest
然后进入linux虚拟机里面,查看虚拟机具体的ip地址
成功访问
为了能尽可能全的收集全球攻击数据,这次计划采用分布式部署方式。使用vps供应商为 vultr ,IDC机房分布如下图
列表中有9个国家,ubuntu 系统最低配置每个月5美元,每个国家一台vps deploy 也没多少钱。这边有个注意点就是,在deploy时候,可以直接添加自己的ssh key,这样后面管理vps也很方便,因为我忘了我的ssh key 的密码了,就直接用账户密码管理。vps过多,管理起来挺麻烦的,这里我使用python3 的 paramiko 自动化一键配置,主要代码如下:
初始化服务器,并安装docker.io :
启动 docker 容器:
官方分布式部署命令会少些端口,可以根据 config.ini 端口自行增删。
这边还有一些需要注意的地方,国内访问国外服务器,可能会丢包,最好是在其中一台vps上面执行初始化脚本
运行完后,查看主节点,成功接收到数据。
分布式蜜罐部署了几天后,接下来是对捕获的数据进行分析了,下面主要以 SSH 蜜罐攻击行为为例。各位大佬也可以从附件里下载数据库自行分析。往后如果有能力,会定期提供蜜罐捕获数据给各位。
先来看下数据库 hfish_info 表结构及数据:
可以看到数据库用 && 替换换行符,保存在数据库中,接下来可以写个统计攻击字典脚本。以下为关键部分示例代码:
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 攻击的类型
然后分割 && ,把用户名密码分割开,并输出到文本里面
打印一下用户名及密码频次
取用户名及密码出现次数top10
# 按字典值反序排序,方法一 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,不在常见外网爆破攻击字典里,所以后续很多攻击都无法捕捉。
接下来分析一下各个国家的蜜罐收集到的字典差异,主要代码如下:
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 生成图表,
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 打开,可以看到子节点和主节点之间的通信以明文传输,且有明显的特征
使用scapy 识别主节点和子节点的地址,主要代码如下
存在问题的代码在 /core/rpc/client/client.go
在内网渗透过程中,如果能发现部署的蜜罐,可以降低被发现可能性。
hfish 高交互式蜜罐是根据特征字符回显,匹配的规则有限,比如常见的读取 passwd 通常使用 cat /etc/passwd ,在SSH规则里有相应的规则
如果变形使用
cat /etc/passwd &
或者
tail /etc/passwd
在正常的 vps 里面也是可以正常读取到 passwd 的内容,
但如果在蜜罐里面,则会显示异常,未修改配置的情况下是 test .
基于字符匹配的规则,总会有遗漏的地方,可以尝试变形的命令测试是否是hfish蜜罐。
高交互式蜜罐的配置文件在相应的 /libs/蜜罐类型/ 下面,默认default 值在 /libs/蜜罐类型/default.hf 。
这个很好理解了,如果返回包含管理页面特征字符就可以判断了,这里就直接给出 POC 了。
问题代码在 /view/url.go 文件中
可以发现,这里连身份鉴别都没作,当获取到主机点ip及端口后,直接请求uri,就可以获取蜜罐捕获的信息,从而分析蜜罐位置。
验证POC:
http://ip:port/api/v1/get/iphttp://ip:port/api/v1/get/fish_info
查看下主节点面板查询传输的数据包,用户认证是通过后,is_login 的值就是登陆用户,也就是说我们可以直接爆破这个用户,绕过登陆,直接设置后端各种参数,比如将报警参数置为空。
对应的问题源码在 /view/login/view.go 里
更新报警邮件的具体配置参数在 /view/setting/view.go 里面,禁止报警 poc 就不给出了,可自行查看对应参数。
这个漏洞是某位不愿提供ID大佬提醒的(手动滑稽)。
因为这漏洞是后台展示的原因,所以任何一个蜜罐都可以触发这个漏洞,这里以 ssh 蜜罐演示。
使用如下payload连接
ssh ^<script^>alert^(1234^)^<^/script^>@192.168.99.101 -p 2222
我使用的是window系统,需要用 ^ 转义特殊字符
提交之后,返回 上钩列表 ,点击查看详情,可以看到成功执行xss。
这里以攻击字典地域性特点及蜜罐检测中的交互式返回内容缺陷,特性化配置蜜罐。
将用户名、密码修改为统计的字典出现频率最高的值。
# 替换密码和用户名set_user_tpl = 'sed -i "s/\\"account\\": \\"root\\"/\\"account\\": \\"{}\\"/g" %s'%ssh_conf_pathset_pwd_tpl = 'sed -i "s/\\"password\\": \\"root\\"/\\"password\\": \\"{}\\"/g" %s'%ssh_conf_path
咱们用一台Ubuntu 的vps测试一下,未知的命令返回:
也就是说,我们可以把默认返回修改为”command not found”的话,可以稍微改善下返回结果。
set_default_tpl = 'sed -i "s/test/: command not found/g" %s'%ssh_default_path
感谢三斤大佬解惑。
HFish 是一款非常不错的高交互式蜜罐,可扩展性好,可以帮忙点击一下 start,支持一下国产蜜罐。
*本文原创作者:cyker,本文属FreeBuf原创奖励计划,未经许可禁止转载