插件编写指南:插件交互式输出
当我们可以创建一个插件,并执行代码之后,面对一个很现实的问题是
我们如何为用户输出好看的,利于理解,利于后续操作的插件执行结果?本文我们就来讲解如何实现插件的输出
#
Yak 原生模块输出了解 Yakit 插件技术背景的同学可能非常清楚,Yak 原生插件依赖 webhook 与服务器进行通信。
为此我们在 yak 语言内部内置了一个 yakit
的库,在这个库中,我们可以便捷操作与用户的操作界面通信。
yakit.AutoInitYakit()
#
准备工作 如果用户需要启用与 yakit 通信的模块,则需要在脚本开头或者输出之前执行
yakit.AutoInitYakit()
。
这行代码会从环境变量中提取 Webhook 的实际端口,并且针对实际端口进行通信。在进行初始化之后,我们使用 yakit
中的一些接口,就可以实现把插件的执行结果返回到 yakit 中从而实现与用户的交互了!
Info/Warn/Error/Output
#
输出日志 最基础的输出,也就是我们最一开始实现 Hello World 插件的输出,就是使用这种形式。
yakit.AutoInitYakit()yakit.Info("Hello This is a info message")yakit.Warn("Warning!!! Warning: %v", now())yakit.Error("Error!? Impossible")
当我们把这段代码在插件中执行时,得到如下内容
#
Preview#
输出状态与统计数据我们在使用的过程中,经常需要告诉用户 "输出结果" 的状态或者某个指标的数据,例如:
- 我们发现了多少漏洞
- 我们发出了多少请求
- 关键步骤运行了多长时间
- ...
这些状态其实往往应该被单独展示,而不应该放在日志中,为了支持这种常见的情况,我们可以使用 yakit.StatusCard(title: string, value: any)
支持。
#
Preview#
输出进度条同上,我们在调用 yakit.AutoInitYakit()
之后,将可以使用进度条功能,为你的插件增加一个 "进度"。
#
单进度条作为最简单的情况,进度条的输入只应该是一个 "百分比",为了支持这种情况,我们实现了一个
yakit.SetProgress(percent: float)
函数
yakit.AutoInitYakit()
yakit.SetProgress(0.1)sleep(1)yakit.SetProgress(0.4)sleep(1)yakit.SetProgress(0.8)
将会在界面生成一个进度条,实现进度条的展示!
#
Preview#
多进度条当然如果上述的内容中,单个进度条无法满足用户需求,你希望我们可以展示多个进度条,进度条之间可以互相关联。
那么我们可以使用 yakit.SetProgressEx(id: string, percent: float)
来按照 ID 创建多个进度条
我们使用如下案例来展示
yakit.AutoInitYakit()
go func{ percent = 0.1 for { yakit.SetProgressEx("test1", percent) time.sleep(0.3) percent+=0.1 }
}
yakit.SetProgress(0.1)sleep(1)yakit.SetProgress(0.4)sleep(1)yakit.SetProgress(0.8)sleep(1)yakit.SetProgress(0.9)
我们在原来代码的基础上,增加了 goroutine,来创建另一个进度条,给新的进度条命名为 test1
。
观察代码,我们预期两个进度条可以同步进行
#
Preview#
输出表格虽然上面输出了一些内容,但是实际上并不够,如果我们需要不断输出一些结果
例如批量扫描的结果,或者猜测某一个 KEY 的结果,我们经常需要一个表格作为输出。
这个时候,我们应该如何编写几个表格呢?
yakit.AutoInitYakit()
yakit.EnableTable("tablename", ["key", "key2"])
data = make(map[string]var)data["key"] = 123data["key2"] = 2222yakit.Output(yakit.TableData("tablename", data))
data = make(map[string]var)data["key"] = "测试KEY1"data["key2"] = "测试KEY2"yakit.Output(yakit.TableData("tablename", data))
同样的,我们通过 AutoInitYakit()
来初始化,成功之后我们启用 yakit.EnableTable(tableName: string, fields: string[])
在界面上创建一个新的表格。
创建了表格则可以通过 yakit.Output(yakit.TableData(tableName: string, data: map[string]var))
来输出表格具体内容了。
我们可以通过 make(map[string]var)
来创建一个表格需要输出的数据。更简单的,我们可以通过一些小重构,让这个 API 变得更好用!
yakit.EnableTable("tablename", ["key", "key2"])
outputData = def(key, key2){ data = make(map[string]var) data["key"] = key data["key2"] = key2 yakit.Output(yakit.TableData("tablename", data))}
outputData("测试数据1", "jkoasdkoasdf")outputData("测试数据2", "jkoasdkoasasdfaadf")outputData("测试数据3", "jkrewgiogq423421oasdkoasdf")outputData("测试数据4", "jkoasdfasdgaasdkoasdf")outputData("测试数据5", "jkoasdkoasdasdfhadfhsdrff")outputData("测试数据1", "j132562345235dcf*&TY^koasdkoasdf")
#
Preview#
输出图详情可参考 Yakit API
#
MITM 插件的输出MITM 插件的输出接口其实并不多,同时接口相对更容易一些
#
输出到 MITM 插件操作台yakit_output(data: any)
:仅输出到操作台yakit_save(data: any)
:输出到操作台,同时保存一份到插件输入,可以在数据库中找保存的数据
以上接口非常容易理解,我们可以创建一个插件,分别输出两个内容试试看~
#
Preview#
输出状态卡片在原生 yak 模块中,状态卡片是一个非常受欢迎的小组件;
我们同样的也在 MITM 中实现了该组件的功能。
yakit_status(title: string, value: any)
直接调用这个函数,将会自动生成一个状态卡片,用于展示各种动态的指标。
#
Preview:编写一个建议的流量记述插件!我们使用一个更贴近场景的案例来告诉大家这个功能的用法:流量统计。
我们可以做一个简单的计数器,在 MITM 的 Hook 函数内实现统计方法,每一个数据包都会被记数,从而实现一个指标来记录流经我们劫持平台的数据包到底有多少。
实际生效的代码仅仅三行,我们为插件创建一个计数器,具体如何使用呢?我们可以查看如下内容