mirror of
https://github.com/gophish/gophish
synced 2024-11-14 00:07:19 +00:00
Added IP, Lat and Lon to models.Result. Closes #47
Added basic mapping on campaign results. Closes #51
This commit is contained in:
parent
8969ebdccc
commit
c6cd018536
6 changed files with 130 additions and 32 deletions
|
@ -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(""))
|
||||
}
|
||||
|
||||
|
|
|
@ -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
static/css/main.css
vendored
3
static/css/main.css
vendored
|
@ -323,3 +323,6 @@
|
|||
font-family: 'Courier New',Monospace !important;
|
||||
font-size: small !important;
|
||||
}
|
||||
#resultsMap {
|
||||
margin-top:-30px;
|
||||
}
|
||||
|
|
BIN
static/db/geolite2-city.mmdb
Normal file
BIN
static/db/geolite2-city.mmdb
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 MiB |
|
@ -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()
|
||||
|
|
|
@ -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…
Reference in a new issue