mirror of
https://github.com/bettercap/bettercap
synced 2025-07-07 21:42:06 -07:00
new: grabbing meta info from mDNS TXT records
This commit is contained in:
parent
3789b21ba1
commit
798df7e32f
4 changed files with 51 additions and 8 deletions
|
@ -89,10 +89,11 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) []string {
|
||||||
if withMeta {
|
if withMeta {
|
||||||
metas := []string{}
|
metas := []string{}
|
||||||
e.Meta.Each(func(name string, value interface{}) {
|
e.Meta.Each(func(name string, value interface{}) {
|
||||||
metas = append(metas, fmt.Sprintf("%s: %s", name, value.(string)))
|
metas = append(metas, fmt.Sprintf("%s=%s", core.Bold(name), core.Yellow(value.(string))))
|
||||||
})
|
})
|
||||||
|
|
||||||
row = append(row, strings.Join(metas, "\n"))
|
sort.Strings(metas)
|
||||||
|
row = append(row, strings.Join(metas, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
return row
|
return row
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package packets
|
package packets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/core"
|
||||||
|
|
||||||
"github.com/google/gopacket"
|
"github.com/google/gopacket"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
|
|
||||||
|
@ -9,6 +13,33 @@ import (
|
||||||
|
|
||||||
const MDNSPort = 5353
|
const MDNSPort = 5353
|
||||||
|
|
||||||
|
func MDNSGetMeta(pkt gopacket.Packet) map[string]string {
|
||||||
|
if ludp := pkt.Layer(layers.LayerTypeUDP); ludp != nil {
|
||||||
|
if udp := ludp.(*layers.UDP); udp != nil && udp.SrcPort == MDNSPort && udp.DstPort == MDNSPort {
|
||||||
|
var msg dns.Msg
|
||||||
|
if err := msg.Unpack(udp.Payload); err == nil && msg.Opcode == dns.OpcodeQuery && len(msg.Answer) > 0 {
|
||||||
|
for _, answer := range append(msg.Answer, msg.Extra...) {
|
||||||
|
switch answer.(type) {
|
||||||
|
case *dns.TXT:
|
||||||
|
meta := make(map[string]string)
|
||||||
|
txt := answer.(*dns.TXT)
|
||||||
|
for _, value := range txt.Txt {
|
||||||
|
if strings.Contains(value, "=") {
|
||||||
|
parts := strings.SplitN(value, "=", 2)
|
||||||
|
meta[core.Trim(parts[0])] = core.Trim(parts[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(meta) > 0 {
|
||||||
|
return meta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func MDNSGetHostname(pkt gopacket.Packet) string {
|
func MDNSGetHostname(pkt gopacket.Packet) string {
|
||||||
if ludp := pkt.Layer(layers.LayerTypeUDP); ludp != nil {
|
if ludp := pkt.Layer(layers.LayerTypeUDP); ludp != nil {
|
||||||
if udp := ludp.(*layers.UDP); udp != nil && udp.SrcPort == MDNSPort && udp.DstPort == MDNSPort {
|
if udp := ludp.(*layers.UDP); udp != nil && udp.SrcPort == MDNSPort && udp.DstPort == MDNSPort {
|
||||||
|
|
|
@ -16,6 +16,7 @@ type Activity struct {
|
||||||
IP net.IP
|
IP net.IP
|
||||||
MAC net.HardwareAddr
|
MAC net.HardwareAddr
|
||||||
Hostname string
|
Hostname string
|
||||||
|
Meta map[string]string
|
||||||
Source bool
|
Source bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,12 +114,13 @@ func (q *Queue) trackProtocols(pkt gopacket.Packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queue) trackActivity(eth *layers.Ethernet, ip4 *layers.IPv4, address net.IP, hostname string, pktSize uint64, isSent bool) {
|
func (q *Queue) trackActivity(eth *layers.Ethernet, ip4 *layers.IPv4, address net.IP, hostname string, meta map[string]string, pktSize uint64, isSent bool) {
|
||||||
// push to activity channel
|
// push to activity channel
|
||||||
q.Activities <- Activity{
|
q.Activities <- Activity{
|
||||||
IP: address,
|
IP: address,
|
||||||
MAC: eth.SrcMAC,
|
MAC: eth.SrcMAC,
|
||||||
Hostname: hostname,
|
Hostname: hostname,
|
||||||
|
Meta: meta,
|
||||||
Source: isSent,
|
Source: isSent,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,17 +194,19 @@ func (q *Queue) worker() {
|
||||||
isFromMe := q.iface.IP.Equal(ip4.SrcIP)
|
isFromMe := q.iface.IP.Equal(ip4.SrcIP)
|
||||||
isFromLAN := q.iface.Net.Contains(ip4.SrcIP)
|
isFromLAN := q.iface.Net.Contains(ip4.SrcIP)
|
||||||
if !isFromMe && isFromLAN {
|
if !isFromMe && isFromLAN {
|
||||||
// check if the packet is a useful MDNS query response
|
// check if the packet is a useful mDNS query response
|
||||||
hostname := MDNSGetHostname(pkt)
|
hostname := MDNSGetHostname(pkt)
|
||||||
|
// check if we can get some meta info from mDNS TXT records
|
||||||
|
meta := MDNSGetMeta(pkt)
|
||||||
|
|
||||||
q.trackActivity(eth, ip4, ip4.SrcIP, hostname, pktSize, true)
|
q.trackActivity(eth, ip4, ip4.SrcIP, hostname, meta, pktSize, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// something going to someone on the LAN
|
// something going to someone on the LAN
|
||||||
isToMe := q.iface.IP.Equal(ip4.DstIP)
|
isToMe := q.iface.IP.Equal(ip4.DstIP)
|
||||||
isToLAN := q.iface.Net.Contains(ip4.DstIP)
|
isToLAN := q.iface.Net.Contains(ip4.DstIP)
|
||||||
if !isToMe && isToLAN {
|
if !isToMe && isToLAN {
|
||||||
q.trackActivity(eth, ip4, ip4.DstIP, "", pktSize, false)
|
q.trackActivity(eth, ip4, ip4.DstIP, "", nil, pktSize, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,9 +94,16 @@ func (s *Session) startNetMon() {
|
||||||
existing, _ = s.Lan.Get(mac)
|
existing, _ = s.Lan.Get(mac)
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing != nil && existing.Hostname == "" && event.Hostname != "" {
|
if existing != nil {
|
||||||
|
if existing.Hostname == "" && event.Hostname != "" {
|
||||||
existing.Hostname = event.Hostname
|
existing.Hostname = event.Hostname
|
||||||
}
|
}
|
||||||
|
if event.Meta != nil {
|
||||||
|
for k, v := range event.Meta {
|
||||||
|
existing.Meta.Set(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue