Inserted web templates, readme, license. Updated logo and favicon

This commit is contained in:
2019-07-06 15:55:06 +08:00
parent d606cc129b
commit 31796678ae
54 changed files with 1329 additions and 51 deletions

View File

@@ -7,7 +7,6 @@ import (
"encoding/json"
"github.com/jinzhu/gorm"
"math/rand"
"time"
"golang.org/x/crypto/bcrypt"
)
@@ -104,7 +103,7 @@ func (tapit *Tapit) register(w http.ResponseWriter, r *http.Request) {
}
// checks if secret code is correct
if userJson.SecretCode != tapit.globalSettings.secretRegistrationCode {
if userJson.SecretCode != tapit.globalSettings.SecretRegistrationCode {
messageOutput := NotificationJson{
Text: "Your secret code is incorrect. Please try again.",
ResultType: "failure",
@@ -280,7 +279,6 @@ func (tapit *Tapit) deleteCookie() http.Cookie {
func generateToken() string {
var tokenResult strings.Builder
rand.Seed(time.Now().UnixNano())
var r int
tokenCharset := "abcdefghijklmnopqrstuvwxyz0123456789"
for i:=0; i<16; i++ {
@@ -291,7 +289,7 @@ func generateToken() string {
}
func (tapit *Tapit) hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), tapit.globalSettings.bcryptCost)
bytes, err := bcrypt.GenerateFromPassword([]byte(password), tapit.globalSettings.BcryptCost)
return string(bytes), err
}

View File

@@ -54,6 +54,7 @@ type Job struct {
gorm.Model
CampaignId uint
CurrentStatus string // enum Failed, Queued, Sent, Delivered, Not Started
WebStatus string // enum Not Visited, xx visits
TimeSent time.Time
ProviderTag string
AccSID string
@@ -63,14 +64,21 @@ type Job struct {
ToNum string
ResultStr string
MessageSid string
WebRoute string
FullUrl string
Visits []Visit
}
type JobJson struct {
Id uint `json:"id"`
CurrentStatus string `json:"currentStatus"`
WebStatus string `json:"webStatus"`
TimeSent time.Time `json:"timeSent"`
FromNum string `json:"fromNum"`
ToNum string `json:"toNum"`
WebRoute string `json:"webRoute"`
FullUrl string `json:"fullUrl"`
Visits []VisitJson `json:"visitJson"`
}
type TwilioMessageJson struct {
@@ -187,14 +195,24 @@ func (tapit *Tapit) createCampaign(w http.ResponseWriter, r *http.Request) {
newCampaign.WebTemplateId = newCampaignJson.WebTemplateId
newCampaign.ProviderTag = newCampaignJson.ProviderTag
// save campaign first
tapit.db.NewRecord(&newCampaign)
tapit.db.Create(&newCampaign)
if newCampaign.ID == 0 {
notifyPopup(w, r, "failure", "Failed to create campaign", nil)
return
}
// update records
for _, record := range newRecords {
var newJob Job
newJob.CurrentStatus = "Not Started"
newJob.WebStatus = "Not Visited"
newJob.ProviderTag = newCampaign.ProviderTag
newJob.AccSID = newAccSID
newJob.AuthToken = newAuthToken
newJob.FromNum = newCampaign.FromNumber
newJob.WebRoute = tapit.generateWebTemplateRoute()
newJob.FullUrl = tapit.globalSettings.WebTemplatePrefix + newJob.WebRoute
// interpreting records
var newBodyText string
@@ -204,20 +222,17 @@ func (tapit *Tapit) createCampaign(w http.ResponseWriter, r *http.Request) {
newBodyText = strings.Replace(newBodyText, "{lastName}", record.LastName, -1)
newBodyText = strings.Replace(newBodyText, "{alias}", record.Alias, -1)
newBodyText = strings.Replace(newBodyText, "{phoneNumber}", record.PhoneNumber, -1)
newBodyText = strings.Replace(newBodyText, "{url}", newJob.FullUrl, -1)
newJob.BodyText = newBodyText
// saving it
newCampaign.Jobs = append(newCampaign.Jobs, newJob)
// update campaign
tapit.db.Save(&newCampaign)
}
// update database
tapit.db.NewRecord(&newCampaign)
tapit.db.Create(&newCampaign)
if newCampaign.ID == 0 {
notifyPopup(w, r, "failure", "Failed to create campaign", nil)
return
}
newCampaignJson.Id = newCampaign.ID
newCampaignJson.CreateDate = newCampaign.CreatedAt
newCampaignJson.Size = newCampaign.Size
@@ -301,7 +316,11 @@ func campaignToJson(campaign Campaign) CampaignJson {
// iterating jobs
for _, job := range campaign.Jobs {
var currJson JobJson
currJson.Id = job.ID
currJson.CurrentStatus = job.CurrentStatus
currJson.WebStatus = job.WebStatus
currJson.WebRoute = job.WebRoute
currJson.FullUrl = job.FullUrl
currJson.TimeSent = job.TimeSent
currJson.FromNum = job.FromNum
currJson.ToNum = job.ToNum
@@ -425,7 +444,7 @@ func (tapit *Tapit) workerCampaign(campaign Campaign) {
var wg sync.WaitGroup
jobChan = make(chan JobComms, 1)
for i:=0; i<tapit.globalSettings.threadsPerCampaign; i++ {
for i:=0; i<tapit.globalSettings.ThreadsPerCampaign; i++ {
wg.Add(1)
go tapit.workerJob(jobChan, &wg)
}
@@ -436,7 +455,7 @@ func (tapit *Tapit) workerCampaign(campaign Campaign) {
if campaignComms.Campaign.ID == campaign.ID {
if campaignComms.Action == "stop" {
// kill all
for i:=0; i<tapit.globalSettings.threadsPerCampaign; i++ {
for i:=0; i<tapit.globalSettings.ThreadsPerCampaign; i++ {
var stopComms JobComms
stopComms.Action = "stop"
jobChan <- stopComms
@@ -468,7 +487,7 @@ func (tapit *Tapit) workerCampaign(campaign Campaign) {
}
}
}
for i:=0; i<tapit.globalSettings.threadsPerCampaign; i++ {
for i:=0; i<tapit.globalSettings.ThreadsPerCampaign; i++ {
var stopComms JobComms
stopComms.Action = "stop"
jobChan <- stopComms
@@ -512,6 +531,7 @@ func (tapit *Tapit) workerJob(jobChan chan JobComms, wg *sync.WaitGroup) {
} else if twilioResult.Status == "delivered" {
currentJob.Job.MessageSid = twilioResult.Sid
currentJob.Job.CurrentStatus = "Delivered"
currentJob.Job.TimeSent = time.Now()
} else {
currentJob.Job.CurrentStatus = "Failed"
}

View File

@@ -0,0 +1,114 @@
package main
import (
"github.com/jinzhu/gorm"
"strings"
"net/http"
"io/ioutil"
"encoding/json"
)
// GlobalSettings contains basic common settings across the app
type GlobalSettings struct {
gorm.Model
SecretRegistrationCode string
ThreadsPerCampaign int
BcryptCost int
MaxRequestRetries int
WaitBeforeRetry int
WebTemplatePrefix string
WebTemplateRoute string
}
type GlobalSettingsJson struct {
SecretRegistrationCode string `json:"secretRegistrationCode"`
ThreadsPerCampaign int `json:"threadsPerCampaign"`
BcryptCost int `json:"bcryptCost"`
MaxRequestRetries int `json:"maxRequestRetries"`
WaitBeforeRetry int `json:"waitBeforeRetry"`
WebTemplatePrefix string `json:"webTemplatePrefix"`
WebTemplateRoute string `json:"webTemplateRoute"`
}
func (tapit *Tapit) handleGlobalSettings(w http.ResponseWriter, r *http.Request) {
if strings.ToUpper(r.Method) == "PUT" {
tapit.updateGlobalSettings(w, r)
} else if strings.ToUpper(r.Method) == "GET" {
tapit.getGlobalSettings(w,r)
} else {
http.Error(w, "HTTP method not implemented", 400)
return
}
}
func (tapit *Tapit) updateGlobalSettings(w http.ResponseWriter, r *http.Request) {
requestBody, err:= ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
var globalSettingsJson GlobalSettingsJson
var globalSettings GlobalSettings
err = tapit.db.Last(&globalSettings).Error
if err != nil {
http.Error(w, "Bad request", 400)
return
}
err = json.Unmarshal(requestBody, &globalSettingsJson)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
if globalSettingsJson.SecretRegistrationCode != "" && globalSettingsJson.ThreadsPerCampaign != 0 && globalSettingsJson.BcryptCost != 0 && globalSettingsJson.WebTemplatePrefix != "" && globalSettingsJson.WebTemplateRoute != "" {
globalSettings.SecretRegistrationCode = globalSettingsJson.SecretRegistrationCode
globalSettings.ThreadsPerCampaign = globalSettingsJson.ThreadsPerCampaign
globalSettings.BcryptCost = globalSettingsJson.BcryptCost
globalSettings.MaxRequestRetries = globalSettingsJson.MaxRequestRetries
globalSettings.WaitBeforeRetry = globalSettingsJson.WaitBeforeRetry
globalSettings.WebTemplatePrefix = globalSettingsJson.WebTemplatePrefix
globalSettings.WebTemplateRoute = globalSettingsJson.WebTemplateRoute
err = tapit.db.Save(&globalSettings).Error
if err != nil {
notifyPopup(w, r, "failure", "Failed to update global settings", nil)
return
} else {
tapit.globalSettings = globalSettings
notifyPopup(w, r, "success", "Successfully updated global settings", globalSettingsJson)
return
}
} else {
notifyPopup(w, r, "failure", "Failed to update global settings", nil)
return
}
}
func (tapit *Tapit) getGlobalSettings(w http.ResponseWriter, r *http.Request) {
var globalSettingsJson GlobalSettingsJson
var globalSettings GlobalSettings
err := tapit.db.Last(&globalSettings).Error
if err == nil {
globalSettingsJson.SecretRegistrationCode = globalSettings.SecretRegistrationCode
globalSettingsJson.ThreadsPerCampaign = globalSettings.ThreadsPerCampaign
globalSettingsJson.BcryptCost = globalSettings.BcryptCost
globalSettingsJson.MaxRequestRetries = globalSettings.MaxRequestRetries
globalSettingsJson.WaitBeforeRetry = globalSettings.WaitBeforeRetry
globalSettingsJson.WebTemplatePrefix = globalSettings.WebTemplatePrefix
globalSettingsJson.WebTemplateRoute = globalSettings.WebTemplateRoute
jsonResults, err := json.Marshal(globalSettingsJson)
if err != nil {
http.Error(w, err.Error(), 500)
return
} else {
w.Header().Set("Content-Type", "application/json")
w.Write(jsonResults)
return
}
} else {
http.Error(w, "Bad request", 400)
return
}
}

View File

@@ -8,23 +8,18 @@ import (
"io/ioutil"
"net/http"
"os"
"time"
"path/filepath"
"math/rand"
)
// Tapit is the general struct with shared objects
type Tapit struct {
db *gorm.DB
globalSettings GlobalSettings
campaignChan chan CampaignComms
}
type GlobalSettings struct {
secretRegistrationCode string
threadsPerCampaign int
bcryptCost int
maxRequestRetries int
waitBeforeRetry int
}
func generateFileHandler(path string) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
r.Header.Add("Cache-Control", "private, max-age=604800") // 7 days
@@ -66,23 +61,43 @@ func main() {
defer db.Close()
// DB Migrations
db.AutoMigrate(&GlobalSettings{})
db.AutoMigrate(&Session{})
db.AutoMigrate(&User{})
db.AutoMigrate(&TextTemplate{})
db.AutoMigrate(&WebTemplate{})
db.AutoMigrate(&TwilioProvider{})
db.AutoMigrate(&Phonebook{})
db.AutoMigrate(&PhoneRecord{})
db.AutoMigrate(&Campaign{})
db.AutoMigrate(&Job{})
db.AutoMigrate(&Visit{})
// Setting up Tapit app
var tapit Tapit
tapit.db = db
tapit.globalSettings.secretRegistrationCode = "Super-Secret-Code"
tapit.globalSettings.threadsPerCampaign = 2
tapit.globalSettings.bcryptCost = 12
tapit.globalSettings.maxRequestRetries = 5
tapit.globalSettings.waitBeforeRetry = 1000
var globalSettings GlobalSettings
// handle global settings
err = tapit.db.Last(&globalSettings).Error
if err != nil {
globalSettings.SecretRegistrationCode = "Super-Secret-Code"
globalSettings.ThreadsPerCampaign = 2
globalSettings.BcryptCost = 12
globalSettings.MaxRequestRetries = 5
globalSettings.WaitBeforeRetry = 1000
globalSettings.WebTemplatePrefix = "https://www.attacker.com/"
globalSettings.WebTemplateRoute = "/"
tapit.db.NewRecord(&globalSettings)
tapit.db.Create(&globalSettings)
}
tapit.globalSettings = globalSettings
// Seeding random
rand.Seed(time.Now().UnixNano())
// Clear running campaigns & starting background jobs
tapit.clearRunningCampaigns()
@@ -114,6 +129,10 @@ func main() {
"/text-template",
"/text-template/new",
"/text-template/{id}/edit",
"/web-template",
"/web-template/new",
"/web-template/{id}/edit",
"/global-settings",
"/provider",
}
indexPath := dir + "/static/index.html"
@@ -127,6 +146,8 @@ func main() {
r.Handle("/api/text-template",tapit.authenticationHandler(tapit.handleTextTemplate))
r.Handle("/api/text-template/{id}",tapit.authenticationHandler(tapit.handleSpecificTextTemplate))
r.Handle("/api/web-template",tapit.authenticationHandler(tapit.handleWebTemplate))
r.Handle("/api/web-template/{id}",tapit.authenticationHandler(tapit.handleSpecificWebTemplate))
r.Handle("/api/provider/twilio",tapit.authenticationHandler(tapit.handleTwilioProvider))
r.Handle("/api/phonebook",tapit.authenticationHandler(tapit.handlePhonebook))
r.Handle("/api/phonebook/{id}",tapit.authenticationHandler(tapit.handleSpecificPhonebook))
@@ -135,9 +156,21 @@ func main() {
r.Handle("/api/campaign/{id}",tapit.authenticationHandler(tapit.handleSpecificCampaign))
r.Handle("/api/campaign/{id}/start",tapit.authenticationHandler(tapit.handleStartCampaign))
r.Handle("/api/campaign/{id}/pause",tapit.authenticationHandler(tapit.handleStopCampaign))
r.Handle("/api/globalsettings",tapit.authenticationHandler(tapit.handleGlobalSettings))
r.Handle("/api/jobs/{id}/visits",tapit.authenticationHandler(tapit.handleDownloadView))
// Starting management web server
r.Handle("/", r)
log.Println("Starting management web server on port 8000...")
go http.ListenAndServe(":8000", r)
// Handle WebTemplate Routes
webTemplateRouter := mux.NewRouter()
webTemplateRouter.HandleFunc("/{route}", tapit.webTemplateRouteHandler)
// Starting victim route web server
webTemplateRouter.Handle("/", webTemplateRouter)
log.Println("Starting victim routes on port 8001...")
http.ListenAndServe(":8001", webTemplateRouter)
// Starting web server
http.Handle("/", r)
log.Println("Starting web server...")
http.ListenAndServe(":8000", nil)
}

Binary file not shown.

View File

@@ -11,12 +11,14 @@ import (
"strconv"
)
// TextTemplate is the persistent object within Postgres
type TextTemplate struct {
gorm.Model
Name string
TemplateStr string
}
// TextTemplateJson is the temporary object for JSON data passing
type TextTemplateJson struct {
Id int `json:"id"`
Name string `json:"name"`
@@ -238,3 +240,4 @@ func textTemplateToJson(textTemplate TextTemplate) TextTemplateJson {
result.CreateDate = textTemplate.CreatedAt
return result
}

View File

@@ -128,12 +128,12 @@ func (tapit *Tapit) twilioSend(accSid string, accToken string, bodyText string,
// sending request
res, err := client.Do(newRequest1)
retriesLeft := tapit.globalSettings.maxRequestRetries
retriesLeft := tapit.globalSettings.MaxRequestRetries
for err != nil && retriesLeft > 0 {
log.Println("Error in sending request")
res, err = client.Do(newRequest1)
retriesLeft -= 1
time.Sleep(time.Duration(tapit.globalSettings.waitBeforeRetry) * time.Millisecond)
time.Sleep(time.Duration(tapit.globalSettings.WaitBeforeRetry) * time.Millisecond)
}
// exit gracefully if can't
@@ -160,12 +160,12 @@ func (tapit *Tapit) twilioCheck(accSid string, accToken string, messageSid strin
// sending request
res, err := client.Do(newRequest1)
retriesLeft := tapit.globalSettings.maxRequestRetries
retriesLeft := tapit.globalSettings.MaxRequestRetries
for err != nil && retriesLeft > 0 {
log.Println("Error in sending request")
res, err = client.Do(newRequest1)
retriesLeft -= 1
time.Sleep(time.Duration(tapit.globalSettings.waitBeforeRetry) * time.Millisecond)
time.Sleep(time.Duration(tapit.globalSettings.WaitBeforeRetry) * time.Millisecond)
}
// exit gracefully if can't
@@ -207,6 +207,7 @@ func (tapit *Tapit) workerTwilioChecker() {
} else if twilioResult.Status == "delivered" {
job.MessageSid = twilioResult.Sid
job.CurrentStatus = "Delivered"
job.TimeSent = time.Now()
}
tapit.db.Save(&job)
}

View File

@@ -0,0 +1,468 @@
package main
import (
"github.com/jinzhu/gorm"
"github.com/gorilla/mux"
"time"
"log"
"math/rand"
"net/http"
"net/http/httputil"
"strings"
"encoding/json"
"io/ioutil"
"strconv"
"encoding/csv"
"bytes"
)
// WebTemplate is the persistent object within Postgres
type WebTemplate struct {
gorm.Model
Name string
TemplateType string // enum redirect, harvester
RedirectAgent string
RedirectNegAgent string
RedirectPlaceholderHtml string
RedirectUrl string
HarvesterBeforeHtml string
HarvesterAfterHtml string
}
// WebTemplateJson is the temporary object for JSON data passing
type WebTemplateJson struct {
Id int `json:"id"`
Name string `json:"name"`
TemplateType string `json:"templateType"`
RedirectAgent string `json:"redirectAgent"`
RedirectNegAgent string `json:"redirectNegAgent"`
RedirectPlaceholderHtml string `json:"redirectPlaceholderHtml"`
RedirectUrl string `json:"redirectUrl"`
HarvesterBeforeHtml string `json:"harvesterBeforeHtml"`
HarvesterAfterHtml string `json:"harvesterAfterHtml"`
CreateDate time.Time `json:"createDate"`
}
type Visit struct {
gorm.Model
JobId uint
SourceIp string
UserAgent string
Method string
BodyContent string
RawRequest string
}
type VisitJson struct {
Id uint `json:"id"`
JobId uint `json:"jobId"`
SourceIP string `json:"sourceIp"`
UserAgent string `json:"userAgent"`
Method string `json:"method"`
BodyContent string `json:"bodyContent"`
RawRequest string `json:"rawRequest"`
CreateDate time.Time `json:"createDate"`
}
func (tapit *Tapit) handleWebTemplate(w http.ResponseWriter, r *http.Request) {
if strings.ToUpper(r.Method) == "GET" {
tapit.getWebTemplates(w, r)
} else if strings.ToUpper(r.Method) == "POST" {
tapit.createWebTemplate(w, r)
} else {
http.Error(w, "HTTP method not implemented", 400)
return
}
}
func (tapit *Tapit) getWebTemplates(w http.ResponseWriter, r *http.Request) {
webTemplates := []WebTemplate{}
tapit.db.Find(&webTemplates)
jsonResults, err := json.Marshal(webTemplatesToJson(webTemplates))
if err != nil {
http.Error(w, err.Error(), 500)
return
} else {
w.Header().Set("Content-Type", "application/json")
w.Write(jsonResults)
return
}
}
func webTemplatesToJson(webTemplates []WebTemplate) []WebTemplateJson {
webTemplateJson := make([]WebTemplateJson, 0)
for _, webTemplate := range webTemplates {
var currentWebTemplateJson WebTemplateJson
currentWebTemplateJson.Id = int(webTemplate.ID)
currentWebTemplateJson.Name = webTemplate.Name
currentWebTemplateJson.TemplateType = webTemplate.TemplateType
currentWebTemplateJson.RedirectAgent = webTemplate.RedirectAgent
currentWebTemplateJson.RedirectNegAgent = webTemplate.RedirectNegAgent
currentWebTemplateJson.RedirectPlaceholderHtml = webTemplate.RedirectPlaceholderHtml
currentWebTemplateJson.RedirectUrl = webTemplate.RedirectUrl
currentWebTemplateJson.HarvesterBeforeHtml = webTemplate.HarvesterBeforeHtml
currentWebTemplateJson.HarvesterAfterHtml = webTemplate.HarvesterAfterHtml
currentWebTemplateJson.CreateDate = webTemplate.CreatedAt
webTemplateJson = append(webTemplateJson, currentWebTemplateJson)
}
return webTemplateJson
}
func (tapit *Tapit) createWebTemplate(w http.ResponseWriter, r *http.Request) {
// start doing work
requestBody, err:= ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
newWebTemplateJson := WebTemplateJson{}
err = json.Unmarshal(requestBody, &newWebTemplateJson)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
if newWebTemplateJson.Name != "" && newWebTemplateJson.TemplateType != "" {
// check that not both user agents are filled
if newWebTemplateJson.RedirectAgent != "" && newWebTemplateJson.RedirectNegAgent != "" {
notifyPopup(w, r, "failure", "Please fill in only either positive or negative redirect user agent.", nil)
return
}
newWebTemplate := jsonToWebTemplate(newWebTemplateJson)
tapit.db.NewRecord(&newWebTemplate)
tapit.db.Create(&newWebTemplate)
if newWebTemplate.ID == 0 {
notifyPopup(w, r, "failure", "Failed to create text template", nil)
return
}
newWebTemplateJson.Id = int(newWebTemplate.ID)
newWebTemplateJson.CreateDate = newWebTemplate.CreatedAt
notifyPopup(w, r, "success", "Successfully added new text template", newWebTemplateJson)
return
} else {
notifyPopup(w, r, "failure", "Please fill in all details", nil)
return
}
}
func jsonToWebTemplate(currentWebTemplateJson WebTemplateJson) WebTemplate {
var webTemplate WebTemplate
webTemplate.Name = currentWebTemplateJson.Name
webTemplate.TemplateType = currentWebTemplateJson.TemplateType
webTemplate.RedirectAgent = currentWebTemplateJson.RedirectAgent
webTemplate.RedirectNegAgent = currentWebTemplateJson.RedirectNegAgent
webTemplate.RedirectPlaceholderHtml = currentWebTemplateJson.RedirectPlaceholderHtml
webTemplate.RedirectUrl = currentWebTemplateJson.RedirectUrl
webTemplate.HarvesterBeforeHtml = currentWebTemplateJson.HarvesterBeforeHtml
webTemplate.HarvesterAfterHtml = currentWebTemplateJson.HarvesterAfterHtml
return webTemplate
}
func (tapit *Tapit) handleSpecificWebTemplate(w http.ResponseWriter, r *http.Request) {
if strings.ToUpper(r.Method) == "PUT" {
tapit.updateWebTemplate(w, r)
} else if strings.ToUpper(r.Method) == "DELETE" {
tapit.deleteWebTemplate(w,r)
} else if strings.ToUpper(r.Method) == "GET" {
tapit.getWebTemplate(w,r)
} else {
http.Error(w, "HTTP method not implemented", 400)
return
}
}
func (tapit *Tapit) updateWebTemplate(w http.ResponseWriter, r *http.Request) {
requestBody, err:= ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
var newWebTemplateJson WebTemplateJson
err = json.Unmarshal(requestBody, &newWebTemplateJson)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
if newWebTemplateJson.Name != "" && newWebTemplateJson.TemplateType != "" {
var newWebTemplate WebTemplate
// get current phonebook
var dbSearchWT WebTemplate
dbSearchWT.ID = uint(newWebTemplateJson.Id)
tapit.db.Where(&dbSearchWT).First(&newWebTemplate)
if newWebTemplate.ID == uint(newWebTemplateJson.Id) {
// update name & template
newWebTemplate.Name = newWebTemplateJson.Name
newWebTemplate.TemplateType = newWebTemplateJson.TemplateType
newWebTemplate.RedirectAgent = newWebTemplateJson.RedirectAgent
newWebTemplate.RedirectNegAgent = newWebTemplateJson.RedirectNegAgent
newWebTemplate.RedirectPlaceholderHtml = newWebTemplateJson.RedirectPlaceholderHtml
newWebTemplate.RedirectUrl = newWebTemplateJson.RedirectUrl
newWebTemplate.HarvesterBeforeHtml = newWebTemplateJson.HarvesterBeforeHtml
newWebTemplate.HarvesterAfterHtml = newWebTemplateJson.HarvesterAfterHtml
// update database
tapit.db.Save(&newWebTemplate)
if newWebTemplate.ID == 0 {
notifyPopup(w, r, "failure", "Failed to update phonebook", nil)
return
}
newWebTemplateJson.Id = int(newWebTemplate.ID)
newWebTemplateJson.CreateDate = newWebTemplate.CreatedAt
notifyPopup(w, r, "success", "Successfully updated web template", newWebTemplateJson)
return
} else {
notifyPopup(w, r, "failure", "Failed to update web template", nil)
return
}
} else {
notifyPopup(w, r, "failure", "Please enter all details", nil)
return
}
}
func (tapit *Tapit) deleteWebTemplate(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
tempID, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Bad request", 400)
return
}
// start working
var webTemplate WebTemplate
// get tt
var dbSearchWT WebTemplate
dbSearchWT.ID = uint(tempID)
tapit.db.Where(dbSearchWT).First(&webTemplate)
if webTemplate.ID == uint(tempID) {
// finally delete it
tapit.db.Delete(&webTemplate)
notifyPopup(w, r, "success", "Successfully deleted phonebook", nil)
return
} else {
http.Error(w, "Bad request", 400)
return
}
}
func (tapit *Tapit) getWebTemplate(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
tempID, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Bad request", 400)
return
}
// start working
var webTemplate WebTemplate
// get tt
var dbSearchWT WebTemplate
dbSearchWT.ID = uint(tempID)
tapit.db.Where(dbSearchWT).First(&webTemplate)
if webTemplate.ID == uint(tempID) {
jsonResults, err := json.Marshal(webTemplateToJson(webTemplate))
if err != nil {
http.Error(w, err.Error(), 500)
return
} else {
w.Header().Set("Content-Type", "application/json")
w.Write(jsonResults)
return
}
} else {
http.Error(w, "Bad request", 400)
return
}
}
func (tapit *Tapit) generateWebTemplateRoute() string {
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
// generate 5 char
var newRoute string
var successRoute bool
successRoute = false
for !successRoute {
newRoute = ""
for i:=0; i<5; i++ {
num := rand.Int() % len(charset)
newRoute = newRoute + string(charset[num])
// search if route already exists
var dbSearchJob Job
var jobs []Job
dbSearchJob.WebRoute = newRoute
tapit.db.Where(&dbSearchJob).Find(&jobs)
if len(jobs) == 0 {
successRoute = true
}
}
}
return newRoute
}
func webTemplateToJson(webTemplate WebTemplate) WebTemplateJson {
var currentWebTemplateJson WebTemplateJson
currentWebTemplateJson.Id = int(webTemplate.ID)
currentWebTemplateJson.Name = webTemplate.Name
currentWebTemplateJson.TemplateType = webTemplate.TemplateType
currentWebTemplateJson.RedirectAgent = webTemplate.RedirectAgent
currentWebTemplateJson.RedirectNegAgent = webTemplate.RedirectNegAgent
currentWebTemplateJson.RedirectPlaceholderHtml = webTemplate.RedirectPlaceholderHtml
currentWebTemplateJson.RedirectUrl = webTemplate.RedirectUrl
currentWebTemplateJson.HarvesterBeforeHtml = webTemplate.HarvesterBeforeHtml
currentWebTemplateJson.HarvesterAfterHtml = webTemplate.HarvesterAfterHtml
currentWebTemplateJson.CreateDate = webTemplate.CreatedAt
return currentWebTemplateJson
}
func (tapit *Tapit) webTemplateRouteHandler(w http.ResponseWriter, r *http.Request) {
var err error
vars := mux.Vars(r)
currRoute := vars["route"]
currJob := Job{}
err = tapit.db.Where(&Job{WebRoute:currRoute}).First(&currJob).Error
if err != nil {
log.Println(err)
http.Error(w, "Bad request", 400)
return
}
currCampaign := Campaign{}
err = tapit.db.Where(&Campaign{Model: gorm.Model{ID:currJob.CampaignId}}).First(&currCampaign).Error
if err != nil {
log.Println(err)
http.Error(w, "Bad request", 400)
return
}
currWebTemplate := WebTemplate{}
err = tapit.db.Where(&WebTemplate{Model: gorm.Model{ID:currCampaign.WebTemplateId}}).First(&currWebTemplate).Error
if err != nil {
log.Println(err)
http.Error(w, "Bad request", 400)
return
}
// check type for "redirect" or "harvester"
if currWebTemplate.TemplateType == "redirect" {
if currWebTemplate.RedirectAgent != "" {
listOfUA := strings.Split(currWebTemplate.RedirectAgent, ",")
currCheck := false
for _, currUA := range listOfUA {
// check if user agent matches
if strings.Contains(r.UserAgent(), currUA) {
currCheck = true
}
}
// if matches at least once, redirect, otherwise placeholder
if currCheck == true {
http.Redirect(w, r, currWebTemplate.RedirectUrl, 302)
} else {
w.Write([]byte(currWebTemplate.RedirectPlaceholderHtml))
}
} else {
listOfUA := strings.Split(currWebTemplate.RedirectNegAgent, ",")
currCheck := true
for _, currUA := range listOfUA {
// check if user agent matches
if strings.Contains(r.UserAgent(), currUA) {
currCheck = false
}
}
// if matches at least once, redirect, otherwise placeholder
if currCheck == true {
http.Redirect(w, r, currWebTemplate.RedirectUrl, 302)
} else {
w.Write([]byte(currWebTemplate.RedirectPlaceholderHtml))
}
}
} else if currWebTemplate.TemplateType == "harvester" {
// if get show before, if post show after
if strings.ToUpper(r.Method) == "GET"{
w.Write([]byte(currWebTemplate.HarvesterBeforeHtml))
} else if strings.ToUpper(r.Method) == "POST"{
w.Write([]byte(currWebTemplate.HarvesterAfterHtml))
} else {
http.Error(w, "Bad request", 400)
}
}
// saving records
requestBody, err:= ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
var newVisit Visit
newVisit = Visit{}
newVisit.JobId = currJob.ID
if r.Header.Get("X-Forwarded-For") == "" {
newVisit.SourceIp = r.RemoteAddr
} else {
newVisit.SourceIp = r.Header.Get("X-Forwarded-For")
}
newVisit.UserAgent = r.UserAgent()
newVisit.Method = r.Method
newVisit.BodyContent = string(requestBody)
rawReqBytes, err := httputil.DumpRequest(r, true)
if err == nil {
newVisit.RawRequest = string(rawReqBytes)
}
// Update visited status
var visits []Visit
tapit.db.Where(Visit{JobId: uint(currJob.ID)}).Find(&visits)
currJob.WebStatus = strconv.Itoa(len(visits) + 1) + " visits"
tapit.db.Save(&currJob)
tapit.db.NewRecord(&newVisit)
tapit.db.Create(&newVisit)
return
}
func (tapit *Tapit) handleDownloadView(w http.ResponseWriter, r *http.Request) {
if strings.ToUpper(r.Method) == "GET" {
var csvBuffer bytes.Buffer
vars := mux.Vars(r)
tempID, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Bad request", 400)
return
}
var visits []Visit
tapit.db.Where(Visit{JobId: uint(tempID)}).Find(&visits)
// generate csv
csvWriter := csv.NewWriter(&csvBuffer)
csvWriter.Write([]string{"ID", "Time", "Source IP", "User Agent", "Method", "Body Content", "Raw Request"})
for _, visit := range visits {
csvWriter.Write([]string{strconv.Itoa(int(visit.ID)), visit.CreatedAt.String(), visit.SourceIp, visit.UserAgent, visit.Method, visit.BodyContent, visit.RawRequest})
}
csvWriter.Flush()
w.Header().Set("Content-Disposition", "attachment; filename=\"results.csv\"")
w.Write(csvBuffer.Bytes())
return
} else {
http.Error(w, "HTTP method not implemented", 400)
return
}
}