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"
"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(""))
}

View File

@ -4,10 +4,22 @@ 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:"-"`
@ -17,12 +29,37 @@ type Result struct {
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
static/css/main.css vendored
View File

@ -323,3 +323,6 @@
font-family: 'Courier New',Monospace !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()
$("#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()

View File

@ -73,14 +73,16 @@
</div>
</div>
</div>
</div>
<!-- <div role="tabpanel" class="tab-pane" id="plugins">
<div class="row">
<div class="col-md-8">
<div class="col-md-6">
<p style="text-align:center;">Targets Map</p>
<div id="resultsMap"></div>
</div>
</div>
</div>
<!--
<div role="tabpanel" class="tab-pane" id="plugins">
</div>
<div role="tabpanel" class="tab-pane" id="demographics">
Demographics here
</div> -->