From e4f9223fb4d91b91a395756bd534eece01b6393c Mon Sep 17 00:00:00 2001 From: "kayos@tcp.direct" Date: Sun, 30 Apr 2023 04:18:34 -0700 Subject: [PATCH] Refactor: overhaul program configuration system --- cmd.go | 40 ++++++++------- main.go | 18 +------ src/arboghast/arboghast.go | 8 +-- src/config/config.go | 99 ++++++++++++++++++++++++++++++++++++++ src/eros/eros.go | 63 +++++++++++++----------- src/vars/projVars.go | 51 -------------------- src/wrath/wrath.go | 11 +++-- 7 files changed, 170 insertions(+), 120 deletions(-) create mode 100644 src/config/config.go delete mode 100644 src/vars/projVars.go diff --git a/cmd.go b/cmd.go index 31f313a..fdcb382 100644 --- a/cmd.go +++ b/cmd.go @@ -2,17 +2,20 @@ package main import ( "fmt" + "os" + "strconv" + "strings" + cli "git.tcp.direct/Mirrors/go-prompt" . "github.com/logrusorgru/aurora" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "os" + "protomolecule/src/eros" - "strconv" - //"protomolecule/src/wrath" + + // "protomolecule/src/wrath" + projVars "protomolecule/src/config" "protomolecule/src/deimos" - projVars "protomolecule/src/vars" - "strings" ) var suggestions = []cli.Suggest{ @@ -95,16 +98,17 @@ func executor(cmd string) { os.Exit(0) case "debug": - if projVars.Debug { + switch log.Logger.GetLevel() { + case zerolog.DebugLevel: zerolog.SetGlobalLevel(zerolog.InfoLevel) - projVars.Debug = false log.Info(). Msg("Debug mode turned " + Sprintf(BrightRed("OFF\n").Bold())) - } else { + case zerolog.InfoLevel: zerolog.SetGlobalLevel(zerolog.DebugLevel) - projVars.Debug = true log.Debug(). Msg("Debug mode turned " + Sprintf(BrightGreen("ON\n").Bold())) + default: + return } case "eros": @@ -136,7 +140,7 @@ func executor(cmd string) { log.Info(). Str("Name", fromEros.Name). Str("Addr", fromEros.Addr). - Str("ManuF", fromEros.Manufacturer). //needs to be changed back to fromEros.Manufacturer + Str("ManuF", fromEros.Manufacturer). // needs to be changed back to fromEros.Manufacturer Int16("Current_RSSI", fromEros.RSSIlast). Int("Service_Count", len(fromEros.Services)). Msg("EROS_RECALL") @@ -167,7 +171,7 @@ func executor(cmd string) { println() } - projVars.ManuFile = args[1] + projVars.GlobalConfig.ManuFile = args[1] eros.ManufLoad() case "adapter": @@ -212,11 +216,11 @@ func executor(cmd string) { if len(args) > 2 { switch args[2] { case "tracking": - projVars.TrackingMode = true - projVars.AttackMode = false + *projVars.GlobalConfig.CooleanFlags.Tracking = true + *projVars.GlobalConfig.CooleanFlags.Attack = false case "attack": - projVars.TrackingMode = false - projVars.AttackMode = true + *projVars.GlobalConfig.CooleanFlags.Tracking = false + *projVars.GlobalConfig.CooleanFlags.Attack = true default: // getHelp(getArgs(args)) log.Error().Msg("unknown sub command: " + args[2]) @@ -259,7 +263,7 @@ func executor(cmd string) { case "clear": print("\033[H\033[2J") - //termenv.ClearScreen() + // termenv.ClearScreen() default: log.Error().Msg("unknown command: " + cmd) @@ -304,14 +308,14 @@ func StartCLI() { executor, completer, cli.OptionPrefix("ProtoMolecule"+"> "), - //cli.OptionPrefixBackgroundColor(cli.Black), + // cli.OptionPrefixBackgroundColor(cli.Black), cli.OptionPrefixTextColor(cli.Cyan), cli.OptionHistory(hist), cli.OptionSuggestionBGColor(cli.Black), cli.OptionSuggestionTextColor(cli.White), cli.OptionSelectedSuggestionBGColor(cli.Black), cli.OptionSelectedSuggestionTextColor(cli.Cyan), - //prompt.OptionLivePrefix + // prompt.OptionLivePrefix cli.OptionTitle("ProtoMolecule"), ) diff --git a/main.go b/main.go index ec82876..a782afa 100644 --- a/main.go +++ b/main.go @@ -63,24 +63,10 @@ func loginit() { func cliFlags() { flag.Parse() - - if *projVars.AFlag { - projVars.AttackMode = true - } - - if *projVars.DFlag { - projVars.Debug = true + if *projVars.GlobalConfig.CooleanFlags.Debug { zerolog.SetGlobalLevel(zerolog.DebugLevel) } - - if *projVars.TFlag { - projVars.TrackingMode = true - } - - if *projVars.MFlag != "0" { - projVars.ManuFile = *projVars.MFlag - manufLoad = true - } + manufLoad = *projVars.GlobalConfig.StringFlags.MACVendorFile != "" } func sigHandler() { diff --git a/src/arboghast/arboghast.go b/src/arboghast/arboghast.go index 9a702e9..32e4b92 100644 --- a/src/arboghast/arboghast.go +++ b/src/arboghast/arboghast.go @@ -2,9 +2,11 @@ package arboghast import ( - bluetooth "git.tcp.direct/kayos/prototooth" - projVars "protomolecule/src/vars" "sync" + + bluetooth "git.tcp.direct/kayos/prototooth" + + projVars "protomolecule/src/config" ) type Circus struct { @@ -37,7 +39,7 @@ func NewEntropicFuzzer() *Fuzzy { } mutex := &sync.Mutex{} - ad := projVars.ScanAdapter.DefaultAdvertisement() + ad := projVars.GlobalConfig.GetScanAdapter().DefaultAdvertisement() ad.Configure(*options) return &Fuzzy{ diff --git a/src/config/config.go b/src/config/config.go new file mode 100644 index 0000000..c10f1ad --- /dev/null +++ b/src/config/config.go @@ -0,0 +1,99 @@ +package common + +import ( + "flag" + + bluetooth "git.tcp.direct/kayos/prototooth" +) + +type Mode uint32 + +const ( + ModeNone Mode = iota + ModeScan + ModeTrack + ModeAttack +) + +func (m Mode) String() string { + return [...]string{"None", "Track", "Attack"}[m] +} + +// Tooth is a bluetooth adapter. +type Tooth struct { + ID int + Usecase Mode + *bluetooth.Adapter +} + +type Config struct { + // ManuFile is a place holder for a file with list of all known Manufacturers + // this is actually stored by eros and likely deprecated. + ManuFile string + Teeth []*Tooth + + CooleanFlags struct { + Debug *bool + Attack *bool + Tracking *bool + } + StringFlags struct { + MACVendorFile *string + MACTarget *string + } +} + +func (c *Config) GetScanAdapter() *bluetooth.Adapter { + if len(c.Teeth) == 1 { + return c.Teeth[0].Adapter + } + var choice *bluetooth.Adapter + for _, v := range c.Teeth { + if v.Usecase == ModeScan || v.Usecase == ModeTrack { + choice = v.Adapter + break + } + } + return choice +} + +var DefaultConfig = Config{ + ManuFile: DefManuFile, + Teeth: []*Tooth{ + &Tooth{ + ID: 0, + Usecase: ModeNone, + Adapter: bluetooth.DefaultAdapter, + }, + }, + CooleanFlags: struct { + Debug *bool + Attack *bool + Tracking *bool + }{ + Debug: flag.Bool("d", false, "global debug logging and pretty printing"), + Attack: flag.Bool("a", false, "attack mode"), + Tracking: flag.Bool("t", false, "device tracking mode"), + }, + + StringFlags: struct { + MACVendorFile *string + MACTarget *string + }{ + MACVendorFile: flag.String("m", DefManuFile, "json file with manufacturer identifying data to preload into eros"), + MACTarget: flag.String("w", "00:00:00:00:00:00", "MAC address of target"), + }, +} + +const DefManuFile = "./ManufUUID.json" + +// Service UUIDs for testing +var ( + SonosScanTest = bluetooth.New16BitUUID(0xfe07) + AppleScanTest = bluetooth.New16BitUUID(0x004c) + GlobalConfig *Config +) + +func init() { + GlobalConfig = &DefaultConfig +} diff --git a/src/eros/eros.go b/src/eros/eros.go index 6dc933a..1f235af 100644 --- a/src/eros/eros.go +++ b/src/eros/eros.go @@ -5,26 +5,26 @@ // Raw Advertisement Packet (Advertisement) // Services UUIDs (Services) -// TODO: -// Output to report +// TODO: // +// Output to report package eros import ( "bufio" - jsoniter "github.com/json-iterator/go" "os" - projVars "protomolecule/src/vars" "strconv" "strings" "sync" "time" + jsoniter "github.com/json-iterator/go" + + projVars "protomolecule/src/config" + bluetooth "git.tcp.direct/kayos/prototooth" "github.com/prologic/bitcask" "github.com/rs/zerolog/log" - - ) var ( @@ -39,7 +39,7 @@ var ( err error Manufacturers ManufData - Exploits Exploit + // Exploits Exploit // DataDir - should be defined by config or cmd flag DataDir string = "./.eros-data/" @@ -82,7 +82,7 @@ func (d *Device) ConnectHandler(target bluetooth.Addresser, c bool) { // ManufLoad loads data from a json file containing UUID manufacturer associations func ManufLoad() { - path := projVars.ManuFile + path := *projVars.GlobalConfig.StringFlags.MACVendorFile var uuid bluetooth.UUID log.Info(). @@ -107,7 +107,7 @@ func ManufLoad() { utmp, err := strconv.ParseUint(mf.UString, 0, 16) if err != nil { - log.Fatal().Str("file", projVars.ManuFile). + log.Fatal().Str("file", path). Str("string", mf.UString). Err(err).Msg("MANUFACTURER_PARSE_ERROR") } @@ -118,8 +118,8 @@ func ManufLoad() { log.Debug(). Str("Manufacturer", mf.Name). Str("UUID_String", mf.UString). - //Interface("UUID_Type", uuid). - //Str("Website", mf.Website). + // Interface("UUID_Type", uuid). + // Str("Website", mf.Website). Msg("LOADED_MANUFACTURER_DATA") mf.UString = "" @@ -142,7 +142,7 @@ func ManufLoad() { log.Debug().Str("Manufacturer", mf.Name). Int("UUID_Count", len(mf.UUIDs)). - //Interface("UUIDs", mf.UUIDs). + // Interface("UUIDs", mf.UUIDs). Msg("EXISTING_MANUFACTURER_FOUND") } @@ -182,12 +182,19 @@ func Awaken() { } } +func logErr(err error) { + if err != nil { + log.Error().Err(err). + Msg("EROS_DATABASE_ERROR") + } +} + // Slumber - Clean up database entries, sync them to persistent storage, and safelty close the database. func Slumber() { for _, db := range DB { - db.Merge() - db.Sync() - db.Close() + logErr(db.Merge()) + logErr(db.Sync()) + logErr(db.Close()) } } @@ -241,14 +248,16 @@ func Recall(Addr string) (Device, error) { return member, err } - json.Unmarshal(bytes, &member) + if err := json.Unmarshal(bytes, &member); err != nil { + log.Panic().Err(err).Msg("Failed to unmarshal device") + } return member, err } func Backup(path string) error { for _, db := range DB { - db.Merge() - db.Sync() + logErr(db.Merge()) + logErr(db.Sync()) err := db.Backup(path) if err != nil { return err @@ -256,6 +265,7 @@ func Backup(path string) error { } return nil } + /* // Hypnosis - retrieve new exploits/attacks from a remote http repository func Hypnosis(repo string) { @@ -267,7 +277,7 @@ func Hypnosis(repo string) { AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE} //TODO: possibly trim the methods })) - // GET + // GET e.GET("/exploits", func(c echo.Context) error { // This will definitely need to be updated // Build request req, err := http.NewRequest("GET", repo, nil) @@ -289,7 +299,7 @@ func Hypnosis(repo string) { caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) - // Create client + // Create client client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ @@ -308,7 +318,7 @@ func Hypnosis(repo string) { // Defer body close defer res.Body.Close() - // Late binding data from JSON + // Late binding data from JSON var exp Exploit // Decode JSON stream @@ -355,12 +365,9 @@ func FinalizeExploit(bigidea Exploit) *Exploit { */ // Known - check if an exploit is present in the database func Known(Addr string) bool { - if DB["exploits"].Has([]byte(Addr)) { - return true - } - - return false + return DB["exploits"].Has([]byte(Addr)) } + // Flashback - retrieve details for the named exploit/attack func Flashback(Addr string) (Exploit, error) { var err error @@ -374,6 +381,8 @@ func Flashback(Addr string) (Exploit, error) { return member, err } - json.Unmarshal(bytes, &member) + if err := json.Unmarshal(bytes, &member); err != nil { + log.Panic().Err(err).Msg("Failed to unmarshal exploit") + } return member, err } diff --git a/src/vars/projVars.go b/src/vars/projVars.go deleted file mode 100644 index 93ecb28..0000000 --- a/src/vars/projVars.go +++ /dev/null @@ -1,51 +0,0 @@ -package common - -import ( - "flag" - - bluetooth "git.tcp.direct/kayos/prototooth" -) - -type Config struct { -} - -var InitResults []string - -// ManuFile is a place holder for a file with list of all known Manufacturers -// this is actually stored by eros and likely deprecated. -var ManuFile = "./ManufUUID.json" - -// AdapterInUse TODO: use this or refactor it -var AdapterInUse = *&bluetooth.Adapter{} - -var AttackMode bool = false -var TrackingMode bool = false - -// var SrvcUUIDList map[uint32]string - -// ScanResChan hold the values for the initial ble scan results.. -// ... i.e. the mac and broadcast name string -var ScanResChan = make(chan bluetooth.ScanResult) - -// ScanAdapter the BLE adapter --duh -// var Adapter = bluetooth.DefaultAdapter -var ScanAdapter = bluetooth.DefaultAdapter - -var AttackAdapter = bluetooth.DefaultAdapter - -// DFlag Device to be targeted --not fully implemented -// var Target = flag.String("t", "00:00:00:00:00:00", "Target device to attack") -var DFlag = flag.Bool("d", false, "global debug logging and pretty printing") -var AFlag = flag.Bool("a", false, "attack mode") -var TFlag = flag.Bool("t", false, "device tracking mode") -var MFlag = flag.String("m", "0", "json file with manufacturer identifying data to preload into eros") -var WAFlag = flag.String("w", "00:00:00:00:00:00", "MAC address of target") - -var Debug bool = false - -// SonosScanTest Service UUIDs for testing -var SonosScanTest = bluetooth.New16BitUUID(0xfe07) -var AppleScanTest = bluetooth.New16BitUUID(0x004c) - -// WrathTarget target to attack with wrath -var WrathTarget = bluetooth.Address{} diff --git a/src/wrath/wrath.go b/src/wrath/wrath.go index 868d987..6ab73c6 100644 --- a/src/wrath/wrath.go +++ b/src/wrath/wrath.go @@ -4,8 +4,9 @@ import ( bluetooth "git.tcp.direct/kayos/prototooth" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - projVars "protomolecule/src/vars" "tinygo.org/x/bluetooth/rawterm" + + projVars "protomolecule/src/config" ) //used for offensive operations @@ -43,7 +44,7 @@ func Start(targetUUID bluetooth.UUID) { //TargetDevice, connectError := projVars.ScanAdapter.Connect(result.Address, bluetooth.ConnectionParams{}) // Enable BLE interface. - err := projVars.ScanAdapter.Enable() + err := projVars.GlobalConfig.GetScanAdapter().Enable() if err != nil { log.Error(). Err(err). @@ -55,13 +56,13 @@ func Start(targetUUID bluetooth.UUID) { var foundDevice bluetooth.ScanResult // Scan for NUS peripheral. log.Info().Msg("Scanning...") - err = projVars.ScanAdapter.Scan(func(adapter *bluetooth.Adapter, foundDevice bluetooth.ScanResult) { + err = projVars.GlobalConfig.GetScanAdapter().Scan(func(adapter *bluetooth.Adapter, foundDevice bluetooth.ScanResult) { if !foundDevice.AdvertisementPayload.HasServiceUUID(targetUUID) { return } // Stop the scan. - err := projVars.ScanAdapter.StopScan() + err := projVars.GlobalConfig.GetScanAdapter().StopScan() if err != nil { // Unlikely, but we can't recover from this. log.Panic().Err(err). @@ -83,7 +84,7 @@ func Start(targetUUID bluetooth.UUID) { } // Found a NUS peripheral. Connect to it. - device, err := projVars.ScanAdapter.Connect(foundDevice.Address, bluetooth.ConnectionParams{}) + device, err := projVars.GlobalConfig.GetScanAdapter().Connect(foundDevice.Address, bluetooth.ConnectionParams{}) if err != nil { sublog.Error().Err(err). Msg("Failed to connect")