插件编写指南:插件交互式输出
当我们可以创建一个插件,并执行代码之后,面对一个很现实的问题是
我们如何为用户输出好看的,利于理解,利于后续操作的插件执行结果?本文我们就来讲解如何实现插件的输出
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"] = 123
data["key2"] = 2222
yakit.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 函数内实现统计方法,每一个数据包都会被记数,从而实现一个指标来记录流经我们劫持平台的数据包到底有多少。
实际生效的代码仅仅三行,我们为插件创建一个计数器,具体如何使用呢?我们可以查看如下内容