Browse Source

Added IP, Lat and Lon to models.Result. Closes #47

Added basic mapping on campaign results. Closes #51
pull/64/head
Jordan Wright 5 years ago
parent
commit
c6cd018536
6 changed files with 130 additions and 32 deletions
  1. +11
    -0
      controllers/route.go
  2. +45
    -8
      models/result.go
  3. +3
    -0
      static/css/main.css
  4. BIN
      static/db/geolite2-city.mmdb
  5. +62
    -17
      static/js/app/campaign_results.js
  6. +9
    -7
      templates/campaign_results.html

+ 11
- 0
controllers/route.go View File

@ -4,6 +4,7 @@ import (
"fmt"
"html/template"
"log"
"net"
"net/http"
"os"
@ -101,6 +102,16 @@ func PhishTracker(w http.ResponseWriter, r *http.Request) {
if err != nil {
Logger.Println(err)
}
// Update the GeoIP information
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err == nil {
err = rs.UpdateGeo(ip)
if err != nil {
Logger.Println(err)
}
} else {
Logger.Println(err)
}
w.Write([]byte(""))
}

+ 45
- 8
models/result.go View File

@ -4,25 +4,62 @@ import (
"crypto/rand"
"fmt"
"io"
"log"
"net"
"github.com/jinzhu/gorm"
"github.com/oschwald/maxminddb-golang"
)
type mmCity struct {
GeoPoint mmGeoPoint `maxminddb:"location"`
}
type mmGeoPoint struct {
Latitude float64 `maxminddb:"latitude"`
Longitude float64 `maxminddb:"longitude"`
}
type Result struct {
Id int64 `json:"-"`
CampaignId int64 `json:"-"`
UserId int64 `json:"-"`
RId string `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Status string `json:"status" sql:"not null"`
Id int64 `json:"-"`
CampaignId int64 `json:"-"`
UserId int64 `json:"-"`
RId string `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Status string `json:"status" sql:"not null"`
IP string `json:"ip"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
func (r *Result) UpdateStatus(s string) error {
return db.Table("results").Where("id=?", r.Id).Update("status", s).Error
}
func (r *Result) UpdateGeo(addr string) error {
// Open a connection to the maxmind db
mmdb, err := maxminddb.Open("static/db/geolite2-city.mmdb")
if err != nil {
log.Fatal(err)
}
defer mmdb.Close()
ip := net.ParseIP(addr)
var city mmCity
// Get the record
err = mmdb.Lookup(ip, &city)
if err != nil {
return err
}
// Update the database with the record information
return db.Table("results").Where("id=?", r.Id).Updates(map[string]interface{}{
"ip": addr,
"latitude": city.GeoPoint.Latitude,
"longitude": city.GeoPoint.Longitude,
}).Error
}
func (r *Result) GenerateId() {
// Keep trying until we generate a unique key (shouldn't take more than one or two iterations)
k := make([]byte, 32)

+ 3
- 0
static/css/main.css View File

@ -323,3 +323,6 @@
font-family: 'Courier New',Monospace !important;
font-size: small !important;
}
#resultsMap {
margin-top:-30px;
}

BIN
static/db/geolite2-city.mmdb View File

Before After

+ 62
- 17
static/js/app/campaign_results.js View File

@ -183,25 +183,70 @@ $(document).ready(function(){
});
$("#loading").hide()
$("#campaignResults").show()
map = new Datamap({
element: document.getElementById("resultsMap"),
responsive: true,
fills: {
defaultFill: "#ffffff",
point: "#34495e"
},
geographyConfig: {
highlightFillColor : "#1abc9c",
borderColor:"#34495e"
},
bubblesConfig: {
borderColor: "#34495e"
}
});
bubbles = []
$.each(campaign.results, function(i, result){
// Check that it wasn't an internal IP
if (result.latitude == 0 && result.longitude == 0) { return true; }
newIP = true
$.each(bubbles, function(i, bubble){
if (bubble.ip == result.ip){
bubbles[i].radius += 1
newIP = false
return false
}
})
if (newIP){
console.log("Adding bubble at: ")
console.log({
latitude : result.latitude,
longitude: result.longitude,
name : result.ip,
fillKey: "point"
})
bubbles.push({
latitude : result.latitude,
longitude: result.longitude,
name : result.ip,
fillKey: "point",
radius: 2
})
}
})
map.bubbles(bubbles)
}
// Load up the map data (only once!)
// Slated for 0.2 release - coming soon! :)
// $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// if ($(e.target).attr('href') == "#plugins"){
// if (!map){
// map = new Datamap({
// element: document.getElementById("resultsMap"),
// responsive: true,
// fills: {
// defaultFill: "#34495e"
// },
// geographyConfig: {
// highlightFillColor : "#1abc9c"
// }
// });
// }
// }
// })
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if ($(e.target).attr('href') == "#overview"){
if (!map){
map = new Datamap({
element: document.getElementById("resultsMap"),
responsive: true,
fills: {
defaultFill: "#ffffff"
},
geographyConfig: {
highlightFillColor : "#1abc9c",
borderColor:"#34495e"
}
});
}
}
})
})
.error(function(){
$("#loading").hide()

+ 9
- 7
templates/campaign_results.html View File

@ -52,8 +52,8 @@
<div class="row">
<ul class="nav nav-tabs" role="tablist">
<li class="active"><a href="#overview" aria-controls="home" role="tab" data-toggle="tab">Overview</a></li>
<!-- <li><a href="#plugins" aria-controls="profile" role="tab" data-toggle="tab">Plugins</a></li>
<li><a href="#demographics" aria-controls="settings" role="tab" data-toggle="tab">Demographics</a></li> -->
<!--<li><a href="#plugins" aria-controls="profile" role="tab" data-toggle="tab">Plugins</a></li>
<li><a href="#demographics" aria-controls="settings" role="tab" data-toggle="tab">Demographics</a></li>-->
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="overview">
@ -73,13 +73,15 @@
</div>
</div>
</div>
</div>
<!-- <div role="tabpanel" class="tab-pane" id="plugins">
<div class="row">
<div class="col-md-8">
<div class="row">
<div class="col-md-6">
<p style="text-align:center;">Targets Map</p>
<div id="resultsMap"></div>
</div>
</div>
</div>
</div>
<!--
<div role="tabpanel" class="tab-pane" id="plugins">
</div>
<div role="tabpanel" class="tab-pane" id="demographics">
Demographics here

Loading…
Cancel
Save