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

Added basic mapping on campaign results. Closes #51
pull/64/head
Jordan Wright 2016-01-04 00:04:10 -06:00
parent 8969ebdccc
commit c6cd018536
6 changed files with 130 additions and 32 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"html/template" "html/template"
"log" "log"
"net"
"net/http" "net/http"
"os" "os"
@ -101,6 +102,16 @@ func PhishTracker(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
Logger.Println(err) 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("")) w.Write([]byte(""))
} }

View File

@ -4,25 +4,62 @@ import (
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"io" "io"
"log"
"net"
"github.com/jinzhu/gorm" "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 { type Result struct {
Id int64 `json:"-"` Id int64 `json:"-"`
CampaignId int64 `json:"-"` CampaignId int64 `json:"-"`
UserId int64 `json:"-"` UserId int64 `json:"-"`
RId string `json:"id"` RId string `json:"id"`
Email string `json:"email"` Email string `json:"email"`
FirstName string `json:"first_name"` FirstName string `json:"first_name"`
LastName string `json:"last_name"` LastName string `json:"last_name"`
Status string `json:"status" sql:"not null"` 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 { func (r *Result) UpdateStatus(s string) error {
return db.Table("results").Where("id=?", r.Id).Update("status", s).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() { func (r *Result) GenerateId() {
// Keep trying until we generate a unique key (shouldn't take more than one or two iterations) // Keep trying until we generate a unique key (shouldn't take more than one or two iterations)
k := make([]byte, 32) k := make([]byte, 32)

3
static/css/main.css vendored
View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 MiB

View File

@ -183,25 +183,70 @@ $(document).ready(function(){
}); });
$("#loading").hide() $("#loading").hide()
$("#campaignResults").show() $("#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!) // Load up the map data (only once!)
// Slated for 0.2 release - coming soon! :) $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { if ($(e.target).attr('href') == "#overview"){
// if ($(e.target).attr('href') == "#plugins"){ if (!map){
// if (!map){ map = new Datamap({
// map = new Datamap({ element: document.getElementById("resultsMap"),
// element: document.getElementById("resultsMap"), responsive: true,
// responsive: true, fills: {
// fills: { defaultFill: "#ffffff"
// defaultFill: "#34495e" },
// }, geographyConfig: {
// geographyConfig: { highlightFillColor : "#1abc9c",
// highlightFillColor : "#1abc9c" borderColor:"#34495e"
// } }
// }); });
// } }
// } }
// }) })
}) })
.error(function(){ .error(function(){
$("#loading").hide() $("#loading").hide()

View File

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