HaloUI:给poc添加图形化
命令行有时候不够直观
如何快速给自己的poc添加图形化
GUI的库太麻烦了,索性基于gin写了一个ui库
成品展示
运行程序自动打开浏览器
运行过程截图:
运行完成会有提示(同时会有弹窗)
分为两部分输出,fmt.Print输出命令行调试信息,ui库可以向web页面输出结果
How to use
1.导入库
就两文件,自己复制一下就行了
之后导入gin
go get -u github.com/gin-gonic/gin
或者直接运行
go get "github.com/Aixve-c/HaloUI"
2.设置常规信息
HaloUI.SetTitle("xx漏洞poc") //设置标题
HaloUI.SetReadme("ip为目标,端口默认为80") //设置说明文档
3.设置输入
AddInput入参依次为
-
参数名
-
ui中显示的名字
-
是否必填
HaloUI.AddInput("url", "URL", true) //必填的输入框
HaloUI.AddInput("port", "端口", false) //非必填的输入框
4.设置入口函数
HaloUI.SetFunc(mypoc)
5.启动
HaloUI.Run()
入口函数
注意入口函数必须接收一个[]string参数
例如:func mypoc(HaloPars []string){xxxxxxxxx}
获取用户输入
可以通过传入的参数获取用户输入的字符串(所有输入都是字符串)
例如:fmt.Println("url:"+HaloPars[0])
追加一行输出
1.1秒同步一次结果
HaloUI.AddOutput("开搞")
完成
入参为弹窗提示词
注意:在报错或者执行成功后都应该加上此函数
HaloUI.Finsh("完成")
代码
HaloUI.go和Config.go
ps:记得单独放进同一个文件夹HaloUI
HaloUI.go
package HaloUI
import (
"fmt"
"github.com/gin-gonic/gin"
"io/ioutil"
"log"
"os/exec"
"runtime"
"time"
)
var Pars []string
var WebInput []string
var RunFunc func(input []string)
func Run() {
HaloUI_output = "" //还原输出
gin.DefaultWriter = ioutil.Discard //关闭gin的日志
ginServer := gin.Default()
ginServer.POST("/Run", gin_post)
ginServer.GET("/Run", gin_get)
//打印主界面UI
ginServer.GET("/", func(c *gin.Context) {
c.Header("content-type", "text/html; charset=utf-8")
c.String(200, HaloUI_index())
})
port, err := GetFreePort() //获取空闲端口
if err != nil { //错误处理
log.Print(err)
}
WebAddress := fmt.Sprintf("127.0.0.1:%d", port) //定义监听端口
fmt.Println("UI界面: ", "http://"+WebAddress)
go OpenBrowser("http://" + WebAddress)
err = ginServer.Run(WebAddress) //启动HaloUI的http服务(基于gin)
if err != nil { //错误处理
log.Print(err)
}
}
// 一键运行的入口
func gin_post(c *gin.Context) {
WebInput = []string{}
fmt.Println("[+]Run...")
NoFinsh()
for i := 0; i < len(Pars); i++ {
WebInput = append(WebInput, c.PostForm(Pars[i]))
fmt.Println("[+]入参", Pars[i], " : ", WebInput[i])
}
go RunFunc(WebInput)
c.Header("content-type", "text/html; charset=utf-8")
c.String(200, HaloUI_run())
}
// 更新页面的入口
func gin_get(c *gin.Context) {
c.Header("content-type", "text/html; charset=utf-8")
c.String(200, HaloUI_run())
}
// 打开指定url
func OpenBrowser(url string) error {
var cmd string
var args []string
time.Sleep(1 * time.Second) // 睡眠4秒
switch runtime.GOOS {
case "windows":
cmd = "cmd"
args = []string{"/c", "start"}
case "darwin":
cmd = "open"
default: // "linux", "freebsd", "openbsd", "netbsd"
cmd = "xdg-open"
}
args = append(args, url)
return exec.Command(cmd, args...).Start()
}
Config.go
package HaloUI
import (
"html"
"net"
"strings"
)
var HaloUI_readme = "│--│┌─┐│·┌─┐│--│·<br>├─┤├─┤│·│·││--││<br>│--││·│└─└─┘└─┘│<br>适用于白帽子的极简的UI库,基于gin开发<br>可以快速为golang编写的poc添加ui界面<br>[+] Halo UI [+] by Aixve<br><br>//设置标题 <br>HaloUI.SetTitle(\"XX漏洞POC\") <br><br>//设置帮助文档<br>HaloUI.SetReadme(\"url为目标,cmd为执行的命令\")<br><br>//增加输入框<br>//入参为:传递的参数(不得重复)、UI中显示的名字、是否必填<br>HaloUI.AddInput(\"url\",\"URL\",true)<br>//可以借此获取用户输入<br><br>//设置要运行的函数<br>HaloUI.SetFunc(mypoc)<br><br>//启动HaloUI<br>HaloUI.Run()<br><br>//结束单次运行并弹窗提示<br>HaloUI.Finsh(\"完成\")"
var HaloUI_output string
var isFinsh bool
var FinshMsg string
var ui_html = `<!DOCTYPE html>
<body>
<h2>xxx漏洞poc</h2><!-- HaloUI标题 -->
<!-- HaloUI输入开始 -->
<form action="/Run" method="post">
<!-- HaloUI用户输入 -->
<input type="submit" value="一键运行">
</form> <!-- HaloUI输入结束 -->
<br>
<div class="dark-code-box">
此处展示结果<!-- readme -->
</div>
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HaloUI</title> <!-- WebTitle -->
<style>
.dark-code-box {
background-color: #333; /* 深色背景 */
color: #fff; /* 白色文字 */
padding: 10px; /* 内边距 */
border-radius: 5px; /* 边框圆角 */
overflow-x: auto; /* 如果代码太长,允许水平滚动 */
font-family: monospace; /* 使用等宽字体 */
font-size: 25px; /* 设置字体大小 */
}
body {
font-family: 'Courier New', Courier, monospace; /* 设置等宽字体 */
font-size: 25px; /* 设置字体大小 */
margin: 0 auto; /* 上下边距为0,左右自动调整以居中(但这里需要配合容器宽度) */
padding: 20px; /* 内边距 */
max-width: 800px; /* 设置最大宽度,以便内容在较宽的屏幕上也能居中 */
margin-left: auto;
margin-right: auto; /* 显式设置左右自动边距以确保居中 */
}
form input[type="text"] {
height: 25px; /* 设置输入框的高度 */
padding: 0 10px; /* 设置输入框的内边距 */
margin-bottom: 15px; /* 与下一个输入框之间保持间距 */
}
</style>
</head>
</html>
`
func AddInput(Params string, ui_name string, not_null bool) { //添加用户输入
Pars = append(Pars, Params)
if not_null == true { //设置不能为空的输入框
ui_html = strings.Replace(ui_html, "<!-- HaloUI用户输入 -->", ui_name+": <input type=\"text\" name=\""+Params+"\" required> <br>"+"<!-- HaloUI用户输入 -->", -1)
} else { //设置可以为空的输入框
ui_html = strings.Replace(ui_html, "<!-- HaloUI用户输入 -->", ui_name+": <input type=\"text\" name=\""+Params+"\" > <br>"+"<!-- HaloUI用户输入 -->", -1)
}
}
func GetFreePort() (int, error) { //获取空闲的端口
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0, err
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, err
}
defer l.Close()
return l.Addr().(*net.TCPAddr).Port, nil
}
func AddOutput(Output string) {
HaloUI_output += html.EscapeString(Output) + "<br>"
}
func HaloUI_index() string {
//填充readme
return strings.Replace(ui_html, "此处展示结果<!-- readme --> ", HaloUI_readme+"<!-- readme --> ", -1)
}
func HaloUI_run() string {
//填充结果
a := strings.Replace(ui_html, "此处展示结果<!-- readme --> ", HaloUI_output+"<!-- readme --> ", -1)
userin := ""
for i := 0; i < len(Pars); i++ {
userin += Pars[i] + " = " + WebInput[i] + "<br>"
}
//显示输入、持续更新页面
if !isFinsh {
a = strings.Replace(a, "HaloUI输入开始 -->", " 注释", 1)
a = strings.Replace(a, "<!-- HaloUI用户输入 -->", " 注释", 1)
a = strings.Replace(a, "<!-- HaloUI输入结束 -->", "HaloUI输入结束 -->"+userin, 1)
a += "<script>window.onload = function() {setTimeout(function() {window.location.href = 'Run';}, 1100);};</script><!-- HaloUI每1.1秒更新1次 -->"
} else {
a += "<script>alert('" + html.EscapeString(FinshMsg) + "')</script>"
a = strings.Replace(a, "<!-- HaloUI输入结束 -->", userin, 1)
}
return a
}
func SetFunc(MyFunc func(input []string)) {
RunFunc = MyFunc
}
func SetTitle(title string) {
//设置标题
ui_html = strings.Replace(ui_html, "<title>HaloUI</title> <!-- WebTitle --> ", "<title>"+title+"</title> <!-- WebTitle --> ", -1)
ui_html = strings.Replace(ui_html, "<h2>xxx漏洞poc</h2><!-- HaloUI标题 -->", "<h2>"+title+"</h2><!-- HaloUI标题 -->", -1)
}
func SetReadme(Readme string) {
//设置readme,在HaloUIHtml中会具体赋值,因为两个get和post的代码框是复用的
Readme = strings.Replace(Readme, "\n", "<br>", -1)
HaloUI_readme = html.EscapeString(Readme)
HaloUI_readme = strings.Replace(Readme, "<br>", "<br>", -1)
}
func Finsh(msg string) {
isFinsh = true
FinshMsg = msg
HaloUI_output = strings.Replace(HaloUI_output, "[*]运行中...<br>", "[+]Yes运行完成!<br>", 1)
}
func NoFinsh() {
isFinsh = false
HaloUI_output = "[*]运行中...<br>"
}

命令行有时候不够直观,快速给自己的poc添加图形化
浙公网安备 33010602011771号