new: new wifi.handshakes.aggregate parameter to control how handshakes get saved

This commit is contained in:
evilsocket 2019-08-22 13:21:52 -04:00
commit da565afa9a
No known key found for this signature in database
GPG key ID: 82E42E7F3B34C97E
4 changed files with 63 additions and 26 deletions

View file

@ -39,6 +39,7 @@ type WiFiModule struct {
ap *network.AccessPoint ap *network.AccessPoint
stickChan int stickChan int
shakesFile string shakesFile string
shakesAggregate bool
skipBroken bool skipBroken bool
pktSourceChan chan gopacket.Packet pktSourceChan chan gopacket.Packet
pktSourceChanClosed bool pktSourceChanClosed bool
@ -76,6 +77,7 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
assocSilent: false, assocSilent: false,
assocOpen: false, assocOpen: false,
showManuf: false, showManuf: false,
shakesAggregate: true,
writes: &sync.WaitGroup{}, writes: &sync.WaitGroup{},
reads: &sync.WaitGroup{}, reads: &sync.WaitGroup{},
chanLock: &sync.Mutex{}, chanLock: &sync.Mutex{},
@ -220,6 +222,10 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
"", "",
"File path of the pcap file to save handshakes to.")) "File path of the pcap file to save handshakes to."))
mod.AddParam(session.NewBoolParameter("wifi.handshakes.aggregate",
"true",
"If true, all handshakes will be saved inside a single file, otherwise a folder with per-network pcap files will be created."))
mod.AddParam(session.NewStringParameter("wifi.ap.ssid", mod.AddParam(session.NewStringParameter("wifi.ap.ssid",
"FreeWiFi", "FreeWiFi",
"", "",
@ -364,6 +370,8 @@ func (mod *WiFiModule) Configure() error {
if mod.shakesFile, err = fs.Expand(mod.shakesFile); err != nil { if mod.shakesFile, err = fs.Expand(mod.shakesFile); err != nil {
return err return err
} }
} else if err, mod.shakesAggregate = mod.BoolParam("wifi.handshakes.aggregate"); err != nil {
return err
} }
if err, ifName = mod.StringParam("wifi.interface"); err != nil { if err, ifName = mod.StringParam("wifi.interface"); err != nil {

View file

@ -2,6 +2,8 @@ package wifi
import ( import (
"bytes" "bytes"
"fmt"
"path"
"github.com/bettercap/bettercap/packets" "github.com/bettercap/bettercap/packets"
@ -85,11 +87,15 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye
// if we have unsaved packets as part of the handshake, save them. // if we have unsaved packets as part of the handshake, save them.
numUnsaved := station.Handshake.NumUnsaved() numUnsaved := station.Handshake.NumUnsaved()
shakesFileName := mod.shakesFile
doSave := numUnsaved > 0 doSave := numUnsaved > 0
if doSave && mod.shakesFile != "" { if doSave && shakesFileName != "" {
mod.Debug("saving handshake frames to %s", mod.shakesFile) if mod.shakesAggregate == false {
if err := mod.Session.WiFi.SaveHandshakesTo(mod.shakesFile, mod.handle.LinkType()); err != nil { shakesFileName = path.Join(shakesFileName, fmt.Sprintf("%s.pcap", station.PathFriendlyName()))
mod.Error("error while saving handshake frames to %s: %s", mod.shakesFile, err) }
mod.Debug("saving handshake frames to %s", shakesFileName)
if err := mod.Session.WiFi.SaveHandshakesTo(shakesFileName, mod.handle.LinkType()); err != nil {
mod.Error("error while saving handshake frames to %s: %s", shakesFileName, err)
} }
} }
@ -97,7 +103,7 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye
// or it contains the PMKID, generate a new event. // or it contains the PMKID, generate a new event.
if doSave && (rawPMKID != nil || station.Handshake.Half() || station.Handshake.Complete()) { if doSave && (rawPMKID != nil || station.Handshake.Half() || station.Handshake.Complete()) {
mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{ mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{
File: mod.shakesFile, File: shakesFileName,
NewPackets: numUnsaved, NewPackets: numUnsaved,
AP: apMac.String(), AP: apMac.String(),
Station: staMac.String(), Station: staMac.String(),

View file

@ -3,6 +3,7 @@ package network
import ( import (
"encoding/json" "encoding/json"
"os" "os"
"path/filepath"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -214,8 +215,15 @@ func (w *WiFi) SaveHandshakesTo(fileName string, linkType layers.LinkType) error
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
doHead := !fs.Exists(fileName) // check if folder exists first
dirName := filepath.Dir(fileName)
if _, err := os.Stat(dirName); err != nil {
if err = os.MkdirAll(dirName, os.ModePerm); err != nil {
return err
}
}
doHead := !fs.Exists(fileName)
fp, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666) fp, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
if err != nil { if err != nil {
return err return err

View file

@ -1,7 +1,14 @@
package network package network
import ( import (
"fmt"
"regexp"
"strconv" "strconv"
"strings"
)
var (
pathNameCleaner = regexp.MustCompile("[^a-zA-Z0-9]+")
) )
type Station struct { type Station struct {
@ -56,3 +63,11 @@ func (s *Station) HasWPS() bool {
func (s *Station) IsOpen() bool { func (s *Station) IsOpen() bool {
return s.Encryption == "" || s.Encryption == "OPEN" return s.Encryption == "" || s.Encryption == "OPEN"
} }
func (s *Station) PathFriendlyName() string {
name := strings.Replace(s.HwAddress, ":", "", -1)
if essid := pathNameCleaner.ReplaceAllString(s.Hostname, ""); essid != "" {
name = fmt.Sprintf("%s_%s", name, essid)
}
return name
}