mirror of
https://github.com/bettercap/bettercap
synced 2025-07-06 04:52:10 -07:00
204 lines
3.8 KiB
Go
204 lines
3.8 KiB
Go
package session
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/evilsocket/bettercap-ng/core"
|
|
bnet "github.com/evilsocket/bettercap-ng/net"
|
|
)
|
|
|
|
const TargetsDefaultTTL = 10
|
|
const TargetsAliasesFile = "~/bettercap.aliases"
|
|
|
|
type Targets struct {
|
|
sync.Mutex
|
|
|
|
Session *Session `json:"-"`
|
|
Interface *bnet.Endpoint
|
|
Gateway *bnet.Endpoint
|
|
Targets map[string]*bnet.Endpoint
|
|
TTL map[string]uint
|
|
Aliases map[string]string
|
|
|
|
aliasesFileName string
|
|
}
|
|
|
|
func NewTargets(s *Session, iface, gateway *bnet.Endpoint) *Targets {
|
|
t := &Targets{
|
|
Session: s,
|
|
Interface: iface,
|
|
Gateway: gateway,
|
|
Targets: make(map[string]*bnet.Endpoint),
|
|
TTL: make(map[string]uint),
|
|
Aliases: make(map[string]string),
|
|
}
|
|
|
|
t.aliasesFileName, _ = core.ExpandPath(TargetsAliasesFile)
|
|
if core.Exists(t.aliasesFileName) {
|
|
if err := t.loadAliases(); err != nil {
|
|
s.Events.Log(core.ERROR, "%s", err)
|
|
}
|
|
}
|
|
|
|
return t
|
|
}
|
|
|
|
func (tp *Targets) List() (list []*bnet.Endpoint) {
|
|
tp.Lock()
|
|
defer tp.Unlock()
|
|
|
|
list = make([]*bnet.Endpoint, 0)
|
|
for _, t := range tp.Targets {
|
|
list = append(list, t)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (tp *Targets) loadAliases() error {
|
|
tp.Session.Events.Log(core.INFO, "Loading aliases from %s ...", tp.aliasesFileName)
|
|
file, err := os.Open(tp.aliasesFileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
parts := strings.SplitN(line, " ", 2)
|
|
mac := core.Trim(parts[0])
|
|
alias := core.Trim(parts[1])
|
|
tp.Session.Events.Log(core.DEBUG, " aliases[%s] = '%s'", mac, alias)
|
|
tp.Aliases[mac] = alias
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (tp *Targets) saveAliases() {
|
|
data := ""
|
|
for mac, alias := range tp.Aliases {
|
|
data += fmt.Sprintf("%s %s\n", mac, alias)
|
|
}
|
|
ioutil.WriteFile(tp.aliasesFileName, []byte(data), 0644)
|
|
}
|
|
|
|
func (tp *Targets) SetAliasFor(mac, alias string) bool {
|
|
tp.Lock()
|
|
defer tp.Unlock()
|
|
|
|
if t, found := tp.Targets[mac]; found == true {
|
|
if alias != "" {
|
|
tp.Aliases[mac] = alias
|
|
} else {
|
|
delete(tp.Aliases, mac)
|
|
}
|
|
|
|
t.Alias = alias
|
|
tp.saveAliases()
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (tp *Targets) WasMissed(mac string) bool {
|
|
if mac == tp.Session.Interface.HwAddress || mac == tp.Session.Gateway.HwAddress {
|
|
return false
|
|
}
|
|
|
|
tp.Lock()
|
|
defer tp.Unlock()
|
|
|
|
if ttl, found := tp.TTL[mac]; found == true {
|
|
return ttl < TargetsDefaultTTL
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (tp *Targets) Remove(ip, mac string) {
|
|
tp.Lock()
|
|
defer tp.Unlock()
|
|
|
|
if e, found := tp.Targets[mac]; found {
|
|
tp.TTL[mac]--
|
|
if tp.TTL[mac] == 0 {
|
|
tp.Session.Events.Add("endpoint.lost", e)
|
|
delete(tp.Targets, mac)
|
|
delete(tp.TTL, mac)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
func (tp *Targets) shouldIgnore(ip string) bool {
|
|
// skip our own address
|
|
if ip == tp.Interface.IpAddress {
|
|
return true
|
|
}
|
|
// skip the gateway
|
|
if ip == tp.Gateway.IpAddress {
|
|
return true
|
|
}
|
|
// skip broadcast addresses
|
|
if strings.HasSuffix(ip, ".255") {
|
|
return true
|
|
}
|
|
// skip everything which is not in our subnet (multicast noise)
|
|
addr := net.ParseIP(ip)
|
|
return tp.Session.Interface.Net.Contains(addr) == false
|
|
}
|
|
|
|
func (tp *Targets) Has(ip string) bool {
|
|
tp.Lock()
|
|
defer tp.Unlock()
|
|
|
|
for _, e := range tp.Targets {
|
|
if e.IpAddress == ip {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (tp *Targets) AddIfNew(ip, mac string) *bnet.Endpoint {
|
|
tp.Lock()
|
|
defer tp.Unlock()
|
|
|
|
if tp.shouldIgnore(ip) {
|
|
return nil
|
|
}
|
|
|
|
mac = bnet.NormalizeMac(mac)
|
|
if t, found := tp.Targets[mac]; found {
|
|
if tp.TTL[mac] < TargetsDefaultTTL {
|
|
tp.TTL[mac]++
|
|
}
|
|
return t
|
|
}
|
|
|
|
e := bnet.NewEndpoint(ip, mac)
|
|
/*
|
|
e.ResolvedCallback = func(e *bnet.Endpoint) {
|
|
tp.Session.Events.Add("endpoint.resolved", e)
|
|
}
|
|
*/
|
|
|
|
if alias, found := tp.Aliases[mac]; found {
|
|
e.Alias = alias
|
|
}
|
|
|
|
tp.Targets[mac] = e
|
|
tp.TTL[mac] = TargetsDefaultTTL
|
|
|
|
tp.Session.Events.Add("endpoint.new", e)
|
|
|
|
return nil
|
|
}
|