HFish源码浅析(二)

上一篇文章只说到了配置文件和读取配置文件相关的函数与结构,以及Run函数,但是并没有对Run函数进行深入,本篇文章就通过Run函数和项目目录作为切入点,对HFish的源码再作进一步的分析。

补充一下

这里补充一下上一篇遗漏的,我们通过查看项目的go.mod文件内容,可以得知该项目使用的是Gin框架,众所周知Gin框架在易用性、可扩展性、开源社区方面都表现得非常优秀。

module HFish

go 1.12

require (
	github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
	github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
	github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
	github.com/gin-gonic/gin v1.4.0
	github.com/gliderlabs/ssh v0.2.2
	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869
	github.com/mattn/go-sqlite3 v1.11.0
	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
)

这里针对这些依赖项做一下解读:

  1. go-shlex 使用了两个不同开发者的shlex库,它的功能主要是解析和操作命令行参数;
  2. mahonia 是一个字符编码转换库,例如用来处理不同字符编码gbk或者utf-8之间的转换;
  3. ssh 这个库估计是SSH蜜罐使用到的,用于创建SSH服务器或客户端应用程序;
  4. go-strftime 此依赖库主要用来格式化时间字符串;
  5. go-sqlite3 是用来与 SQLite3 数据库进行交互;
  6. quotedprintable.v3 这个依赖库的主要功能也是关于编解码的操作;
  7. gomail.v2 这个应该是专门用来发送电子邮件,主要使用在邮箱的蜜罐功能上面

将调试控制台信息作为切入点分析HFish

程序开始运行的时候通过调试控制台可以看到下面的信息
在这里插入图片描述

HFish的路由以及相对应的处理函数

上图显示的路由方法,是Gin框架的核心,通过项目的源码可以查看到对应的控制器(Controller)和处理器(Handler)HFish是使用Gin框架来编写GETPOST 等方法的控制器函数,来处理HTTP响应。
接下来通过调试窗口查看栈调用信息:
在这里插入图片描述

下面是程序的流程图(针对Run函数做了一定的简略操作)
在这里插入图片描述

/get/fish/list路由为例,找到处理它们这些路由方法的上一层函数LoadUrl
在这里插入图片描述

下面是LoadUrl函数的源码:

func LoadUrl(r *gin.Engine) {
	// 判断是否为 RPC 客户端
	if is.Rpc() {
		/* RPC 客户端 */

		// API 接口
		// WEB 上报蜜罐信息
		apiStatus := conf.Get("api", "status")

		// 判断 API 是否启用
		if apiStatus == "1" {
			r.Use(cors())

			webUrl := conf.Get("api", "web_url")
			deepUrl := conf.Get("api", "deep_url")

			r.POST(webUrl, api.ReportWeb)
			r.POST(deepUrl, api.ReportDeepWeb)
		}
	} else {
		/* RPC 服务端 */
		// 登录
		r.GET("/login", login.Html)
		r.POST("/login", login.Login)
		r.GET("/logout", login.Logout)

		// 仪表盘
		r.GET("/", login.Jump, dashboard.Html)
		r.GET("/dashboard", login.Jump, dashboard.Html)
		r.GET("/get/dashboard/data", login.Jump, dashboard.GetFishData)

		// 蜜罐列表
		r.GET("/fish", login.Jump, fish.Html)
		r.GET("/get/fish/list", login.Jump, fish.GetFishList)
		r.GET("/get/fish/info", login.Jump, fish.GetFishInfo)
		r.GET("/get/fish/typeList", login.Jump, fish.GetFishTypeInfo)
		r.POST("/post/fish/del", login.Jump, fish.PostFishDel)

		// 分布式集群
		r.GET("/colony", login.Jump, colony.Html)
		r.GET("/get/colony/list", login.Jump, colony.GetColony)

		// 邮件群发
		r.GET("/mail", login.Jump, mail.Html)
		r.POST("/post/mail/sendEmail", login.Jump, mail.SendEmailToUsers)

		// 设置
		r.GET("/setting", login.Jump, setting.Html)
		r.GET("/get/setting/info", login.Jump, setting.GetSettingInfo)
		r.POST("/post/setting/update", login.Jump, setting.UpdateEmailInfo)
		r.POST("/post/setting/updateAlertMail", login.Jump, setting.UpdateAlertMail)
		r.POST("/post/setting/checkSetting", login.Jump, setting.UpdateStatusSetting)

		// API 接口
		// WEB 上报蜜罐信息
		apiStatus := conf.Get("api", "status")

		// 判断 API 是否启用
		if apiStatus == "1" {
			r.Use(cors())

			webUrl := conf.Get("api", "web_url")
			deepUrl := conf.Get("api", "deep_url")

			r.POST(webUrl, api.ReportWeb)
			r.POST(deepUrl, api.ReportDeepWeb)

			r.GET("/api/v1/get/ip", api.GetIpList)
		}
	}
}

上一篇文章我们说过配置文件config.ini,它最开头的一个节点是rpc,这部分内容是集群部署才会使用到它。下面是该文件的部分摘抄内容

[rpc]
status = 0                                   # 模式 0关闭 1服务端 2客户端
addr = 127.0.0.1:7879                        # RPC 服务端地址 or 客户端地址
name = Server                                # 状态1 服务端 名称 状态2 客户端 名称

Run函数读取配置文件最关键的地方是在判断当前程序是否为Rpc服务端或者客户端,下面代码截取自Run函数


func Run() {
	//省略代码...
	
	// 启动 RPC
	rpcStatus := conf.Get("rpc", "status")

	// 判断 RPC 是否开启 1 RPC 服务端 2 RPC 客户端
	if rpcStatus == "1" {
		// 服务端监听地址
		rpcAddr := conf.Get("rpc", "addr")
		go server.Start(rpcAddr)
	} else if rpcStatus == "2" {
		// 客户端连接服务端
		// 阻止进程,不启动 admin

		rpcName := conf.Get("rpc", "name")

		for {
			// 这样写 提高IO读写性能
			go client.Start(rpcName, ftpStatus, telnetStatus, "0", mysqlStatus, redisStatus, sshStatus, webStatus, deepStatus)

			time.Sleep(time.Duration(1) * time.Minute)
		}
	}
		// 启动 admin 管理后台
	adminAddr := conf.Get("admin", "addr")

	serverAdmin := &http.Server{
		Addr:         adminAddr,
		Handler:      RunAdmin(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	serverAdmin.ListenAndServe()
}

判断配置文件关于rpc节点的status字段,确认当前程序属于服务端节点还是客户端节点。
若值为“1”,即表示当前程序为rpc服务端,

若值为“2”,即表示当前程序为rpc客户端,下面程序会进入一个for死循环,直至用户主动结束(按下ctrl+c)或者程序发生错误。

HFish项目目录解读

通过项目目录来解读HFish各个文件以及相关函数所对应的关系,下图是HFish_v0.2完整的项目文件夹
在这里插入图片描述

admin文件夹

admin文件夹开始,从上到下逐个分析,admin文件夹下都是管理后台的模板文件
在这里插入图片描述
HFish/view/url.go文件下的LoadUrl函数有对应的模板渲染,下面摘取LoadUrl函数的源代码:

func LoadUrl(r *gin.Engine) {
	// 判断是否为 RPC 客户端
	if is.Rpc() {
		/* RPC 客户端 */

		// API 接口
		// WEB 上报蜜罐信息
		apiStatus := conf.Get("api", "status")

		// 判断 API 是否启用
		if apiStatus == "1" {
			r.Use(cors())

			webUrl := conf.Get("api", "web_url")
			deepUrl := conf.Get("api", "deep_url")

			r.POST(webUrl, api.ReportWeb)
			r.POST(deepUrl, api.ReportDeepWeb)
		}
	} else {
		/* RPC 服务端 */
		// 登录
		r.GET("/login", login.Html)//对应上图的管理后台登陆页面
		r.POST("/login", login.Login)
		r.GET("/logout", login.Logout)

		// 仪表盘
		r.GET("/", login.Jump, dashboard.Html)
		r.GET("/dashboard", login.Jump, dashboard.Html)//管理后台仪表板,需要登陆验证
		r.GET("/get/dashboard/data", login.Jump, dashboard.GetFishData)

		// 蜜罐列表
		r.GET("/fish", login.Jump, fish.Html)//上钩列表
		r.GET("/get/fish/list", login.Jump, fish.GetFishList)
		r.GET("/get/fish/info", login.Jump, fish.GetFishInfo)
		r.GET("/get/fish/typeList", login.Jump, fish.GetFishTypeInfo)
		r.POST("/post/fish/del", login.Jump, fish.PostFishDel)

		// 分布式集群
		r.GET("/colony", login.Jump, colony.Html)//分布式集群页面
		r.GET("/get/colony/list", login.Jump, colony.GetColony)

		// 邮件群发
		r.GET("/mail", login.Jump, mail.Html)//群发邮件通知页面
		r.POST("/post/mail/sendEmail", login.Jump, mail.SendEmailToUsers)

		// 设置
		r.GET("/setting", login.Jump, setting.Html)//管理后台系统设置页面
		r.GET("/get/setting/info", login.Jump, setting.GetSettingInfo)
		r.POST("/post/setting/update", login.Jump, setting.UpdateEmailInfo)
		r.POST("/post/setting/updateAlertMail", login.Jump, setting.UpdateAlertMail)
		r.POST("/post/setting/checkSetting", login.Jump, setting.UpdateStatusSetting)

		// API 接口
		// WEB 上报蜜罐信息
		apiStatus := conf.Get("api", "status")

		// 判断 API 是否启用
		if apiStatus == "1" {
			r.Use(cors())

			webUrl := conf.Get("api", "web_url")
			deepUrl := conf.Get("api", "deep_url")

			r.POST(webUrl, api.ReportWeb)
			r.POST(deepUrl, api.ReportDeepWeb)

			r.GET("/api/v1/get/ip", api.GetIpList)
		}
	}
}

core文件夹

和它的名称一样,是HFish这个项目的核心文件,它的下面又分几个子文件夹,分别是:

  • dbUtil子文件夹
  • exec子文件夹
  • protocol子文件夹
  • report子文件夹
  • rpc子文件夹

dbUtil

主要是操作数据库的一些常用工具函数,CURD这些代码,为了避免本文内容篇幅过长,具体的代码细节这里就不展开了
在这里插入图片描述

exec

这个文件夹里面就一个Execute函数,是一个调用系统名命令的接口函数,在这里主要是实现程序的help参数
在这里插入图片描述

protocol

该子文件夹里包含的文件是HFish各个蜜罐实现的关键。
关于它的httpx子文件夹在这个版本并没有使用到,所以就不对它最具体的展开了
在这里插入图片描述

FTP蜜罐

展开ftp这个文件夹,它对应的信息一下子就很清晰了
在这里插入图片描述
这里可以确定HFishftp蜜罐使用了一个叫graval的第三方库,很明显它用于构建FTP服务器。
下面调试一下它,关于攻击者触发蜜罐执行上报的流程
在这里插入图片描述
这里FTP的蜜罐和SSH不一样,它的上报函数是下面这两个,主要是通过判断是否为RPC节点然后去确定使用哪一个:

在这里插入图片描述

在网站的后台管理也有上报的记录
在这里插入图片描述

mysql蜜罐

通过调试设置断点,确定这里是mysql蜜罐的关键上报函数
在这里插入图片描述
这里对应蜜罐管理后台的返回信息
在这里插入图片描述
它大致的程序执行流程图是这样子的
在这里插入图片描述

Redis蜜罐

本地尝试连接redis服务的时候会触发HFish的蜜罐上报函数,它触发的调用顺序如下图所示
在这里插入图片描述
Redis蜜罐的程序执行流程和MySql类似,这里就不过多赘述了。

SSH蜜罐

再以SSH蜜罐为例,golandkun_-hfish\core\protocol\ssh\ssh.go文件下的Start函数设置调试断点,通过调试可以看到,我输入的密码是123
在这里插入图片描述

从上面的代码可以得知,不管用户(这里角色应该是攻击者更恰当些)输入的是什么,程序都会将其记录日志,并且上报到蜜罐后台report.ReportSSH函数就是实现上报功能的模块。
打开Admin后台查看上报情况
在这里插入图片描述

telnet蜜罐

telnet蜜罐的执行流程图如下所示
在这里插入图片描述

report

这个文件夹里的函数都是涉及到蜜罐的上报处理的,不管是集群部署还是单机部署都会调用到这里的上报函数
在这里插入图片描述

rpc

这部分是集群部署的时候会使用到,分为客户端和服务端的代码。
在这里插入图片描述

error文件夹

这里是使用gin框架的特点来返回错误信息
在这里插入图片描述
一般是在用户查看管理后台仪表盘时执行统计信息
在这里插入图片描述

static文件夹

和大部分的web框架一样,这个staticgin框架中主要是用于存放静态文件的,如下图所示,例如 JavaScriptCSS、图像等。
在这里插入图片描述

utils文件夹

顾名思义工具类,封装的都是项目里面常用的函数
例如打印控制台信息的字体颜色

在这里插入图片描述

又例如下面这个获取攻击者ip的函数
在这里插入图片描述

还有下面这些记录日志的操作,等等
在这里插入图片描述

view文件夹

攻击者测试WEB蜜罐后台登陆功能的时候
在这里插入图片描述
会触发ReportWeb函数

在这里插入图片描述
这个文件夹主要是处理蜜罐管理后台各个页面的数据信息
在这里插入图片描述

web文件夹

该文件夹主要用来存放WEB蜜罐和WEBDEEP蜜罐的静态资源文件
在这里插入图片描述

HFish的模板渲染

Gin框架中使用LoadHTMLGlob对多个模板进行统一渲染,HFish中自然也使用到了。如下图:
在这里插入图片描述
上面代码分别是下面这三个函数使用到了模板渲染:

func RunWeb(template string, index string, static string, url string) http.Handler;
func RunDeep(template string, index string, static string, url string) http.Handler;
func RunAdmin() http.Handler;

未完待续…

下一篇文章打算针对HFish最后开源的版本HFish0.6来展开,通过版本的更新也能从中学习到蜜罐开发的思路。

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
HFish是一款基于Golang开发的跨平台蜜罐平台,为了企业安全做出了精心的打造。 蜜罐技术本质上是一种对攻击方进行欺骗的技术,通过布置一些作为诱饵的主机、网络服务或者信息,诱使攻击方对它们实施攻击,从而可以对攻击行为进行捕获和分析,了解攻击方所使用的工具与方法,推测攻击意图和动机,能够让防御方清晰地了解他们所面对的安全威胁,并通过技术和管理手段来增强实际系统的安全防护能力。 蜜罐好比是情报收集系统。蜜罐好像是故意让人攻击的目标,引诱黑客前来攻击。所以攻击者入侵后,你就可以知道他是如何得逞的,随时了解针对服务器发动的最新的攻击和漏洞。还可以通过窃听黑客之间的联系,收集黑客所用的种种工具,并且掌握他们的社交网络。 HFish承载了全新的架构理念和实现方案,增加了蜜罐在威胁情报和诱捕溯领域的能力,帮助企业在红蓝对抗中自动化的对攻击者进行画像和追溯。 此外,我们将重点关注企业安全场景,从攻击、处置、溯角度提升产品联通能力。从威胁分析、告警策略与办公管理多方面出发,为企业用户提供更高的可用性与可拓展性。 我们深知企业环境特殊性,为了便于快速部署和敏捷管理,HFish提供了一系列方便运维和管理的技术,包括:一键闪电部署、应用模板批量管理、节点服务动态调整等特性……
要编译ceph码生成二进制文件,可以按照以下步骤进行操作: 1. 首先,从GitHub上下载ceph码。使用命令`git clone --recursive https://github.com/ceph/ceph.git`,加上`--recursive`参数以下载码中的子模块。 2. 进入码根目录,并选择要编译的版本。使用`git tag`命令显示已有的版本,并使用`git checkout <版本号>`切换到要编译的版本。 3. 下载依赖项并开始编译。运行以下命令: - `./install-deps.sh`:下载编译所需的依赖项。 - `./autogen.sh`:生成配置脚本。 - `./configure`:配置编译选项。 - `make`:编译码。如果遇到编译器错误,可以使用`-j`参数指定处理器数量,例如`make -j2`。 4. 编译完成后,可以使用`make install`命令将生成的二进制文件和配置文件安装到本地系统。也可以手动将二进制文件放置在`/usr/bin`目录下,将库文件放置在`/usr/lib`目录下,配置文件存放在`/etc/ceph`目录中。 需要注意的是,如果从GitHub上获取ceph码进行编译,可能会遇到一些问题。例如,报告找不到特定文件的错误,可能是因为没有获取到所有的子模块代码。在使用`git clone`命令时,需要添加`--recursive`参数以获取完整的码及其子模块。 此外,还可能遇到编译过程中出现内存不足的问题,导致编译失败。如果出现类似"internal compiler error: Killed (program cc1plus)"的错误提示,可能是因为内存不足。可以尝试增加系统的可用内存或者优化编译环境来解决这个问题。 综上所述,要编译ceph码生成二进制文件,可以按照上述步骤进行操作,同时注意处理可能遇到的子模块获取和内存不足的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [编译ceph码](https://blog.csdn.net/mary0712/article/details/117467780)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值