mirror of
https://github.com/bettercap/bettercap.git
synced 2025-03-12 04:36:03 -07:00
new: can.fuzz now supports an optional size argument (thanks musafir)
This commit is contained in:
parent
1c56622cde
commit
72afa07d28
modules/can
@ -13,10 +13,10 @@ import (
|
||||
type CANModule struct {
|
||||
session.SessionModule
|
||||
|
||||
transport string
|
||||
deviceName string
|
||||
dumpName string
|
||||
dumpInject bool
|
||||
transport string
|
||||
filter string
|
||||
filterExpr *bexpr.Evaluator
|
||||
dbc *DBC
|
||||
@ -101,13 +101,14 @@ func NewCanModule(s *session.Session) *CANModule {
|
||||
return mod.Inject(args[0])
|
||||
}))
|
||||
|
||||
mod.AddHandler(session.NewModuleHandler("can.fuzz ID_OR_NODE_NAME", `(?i)^can\.fuzz\s+(.+)$`,
|
||||
mod.AddHandler(session.NewModuleHandler("can.fuzz ID_OR_NODE_NAME OPTIONAL_SIZE", `(?i)^can\.fuzz\s+([^\s]+)\s*(\d*)$`,
|
||||
"If an hexadecimal frame ID is specified, create a randomized version of it and inject it. If a node name is specified, a random message for the given node will be instead used.",
|
||||
func(args []string) error {
|
||||
if !mod.Running() {
|
||||
return errors.New("can module not running")
|
||||
}
|
||||
return mod.Fuzz(args[0])
|
||||
|
||||
return mod.Fuzz(args[0], args[1])
|
||||
}))
|
||||
|
||||
return mod
|
||||
|
@ -147,6 +147,14 @@ func (dbc *DBC) Messages() []*descriptor.Message {
|
||||
return dbc.db.Messages
|
||||
}
|
||||
|
||||
func (dbc *DBC) AvailableMessages() []string {
|
||||
avail := []string{}
|
||||
for _, msg := range dbc.Messages() {
|
||||
avail = append(avail, fmt.Sprintf("%d (%s)", msg.ID, msg.Name))
|
||||
}
|
||||
return avail
|
||||
}
|
||||
|
||||
func (dbc *DBC) Senders() []string {
|
||||
dbc.RLock()
|
||||
defer dbc.RUnlock()
|
||||
|
@ -12,22 +12,15 @@ import (
|
||||
"go.einride.tech/can"
|
||||
)
|
||||
|
||||
func (mod *CANModule) Fuzz(id string) error {
|
||||
rncSource := rand.NewSource(time.Now().Unix())
|
||||
rng := rand.New(rncSource)
|
||||
|
||||
func (mod *CANModule) fuzzSelectFrame(id string, rng *rand.Rand) (uint64, error) {
|
||||
// let's try as an hex number first
|
||||
// frameID, err := strconv.Atoi(id)
|
||||
frameID, err := strconv.ParseUint(id, 16, 32)
|
||||
dataLen := 0
|
||||
frameData := ([]byte)(nil)
|
||||
|
||||
if err != nil {
|
||||
if mod.dbc != nil {
|
||||
// not a number, use as node name
|
||||
// not a number, use as node name if we have a dbc
|
||||
if mod.dbc.Loaded() {
|
||||
fromSender := mod.dbc.MessagesBySender(id)
|
||||
if len(fromSender) == 0 {
|
||||
return fmt.Errorf("no messages defined in DBC file for node %s, available nodes: %s", id, mod.dbc.Senders())
|
||||
return 0, fmt.Errorf("no messages defined in DBC file for node %s, available nodes: %s", id, mod.dbc.Senders())
|
||||
}
|
||||
|
||||
idx := rng.Intn(len(fromSender))
|
||||
@ -35,35 +28,41 @@ func (mod *CANModule) Fuzz(id string) error {
|
||||
mod.Info("selected %s > (%d) %s", id, selected.ID, selected.Name)
|
||||
frameID = uint64(selected.ID)
|
||||
} else {
|
||||
return err
|
||||
// no dbc, just return the error
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return frameID, nil
|
||||
}
|
||||
|
||||
func (mod *CANModule) fuzzGenerateFrame(frameID uint64, size int, rng *rand.Rand) (*can.Frame, error) {
|
||||
dataLen := 0
|
||||
frameData := ([]byte)(nil)
|
||||
|
||||
// if we have a DBC
|
||||
if mod.dbc.Loaded() {
|
||||
if message := mod.dbc.MessageById(uint32(frameID)); message != nil {
|
||||
mod.Info("found as %s", message.Name)
|
||||
|
||||
mod.Info("using message %s", message.Name)
|
||||
dataLen = int(message.Length)
|
||||
frameData = make([]byte, dataLen)
|
||||
if _, err := rand.Read(frameData); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
avail := []string{}
|
||||
for _, msg := range mod.dbc.Messages() {
|
||||
avail = append(avail, fmt.Sprintf("%d (%s)", msg.ID, msg.Name))
|
||||
}
|
||||
return fmt.Errorf("message with id %d not found in DBC file, available ids: %v", frameID, strings.Join(avail, ", "))
|
||||
return nil, fmt.Errorf("message with id %d not found in DBC file, available ids: %v", frameID, strings.Join(mod.dbc.AvailableMessages(), ", "))
|
||||
}
|
||||
} else {
|
||||
dataLen = rng.Intn(int(can.MaxDataLength))
|
||||
frameData = make([]byte, dataLen)
|
||||
|
||||
if _, err := rand.Read(frameData); err != nil {
|
||||
return err
|
||||
if size <= 0 {
|
||||
// pick randomly
|
||||
dataLen = rng.Intn(int(can.MaxDataLength))
|
||||
} else {
|
||||
// user selected
|
||||
dataLen = size
|
||||
}
|
||||
frameData = make([]byte, dataLen)
|
||||
if _, err := rand.Read(frameData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mod.Warning("no dbc loaded, creating frame with %d bytes of random data", dataLen)
|
||||
}
|
||||
|
||||
@ -76,12 +75,34 @@ func (mod *CANModule) Fuzz(id string) error {
|
||||
|
||||
copy(frame.Data[:], frameData)
|
||||
|
||||
mod.Info("injecting %s of CAN frame %d ...",
|
||||
humanize.Bytes(uint64(frame.Length)), frame.ID)
|
||||
return &frame, nil
|
||||
}
|
||||
|
||||
if err := mod.send.TransmitFrame(context.Background(), frame); err != nil {
|
||||
return err
|
||||
func (mod *CANModule) Fuzz(id string, optSize string) error {
|
||||
rncSource := rand.NewSource(time.Now().Unix())
|
||||
rng := rand.New(rncSource)
|
||||
|
||||
fuzzSize := 0
|
||||
if optSize != "" {
|
||||
if num, err := strconv.Atoi(optSize); err != nil {
|
||||
return fmt.Errorf("could not parse numeric size from '%s': %v", optSize, err)
|
||||
} else if num > 8 {
|
||||
return fmt.Errorf("max can frame size is 8, %d given", num)
|
||||
} else {
|
||||
fuzzSize = num
|
||||
}
|
||||
}
|
||||
|
||||
if frameID, err := mod.fuzzSelectFrame(id, rng); err != nil {
|
||||
return err
|
||||
} else if frame, err := mod.fuzzGenerateFrame(frameID, fuzzSize, rng); err != nil {
|
||||
return err
|
||||
} else {
|
||||
mod.Info("injecting %s of CAN frame %d ...",
|
||||
humanize.Bytes(uint64(frame.Length)), frame.ID)
|
||||
if err := mod.send.TransmitFrame(context.Background(), *frame); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user