Refactor: overhaul program configuration system

This commit is contained in:
kayos@tcp.direct 2023-04-30 04:18:34 -07:00
parent 5892355417
commit e4f9223fb4
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
7 changed files with 170 additions and 120 deletions

40
cmd.go

@ -2,17 +2,20 @@ package main
import ( import (
"fmt" "fmt"
"os"
"strconv"
"strings"
cli "git.tcp.direct/Mirrors/go-prompt" cli "git.tcp.direct/Mirrors/go-prompt"
. "github.com/logrusorgru/aurora" . "github.com/logrusorgru/aurora"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"os"
"protomolecule/src/eros" "protomolecule/src/eros"
"strconv"
//"protomolecule/src/wrath" // "protomolecule/src/wrath"
projVars "protomolecule/src/config"
"protomolecule/src/deimos" "protomolecule/src/deimos"
projVars "protomolecule/src/vars"
"strings"
) )
var suggestions = []cli.Suggest{ var suggestions = []cli.Suggest{
@ -95,16 +98,17 @@ func executor(cmd string) {
os.Exit(0) os.Exit(0)
case "debug": case "debug":
if projVars.Debug { switch log.Logger.GetLevel() {
case zerolog.DebugLevel:
zerolog.SetGlobalLevel(zerolog.InfoLevel) zerolog.SetGlobalLevel(zerolog.InfoLevel)
projVars.Debug = false
log.Info(). log.Info().
Msg("Debug mode turned " + Sprintf(BrightRed("OFF\n").Bold())) Msg("Debug mode turned " + Sprintf(BrightRed("OFF\n").Bold()))
} else { case zerolog.InfoLevel:
zerolog.SetGlobalLevel(zerolog.DebugLevel) zerolog.SetGlobalLevel(zerolog.DebugLevel)
projVars.Debug = true
log.Debug(). log.Debug().
Msg("Debug mode turned " + Sprintf(BrightGreen("ON\n").Bold())) Msg("Debug mode turned " + Sprintf(BrightGreen("ON\n").Bold()))
default:
return
} }
case "eros": case "eros":
@ -136,7 +140,7 @@ func executor(cmd string) {
log.Info(). log.Info().
Str("Name", fromEros.Name). Str("Name", fromEros.Name).
Str("Addr", fromEros.Addr). 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). Int16("Current_RSSI", fromEros.RSSIlast).
Int("Service_Count", len(fromEros.Services)). Int("Service_Count", len(fromEros.Services)).
Msg("EROS_RECALL") Msg("EROS_RECALL")
@ -167,7 +171,7 @@ func executor(cmd string) {
println() println()
} }
projVars.ManuFile = args[1] projVars.GlobalConfig.ManuFile = args[1]
eros.ManufLoad() eros.ManufLoad()
case "adapter": case "adapter":
@ -212,11 +216,11 @@ func executor(cmd string) {
if len(args) > 2 { if len(args) > 2 {
switch args[2] { switch args[2] {
case "tracking": case "tracking":
projVars.TrackingMode = true *projVars.GlobalConfig.CooleanFlags.Tracking = true
projVars.AttackMode = false *projVars.GlobalConfig.CooleanFlags.Attack = false
case "attack": case "attack":
projVars.TrackingMode = false *projVars.GlobalConfig.CooleanFlags.Tracking = false
projVars.AttackMode = true *projVars.GlobalConfig.CooleanFlags.Attack = true
default: default:
// getHelp(getArgs(args)) // getHelp(getArgs(args))
log.Error().Msg("unknown sub command: " + args[2]) log.Error().Msg("unknown sub command: " + args[2])
@ -259,7 +263,7 @@ func executor(cmd string) {
case "clear": case "clear":
print("\033[H\033[2J") print("\033[H\033[2J")
//termenv.ClearScreen() // termenv.ClearScreen()
default: default:
log.Error().Msg("unknown command: " + cmd) log.Error().Msg("unknown command: " + cmd)
@ -304,14 +308,14 @@ func StartCLI() {
executor, executor,
completer, completer,
cli.OptionPrefix("ProtoMolecule"+"> "), cli.OptionPrefix("ProtoMolecule"+"> "),
//cli.OptionPrefixBackgroundColor(cli.Black), // cli.OptionPrefixBackgroundColor(cli.Black),
cli.OptionPrefixTextColor(cli.Cyan), cli.OptionPrefixTextColor(cli.Cyan),
cli.OptionHistory(hist), cli.OptionHistory(hist),
cli.OptionSuggestionBGColor(cli.Black), cli.OptionSuggestionBGColor(cli.Black),
cli.OptionSuggestionTextColor(cli.White), cli.OptionSuggestionTextColor(cli.White),
cli.OptionSelectedSuggestionBGColor(cli.Black), cli.OptionSelectedSuggestionBGColor(cli.Black),
cli.OptionSelectedSuggestionTextColor(cli.Cyan), cli.OptionSelectedSuggestionTextColor(cli.Cyan),
//prompt.OptionLivePrefix // prompt.OptionLivePrefix
cli.OptionTitle("ProtoMolecule"), cli.OptionTitle("ProtoMolecule"),
) )

18
main.go

@ -63,24 +63,10 @@ func loginit() {
func cliFlags() { func cliFlags() {
flag.Parse() flag.Parse()
if *projVars.GlobalConfig.CooleanFlags.Debug {
if *projVars.AFlag {
projVars.AttackMode = true
}
if *projVars.DFlag {
projVars.Debug = true
zerolog.SetGlobalLevel(zerolog.DebugLevel) zerolog.SetGlobalLevel(zerolog.DebugLevel)
} }
manufLoad = *projVars.GlobalConfig.StringFlags.MACVendorFile != ""
if *projVars.TFlag {
projVars.TrackingMode = true
}
if *projVars.MFlag != "0" {
projVars.ManuFile = *projVars.MFlag
manufLoad = true
}
} }
func sigHandler() { func sigHandler() {

@ -2,9 +2,11 @@
package arboghast package arboghast
import ( import (
bluetooth "git.tcp.direct/kayos/prototooth"
projVars "protomolecule/src/vars"
"sync" "sync"
bluetooth "git.tcp.direct/kayos/prototooth"
projVars "protomolecule/src/config"
) )
type Circus struct { type Circus struct {
@ -37,7 +39,7 @@ func NewEntropicFuzzer() *Fuzzy {
} }
mutex := &sync.Mutex{} mutex := &sync.Mutex{}
ad := projVars.ScanAdapter.DefaultAdvertisement() ad := projVars.GlobalConfig.GetScanAdapter().DefaultAdvertisement()
ad.Configure(*options) ad.Configure(*options)
return &Fuzzy{ return &Fuzzy{

99
src/config/config.go Normal file

@ -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
}

@ -5,26 +5,26 @@
// Raw Advertisement Packet (Advertisement) // Raw Advertisement Packet (Advertisement)
// Services UUIDs (Services) // Services UUIDs (Services)
// TODO: // TODO:
// Output to report
// //
// Output to report
package eros package eros
import ( import (
"bufio" "bufio"
jsoniter "github.com/json-iterator/go"
"os" "os"
projVars "protomolecule/src/vars"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
jsoniter "github.com/json-iterator/go"
projVars "protomolecule/src/config"
bluetooth "git.tcp.direct/kayos/prototooth" bluetooth "git.tcp.direct/kayos/prototooth"
"github.com/prologic/bitcask" "github.com/prologic/bitcask"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
var ( var (
@ -39,7 +39,7 @@ var (
err error err error
Manufacturers ManufData Manufacturers ManufData
Exploits Exploit // Exploits Exploit
// DataDir - should be defined by config or cmd flag // DataDir - should be defined by config or cmd flag
DataDir string = "./.eros-data/" 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 // ManufLoad loads data from a json file containing UUID manufacturer associations
func ManufLoad() { func ManufLoad() {
path := projVars.ManuFile path := *projVars.GlobalConfig.StringFlags.MACVendorFile
var uuid bluetooth.UUID var uuid bluetooth.UUID
log.Info(). log.Info().
@ -107,7 +107,7 @@ func ManufLoad() {
utmp, err := strconv.ParseUint(mf.UString, 0, 16) utmp, err := strconv.ParseUint(mf.UString, 0, 16)
if err != nil { if err != nil {
log.Fatal().Str("file", projVars.ManuFile). log.Fatal().Str("file", path).
Str("string", mf.UString). Str("string", mf.UString).
Err(err).Msg("MANUFACTURER_PARSE_ERROR") Err(err).Msg("MANUFACTURER_PARSE_ERROR")
} }
@ -118,8 +118,8 @@ func ManufLoad() {
log.Debug(). log.Debug().
Str("Manufacturer", mf.Name). Str("Manufacturer", mf.Name).
Str("UUID_String", mf.UString). Str("UUID_String", mf.UString).
//Interface("UUID_Type", uuid). // Interface("UUID_Type", uuid).
//Str("Website", mf.Website). // Str("Website", mf.Website).
Msg("LOADED_MANUFACTURER_DATA") Msg("LOADED_MANUFACTURER_DATA")
mf.UString = "" mf.UString = ""
@ -142,7 +142,7 @@ func ManufLoad() {
log.Debug().Str("Manufacturer", mf.Name). log.Debug().Str("Manufacturer", mf.Name).
Int("UUID_Count", len(mf.UUIDs)). Int("UUID_Count", len(mf.UUIDs)).
//Interface("UUIDs", mf.UUIDs). // Interface("UUIDs", mf.UUIDs).
Msg("EXISTING_MANUFACTURER_FOUND") 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. // Slumber - Clean up database entries, sync them to persistent storage, and safelty close the database.
func Slumber() { func Slumber() {
for _, db := range DB { for _, db := range DB {
db.Merge() logErr(db.Merge())
db.Sync() logErr(db.Sync())
db.Close() logErr(db.Close())
} }
} }
@ -241,14 +248,16 @@ func Recall(Addr string) (Device, error) {
return member, err 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 return member, err
} }
func Backup(path string) error { func Backup(path string) error {
for _, db := range DB { for _, db := range DB {
db.Merge() logErr(db.Merge())
db.Sync() logErr(db.Sync())
err := db.Backup(path) err := db.Backup(path)
if err != nil { if err != nil {
return err return err
@ -256,6 +265,7 @@ func Backup(path string) error {
} }
return nil return nil
} }
/* /*
// Hypnosis - retrieve new exploits/attacks from a remote http repository // Hypnosis - retrieve new exploits/attacks from a remote http repository
func Hypnosis(repo string) { 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 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 e.GET("/exploits", func(c echo.Context) error { // This will definitely need to be updated
// Build request // Build request
req, err := http.NewRequest("GET", repo, nil) req, err := http.NewRequest("GET", repo, nil)
@ -289,7 +299,7 @@ func Hypnosis(repo string) {
caCertPool := x509.NewCertPool() caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert) caCertPool.AppendCertsFromPEM(caCert)
// Create client // Create client
client := &http.Client{ client := &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
@ -308,7 +318,7 @@ func Hypnosis(repo string) {
// Defer body close // Defer body close
defer res.Body.Close() defer res.Body.Close()
// Late binding data from JSON // Late binding data from JSON
var exp Exploit var exp Exploit
// Decode JSON stream // Decode JSON stream
@ -355,12 +365,9 @@ func FinalizeExploit(bigidea Exploit) *Exploit {
*/ */
// Known - check if an exploit is present in the database // Known - check if an exploit is present in the database
func Known(Addr string) bool { func Known(Addr string) bool {
if DB["exploits"].Has([]byte(Addr)) { return DB["exploits"].Has([]byte(Addr))
return true
}
return false
} }
// Flashback - retrieve details for the named exploit/attack // Flashback - retrieve details for the named exploit/attack
func Flashback(Addr string) (Exploit, error) { func Flashback(Addr string) (Exploit, error) {
var err error var err error
@ -374,6 +381,8 @@ func Flashback(Addr string) (Exploit, error) {
return member, err 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 return member, err
} }

@ -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{}

@ -4,8 +4,9 @@ import (
bluetooth "git.tcp.direct/kayos/prototooth" bluetooth "git.tcp.direct/kayos/prototooth"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
projVars "protomolecule/src/vars"
"tinygo.org/x/bluetooth/rawterm" "tinygo.org/x/bluetooth/rawterm"
projVars "protomolecule/src/config"
) )
//used for offensive operations //used for offensive operations
@ -43,7 +44,7 @@ func Start(targetUUID bluetooth.UUID) {
//TargetDevice, connectError := projVars.ScanAdapter.Connect(result.Address, bluetooth.ConnectionParams{}) //TargetDevice, connectError := projVars.ScanAdapter.Connect(result.Address, bluetooth.ConnectionParams{})
// Enable BLE interface. // Enable BLE interface.
err := projVars.ScanAdapter.Enable() err := projVars.GlobalConfig.GetScanAdapter().Enable()
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).
@ -55,13 +56,13 @@ func Start(targetUUID bluetooth.UUID) {
var foundDevice bluetooth.ScanResult var foundDevice bluetooth.ScanResult
// Scan for NUS peripheral. // Scan for NUS peripheral.
log.Info().Msg("Scanning...") 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) { if !foundDevice.AdvertisementPayload.HasServiceUUID(targetUUID) {
return return
} }
// Stop the scan. // Stop the scan.
err := projVars.ScanAdapter.StopScan() err := projVars.GlobalConfig.GetScanAdapter().StopScan()
if err != nil { if err != nil {
// Unlikely, but we can't recover from this. // Unlikely, but we can't recover from this.
log.Panic().Err(err). log.Panic().Err(err).
@ -83,7 +84,7 @@ func Start(targetUUID bluetooth.UUID) {
} }
// Found a NUS peripheral. Connect to it. // 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 { if err != nil {
sublog.Error().Err(err). sublog.Error().Err(err).
Msg("Failed to connect") Msg("Failed to connect")