From e263f35fc62c2d6d38c851c75bd67f5d9eb6fb40 Mon Sep 17 00:00:00 2001 From: ConnorPatterson Date: Tue, 20 Jun 2017 12:41:17 -0600 Subject: [PATCH] Added Education Template for Creating Educational Redirect Pages Inside Static Folder gophish.go: /controllers is now imported from relevant local directory controllers/route.go: Added handling for /education URL, including handling AJAX POST requests templates/education.html: New template for creating, editing and managing HTML pages inside the static folder. Pages in this directory are served by the phishing server, and can be redirected to through landing pages templates/landing_pages.html: Added some information to the hover help icon by the redirect field, and a dropdown that suggests files from the static folder. /templates: Most of the other templates had the education page href added to their menus --- controllers/route.go | 138 +++++++++++++++++++++ gophish.go | 14 +-- templates/base.html | 2 + templates/campaign_results.html | 2 + templates/campaigns.html | 2 + templates/dashboard.html | 14 ++- templates/education.html | 205 ++++++++++++++++++++++++++++++++ templates/landing_pages.html | 30 ++++- templates/sending_profiles.html | 2 + templates/settings.html | 2 + templates/templates.html | 2 + templates/users.html | 2 + 12 files changed, 397 insertions(+), 18 deletions(-) create mode 100644 templates/education.html diff --git a/controllers/route.go b/controllers/route.go index 300c973f..fc33e85b 100644 --- a/controllers/route.go +++ b/controllers/route.go @@ -3,9 +3,12 @@ package controllers import ( "fmt" "html/template" + "io/ioutil" "log" "net/http" "os" + "path/filepath" + "strings" "github.com/gophish/gophish/auth" "github.com/gophish/gophish/config" @@ -29,6 +32,9 @@ func CreateAdminRouter() http.Handler { router.HandleFunc("/login", Login) router.HandleFunc("/logout", Use(Logout, mid.RequireLogin)) router.HandleFunc("/campaigns", Use(Campaigns, mid.RequireLogin)) + + router.HandleFunc("/education", Use(Education, mid.RequireLogin)) + router.HandleFunc("/campaigns/{id:[0-9]+}", Use(CampaignID, mid.RequireLogin)) router.HandleFunc("/templates", Use(Templates, mid.RequireLogin)) router.HandleFunc("/users", Use(Users, mid.RequireLogin)) @@ -196,7 +202,27 @@ func LandingPages(w http.ResponseWriter, r *http.Request) { Title string Flashes []interface{} Token string + List []string }{Title: "Landing Pages", User: ctx.Get(r, "user").(models.User), Token: csrf.Token(r)} + + pwd, _ := os.Getwd() + files, _ := filepath.Glob(pwd + "\\static\\endpoint\\[a-z,A-Z,0-9]*") + // + //files, _ := filepath.Glob("C:\\Users\\cpatterson\\Desktop\\gophish-master\\static\\endpoint/[a-z,A-Z,0-9]*") + + if len(files) > 0 { + + for index := range files { + + //Get the filename by splitting off the directory portion + parts := strings.Split(files[index], "\\") + string := parts[len(parts)-1] + + //Add this file to the list of files to be returned to the user + params.List = append(params.List, string) + } + } + getTemplate(w, "landing_pages").ExecuteTemplate(w, "base", params) } @@ -212,6 +238,118 @@ func SendingProfiles(w http.ResponseWriter, r *http.Request) { getTemplate(w, "sending_profiles").ExecuteTemplate(w, "base", params) } +// +//----------------------------------------------------------------------------- +//EDUCATION TEMPLATE FUNCTIONS +//----------------------------------------------------------------------------- +// + +// Proxy struct holds templates found by server +type Proxy struct { + Name string + Body string +} + +// Education handles the default path and template execution +func Education(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == "GET": + params := struct { + User models.User + Title string + Message string + Token string + List []Proxy + }{Title: "Education", User: ctx.Get(r, "user").(models.User), Token: csrf.Token(r)} + + //Return a list of every file in the endpoint directory to return to the user, excluding the .gitignore, using relevant path + pwd, _ := os.Getwd() + files, _ := filepath.Glob(pwd + "\\static\\endpoint\\[a-z,A-Z,0-9]*") + + if len(files) > 0 { + + //For each file found in the list + for index := range files { + + file, err := os.Stat(files[index]) + + if err != nil { + fmt.Println(err) + } + + //Find the last time the file was modified + modifiedtime := file.ModTime() + + //Get the filename by splitting off the directory portion + parts := strings.Split(files[index], "\\") + string := parts[len(parts)-1][:len(parts[len(parts)-1])-5] + + //Add this file to the list of files to be returned to the user + params.List = append(params.List, Proxy{string, modifiedtime.Format("Mon Jan _2 15:04:05 2006")}) + + } + } else { + + //If there weren't any education template files found, display this message to the user + params.Message = "No education templates created yet. Let's create one!" + + } + + //Execute the template and send it to the user + getTemplate(w, "education").ExecuteTemplate(w, "base", params) + + //If we are receiving AJAX POST REQUESTS + case r.Method == "POST": + + //PARSE THE FORM + r.ParseForm() + + //For the actions specified, save the form as a file on disk, return the file contents to be edited, or delete the file on disk + if r.Form.Get("action") == "SUBMIT" { + + pwd, _ := os.Getwd() + + err := ioutil.WriteFile(pwd+"\\static\\endpoint/"+r.Form.Get("name")+".html", []byte(r.Form.Get("body")), 0644) + if err != nil { + JSONResponse(w, "An error was encountered trying to save your file on server.", http.StatusOK) + } + + JSONResponse(w, "Education page saved successfully.", http.StatusOK) + + } else if r.Form.Get("action") == "EDIT" { + + pwd, _ := os.Getwd() + + b, err := ioutil.ReadFile(pwd + "\\static\\endpoint/" + r.Form.Get("name") + ".html") + if err != nil { + JSONResponse(w, "An error was encountered attempting to retrieve the saved file on server.", http.StatusOK) + } + + JSONResponse(w, string(b), http.StatusOK) + + } else if r.Form.Get("action") == "DELETE" { + + pwd, _ := os.Getwd() + + err := os.Remove(pwd + "\\static\\endpoint/" + r.Form.Get("name") + ".html") + + if err != nil { + JSONResponse(w, "An error was encountered trying to delete the file on the server.", http.StatusOK) + return + } + + JSONResponse(w, "File deleted successfully.", http.StatusOK) + + } + } +} + +// +//-------------------------------------------------------------------------------------- +//END OF EDUCATION TEMPLATE FUNCTIONS +//-------------------------------------------------------------------------------------- +// + // Settings handles the changing of settings func Settings(w http.ResponseWriter, r *http.Request) { switch { diff --git a/gophish.go b/gophish.go index 81e1e3ec..93073470 100644 --- a/gophish.go +++ b/gophish.go @@ -2,21 +2,16 @@ package main /* gophish - Open-Source Phishing Framework - The MIT License (MIT) - Copyright (c) 2013 Jordan Wright - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -33,12 +28,10 @@ import ( "os" "sync" - "gopkg.in/alecthomas/kingpin.v2" - + "./controllers" "github.com/NYTimes/gziphandler" "github.com/gophish/gophish/auth" "github.com/gophish/gophish/config" - "github.com/gophish/gophish/controllers" "github.com/gophish/gophish/models" "github.com/gophish/gophish/util" "github.com/gorilla/handlers" @@ -46,14 +39,9 @@ import ( var ( Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile) - - configPath = kingpin.Flag("config", "Location of config.json.").Default("./config.json").String() ) func main() { - // Parse the CLI flags and load the config - kingpin.Parse() - config.LoadConfig(*configPath) // Setup the global variables and settings err := models.Setup() if err != nil { diff --git a/templates/base.html b/templates/base.html index 130f7946..b22a7673 100644 --- a/templates/base.html +++ b/templates/base.html @@ -53,6 +53,8 @@
  • Landing Pages
  • +
  • Education +
  • Sending Profiles
  • Settings diff --git a/templates/campaign_results.html b/templates/campaign_results.html index 3f43cd32..cb9259e1 100644 --- a/templates/campaign_results.html +++ b/templates/campaign_results.html @@ -12,6 +12,8 @@
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles
  • diff --git a/templates/campaigns.html b/templates/campaigns.html index db253904..22b8381f 100644 --- a/templates/campaigns.html +++ b/templates/campaigns.html @@ -12,6 +12,8 @@
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles
  • diff --git a/templates/dashboard.html b/templates/dashboard.html index ce798175..8b9c3cc1 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -13,6 +13,8 @@
  • Landing Pages
  • +
  • Education +
  • Sending Profiles
  • Settings @@ -45,9 +47,15 @@

    Average Phishing Results

    -
    -
    -
      +
      +
      +
        +
      • + Successful Phishes +
      • +
      • + Unsuccessful Phishes +
    diff --git a/templates/education.html b/templates/education.html new file mode 100644 index 00000000..8b8ba0ca --- /dev/null +++ b/templates/education.html @@ -0,0 +1,205 @@ +{{define "body"}} + +
    +

    + Education +

    +
    +
    + +
    +   + + +{{if .List}} + +
    + + + + + + + + + +{{range $index,$article := .List }} + + + + + + + + + + + +{{end}} + +
    NameLast Modified Date
    {{- .Name -}}{{- .Body -}} + +
    + + + + +
    +
    +
    +
    Showing {{len .List}} of {{len .List}} entries
    + +{{end}} + +
    + +
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles
  • @@ -97,9 +99,33 @@
    - +
    - + + + + + + + {{if .List}} + + + + + + {{range $article := .List }} + + + + + {{end}} + + +
    diff --git a/templates/sending_profiles.html b/templates/sending_profiles.html index a3ddbf21..2265751b 100644 --- a/templates/sending_profiles.html +++ b/templates/sending_profiles.html @@ -12,6 +12,8 @@
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles
  • diff --git a/templates/settings.html b/templates/settings.html index 4a7b8560..10efc3ff 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -12,6 +12,8 @@
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles
  • diff --git a/templates/templates.html b/templates/templates.html index a2e82701..f93f7b23 100644 --- a/templates/templates.html +++ b/templates/templates.html @@ -12,6 +12,8 @@
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles
  • diff --git a/templates/users.html b/templates/users.html index e58c1796..87ffd4ab 100644 --- a/templates/users.html +++ b/templates/users.html @@ -12,6 +12,8 @@
  • Email Templates
  • Landing Pages +
  • +
  • Education
  • Sending Profiles