new: net.sniff now supports ipv6

This commit is contained in:
Simone Margaritelli 2021-04-03 19:20:12 +02:00
commit cbc1432358
13 changed files with 122 additions and 83 deletions

View file

@ -128,12 +128,20 @@ func (mod Sniffer) Author() string {
}
func (mod Sniffer) isLocalPacket(packet gopacket.Packet) bool {
ipl := packet.Layer(layers.LayerTypeIPv4)
if ipl != nil {
ip, _ := ipl.(*layers.IPv4)
if ip.SrcIP.Equal(mod.Session.Interface.IP) || ip.DstIP.Equal(mod.Session.Interface.IP) {
ip4l := packet.Layer(layers.LayerTypeIPv4)
if ip4l != nil {
ip4, _ := ip4l.(*layers.IPv4)
if ip4.SrcIP.Equal(mod.Session.Interface.IP) || ip4.DstIP.Equal(mod.Session.Interface.IP) {
return true
}
} else {
ip6l := packet.Layer(layers.LayerTypeIPv6)
if ip6l != nil {
ip6, _ := ip6l.(*layers.IPv6)
if ip6.SrcIP.Equal(mod.Session.Interface.IPv6) || ip6.DstIP.Equal(mod.Session.Interface.IPv6) {
return true
}
}
}
return false
}

View file

@ -3,12 +3,13 @@ package net_sniff
import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"net"
"strings"
"github.com/evilsocket/islazy/tui"
)
func dnsParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
func dnsParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, udp *layers.UDP) bool {
dns, parsed := pkt.Layer(layers.LayerTypeDNS).(*layers.DNS)
if !parsed {
return false
@ -50,13 +51,13 @@ func dnsParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"dns",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s > %s : %s is %s",
tui.Wrap(tui.BACKDARKGRAY+tui.FOREWHITE, "dns"),
vIP(ip.SrcIP),
vIP(ip.DstIP),
vIP(srcIP),
vIP(dstIP),
tui.Yellow(hostname),
tui.Dim(strings.Join(ips, ", ")),
).Push()

View file

@ -1,6 +1,7 @@
package net_sniff
import (
"net"
"regexp"
"github.com/google/gopacket"
@ -14,7 +15,7 @@ var (
ftpRe = regexp.MustCompile(`^(USER|PASS) (.+)[\n\r]+$`)
)
func ftpParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
func ftpParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, tcp *layers.TCP) bool {
data := string(tcp.Payload)
if matches := ftpRe.FindAllStringSubmatch(data, -1); matches != nil {
@ -23,13 +24,13 @@ func ftpParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"ftp",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s > %s:%s - %s %s",
tui.Wrap(tui.BACKYELLOW+tui.FOREWHITE, "ftp"),
vIP(ip.SrcIP),
vIP(ip.DstIP),
vIP(srcIP),
vIP(dstIP),
vPort(tcp.DstPort),
tui.Bold(what),
tui.Yellow(cred),

View file

@ -5,6 +5,7 @@ import (
"bytes"
"compress/gzip"
"io/ioutil"
"net"
"net/http"
"strings"
@ -116,19 +117,19 @@ func toSerializableResponse(res *http.Response) HTTPResponse {
}
}
func httpParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
func httpParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, tcp *layers.TCP) bool {
data := tcp.Payload
if req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(data))); err == nil {
if user, pass, ok := req.BasicAuth(); ok {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"http.request",
ip.SrcIP.String(),
srcIP.String(),
req.Host,
toSerializableRequest(req),
"%s %s %s %s%s - %s %s, %s %s",
tui.Wrap(tui.BACKRED+tui.FOREBLACK, "http"),
vIP(ip.SrcIP),
vIP(srcIP),
tui.Wrap(tui.BACKLIGHTBLUE+tui.FOREBLACK, req.Method),
tui.Yellow(req.Host),
vURL(req.URL.String()),
@ -141,12 +142,12 @@ func httpParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"http.request",
ip.SrcIP.String(),
srcIP.String(),
req.Host,
toSerializableRequest(req),
"%s %s %s %s%s",
tui.Wrap(tui.BACKRED+tui.FOREBLACK, "http"),
vIP(ip.SrcIP),
vIP(srcIP),
tui.Wrap(tui.BACKLIGHTBLUE+tui.FOREBLACK, req.Method),
tui.Yellow(req.Host),
vURL(req.URL.String()),
@ -159,15 +160,15 @@ func httpParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"http.response",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
sres,
"%s %s:%d %s -> %s (%s %s)",
tui.Wrap(tui.BACKRED+tui.FOREBLACK, "http"),
vIP(ip.SrcIP),
vIP(srcIP),
tcp.SrcPort,
tui.Bold(res.Status),
vIP(ip.DstIP),
vIP(dstIP),
tui.Dim(humanize.Bytes(uint64(len(sres.Body)))),
tui.Yellow(sres.ContentType),
).Push()

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"encoding/asn1"
"net"
"github.com/bettercap/bettercap/packets"
@ -11,7 +12,7 @@ import (
"github.com/evilsocket/islazy/tui"
)
func krb5Parser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
func krb5Parser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, udp *layers.UDP) bool {
if udp.DstPort != 88 {
return false
}
@ -26,13 +27,13 @@ func krb5Parser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"krb5",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s -> %s : %s",
tui.Wrap(tui.BACKRED+tui.FOREBLACK, "krb-as-req"),
vIP(ip.SrcIP),
vIP(ip.DstIP),
vIP(srcIP),
vIP(dstIP),
s,
).Push()

View file

@ -1,6 +1,7 @@
package net_sniff
import (
"net"
"strings"
"github.com/bettercap/bettercap/packets"
@ -12,7 +13,7 @@ import (
"github.com/evilsocket/islazy/tui"
)
func mdnsParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
func mdnsParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, udp *layers.UDP) bool {
if udp.SrcPort == packets.MDNSPort && udp.DstPort == packets.MDNSPort {
dns := layers.DNS{}
if err := dns.DecodeFromBytes(udp.Payload, gopacket.NilDecodeFeedback); err == nil && dns.OpCode == layers.DNSOpCodeQuery {
@ -20,12 +21,12 @@ func mdnsParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"mdns",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s : %s query for %s",
tui.Wrap(tui.BACKDARKGRAY+tui.FOREWHITE, "mdns"),
vIP(ip.SrcIP),
vIP(srcIP),
tui.Dim(q.Type.String()),
tui.Yellow(string(q.Name)),
).Push()
@ -56,12 +57,12 @@ func mdnsParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"mdns",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s : %s is %s",
tui.Wrap(tui.BACKDARKGRAY+tui.FOREWHITE, "mdns"),
vIP(ip.SrcIP),
vIP(srcIP),
tui.Yellow(hostname),
tui.Dim(strings.Join(ips, ", ")),
).Push()

View file

@ -1,6 +1,7 @@
package net_sniff
import (
"net"
"regexp"
"strings"
@ -31,7 +32,7 @@ func isResponse(s string) bool {
return respRe.FindString(s) != ""
}
func ntlmParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
func ntlmParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, tcp *layers.TCP) bool {
data := tcp.Payload
ok := false
@ -50,13 +51,13 @@ func ntlmParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"ntlm.response",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s > %s | %s",
tui.Wrap(tui.BACKDARKGRAY+tui.FOREWHITE, "ntlm.response"),
vIP(ip.SrcIP),
vIP(ip.DstIP),
vIP(srcIP),
vIP(dstIP),
data.LcString(),
).Push()
})

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"fmt"
"net"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/packets"
@ -12,21 +13,22 @@ import (
"github.com/evilsocket/islazy/tui"
)
func onUNK(ip *layers.IPv4, pkt gopacket.Packet, verbose bool) {
func onUNK(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, verbose bool) {
if verbose {
sz := len(payload)
NewSnifferEvent(
pkt.Metadata().Timestamp,
pkt.TransportLayer().LayerType().String(),
vIP(ip.SrcIP),
vIP(ip.DstIP),
vIP(srcIP),
vIP(dstIP),
SniffData{
"Size": len(ip.Payload),
"Size": sz,
},
"%s %s > %s %s",
tui.Wrap(tui.BACKDARKGRAY+tui.FOREWHITE, pkt.TransportLayer().LayerType().String()),
vIP(ip.SrcIP),
vIP(ip.DstIP),
tui.Dim(fmt.Sprintf("%d bytes", len(ip.Payload))),
vIP(srcIP),
vIP(dstIP),
tui.Dim(fmt.Sprintf("%d bytes", sz)),
).Push()
}
}
@ -41,13 +43,29 @@ func mainParser(pkt gopacket.Packet, verbose bool) bool {
// simple networking sniffing mode?
nlayer := pkt.NetworkLayer()
if nlayer != nil {
if nlayer.LayerType() != layers.LayerTypeIPv4 {
isIPv4 := nlayer.LayerType() == layers.LayerTypeIPv4
isIPv6 := nlayer.LayerType() == layers.LayerTypeIPv6
if !isIPv4 && !isIPv6 {
log.Debug("Unexpected layer type %s, skipping packet.", nlayer.LayerType())
log.Debug("%s", pkt.Dump())
return false
}
ip := nlayer.(*layers.IPv4)
var srcIP, dstIP net.IP
var basePayload []byte
if isIPv4 {
ip := nlayer.(*layers.IPv4)
srcIP = ip.SrcIP
dstIP = ip.DstIP
basePayload = ip.Payload
} else {
ip := nlayer.(*layers.IPv6)
srcIP = ip.SrcIP
dstIP = ip.DstIP
basePayload = ip.Payload
}
tlayer := pkt.TransportLayer()
if tlayer == nil {
@ -57,11 +75,11 @@ func mainParser(pkt gopacket.Packet, verbose bool) bool {
}
if tlayer.LayerType() == layers.LayerTypeTCP {
onTCP(ip, pkt, verbose)
onTCP(srcIP, dstIP, basePayload, pkt, verbose)
} else if tlayer.LayerType() == layers.LayerTypeUDP {
onUDP(ip, pkt, verbose)
onUDP(srcIP, dstIP, basePayload, pkt, verbose)
} else {
onUNK(ip, pkt, verbose)
onUNK(srcIP, dstIP, basePayload, pkt, verbose)
}
return true
} else if ok, radiotap, dot11 := packets.Dot11Parse(pkt); ok {

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"fmt"
"net"
"regexp"
@ -14,7 +15,7 @@ import (
// poor man's TLS Client Hello with SNI extension parser :P
var sniRe = regexp.MustCompile("\x00\x00.{4}\x00.{2}([a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,6})\x00")
func sniParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
func sniParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, tcp *layers.TCP) bool {
data := tcp.Payload
dataSize := len(data)
@ -35,12 +36,12 @@ func sniParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"https",
ip.SrcIP.String(),
srcIP.String(),
domain,
nil,
"%s %s > %s",
tui.Wrap(tui.BACKYELLOW+tui.FOREWHITE, "sni"),
vIP(ip.SrcIP),
vIP(srcIP),
tui.Yellow("https://"+domain),
).Push()

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"fmt"
"net"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
@ -9,7 +10,7 @@ import (
"github.com/evilsocket/islazy/tui"
)
var tcpParsers = []func(*layers.IPv4, gopacket.Packet, *layers.TCP) bool{
var tcpParsers = []func(net.IP, net.IP, []byte, gopacket.Packet, *layers.TCP) bool{
sniParser,
ntlmParser,
httpParser,
@ -17,30 +18,31 @@ var tcpParsers = []func(*layers.IPv4, gopacket.Packet, *layers.TCP) bool{
teamViewerParser,
}
func onTCP(ip *layers.IPv4, pkt gopacket.Packet, verbose bool) {
func onTCP(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, verbose bool) {
tcp := pkt.Layer(layers.LayerTypeTCP).(*layers.TCP)
for _, parser := range tcpParsers {
if parser(ip, pkt, tcp) {
if parser(srcIP, dstIP, payload, pkt, tcp) {
return
}
}
if verbose {
sz := len(payload)
NewSnifferEvent(
pkt.Metadata().Timestamp,
"tcp",
fmt.Sprintf("%s:%s", ip.SrcIP, vPort(tcp.SrcPort)),
fmt.Sprintf("%s:%s", ip.DstIP, vPort(tcp.DstPort)),
fmt.Sprintf("%s:%s", srcIP, vPort(tcp.SrcPort)),
fmt.Sprintf("%s:%s", dstIP, vPort(tcp.DstPort)),
SniffData{
"Size": len(ip.Payload),
"Size": len(payload),
},
"%s %s:%s > %s:%s %s",
tui.Wrap(tui.BACKLIGHTBLUE+tui.FOREBLACK, "tcp"),
vIP(ip.SrcIP),
vIP(srcIP),
vPort(tcp.SrcPort),
vIP(ip.DstIP),
vIP(dstIP),
vPort(tcp.DstPort),
tui.Dim(fmt.Sprintf("%d bytes", len(ip.Payload))),
tui.Dim(fmt.Sprintf("%d bytes", sz)),
).Push()
}
}

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"github.com/bettercap/bettercap/packets"
"net"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
@ -9,20 +10,20 @@ import (
"github.com/evilsocket/islazy/tui"
)
func teamViewerParser(ip *layers.IPv4, pkt gopacket.Packet, tcp *layers.TCP) bool {
func teamViewerParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, tcp *layers.TCP) bool {
if tcp.SrcPort == packets.TeamViewerPort || tcp.DstPort == packets.TeamViewerPort {
if tv := packets.ParseTeamViewer(tcp.Payload); tv != nil {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"teamviewer",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s %s > %s",
tui.Wrap(tui.BACKYELLOW+tui.FOREWHITE, "teamviewer"),
vIP(ip.SrcIP),
vIP(srcIP),
tui.Yellow(tv.Command),
vIP(ip.DstIP),
vIP(dstIP),
).Push()
return true
}

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"fmt"
"net"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
@ -9,37 +10,38 @@ import (
"github.com/evilsocket/islazy/tui"
)
var udpParsers = []func(*layers.IPv4, gopacket.Packet, *layers.UDP) bool{
var udpParsers = []func(net.IP, net.IP, []byte, gopacket.Packet, *layers.UDP) bool{
dnsParser,
mdnsParser,
krb5Parser,
upnpParser,
}
func onUDP(ip *layers.IPv4, pkt gopacket.Packet, verbose bool) {
func onUDP(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, verbose bool) {
udp := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP)
for _, parser := range udpParsers {
if parser(ip, pkt, udp) {
if parser(srcIP, dstIP, payload, pkt, udp) {
return
}
}
if verbose {
sz := len(payload)
NewSnifferEvent(
pkt.Metadata().Timestamp,
"udp",
fmt.Sprintf("%s:%s", ip.SrcIP, vPort(udp.SrcPort)),
fmt.Sprintf("%s:%s", ip.DstIP, vPort(udp.DstPort)),
fmt.Sprintf("%s:%s", srcIP, vPort(udp.SrcPort)),
fmt.Sprintf("%s:%s", dstIP, vPort(udp.DstPort)),
SniffData{
"Size": len(ip.Payload),
"Size": sz,
},
"%s %s:%s > %s:%s %s",
tui.Wrap(tui.BACKDARKGRAY+tui.FOREWHITE, "udp"),
vIP(ip.SrcIP),
vIP(srcIP),
vPort(udp.SrcPort),
vIP(ip.DstIP),
vIP(dstIP),
vPort(udp.DstPort),
tui.Dim(fmt.Sprintf("%d bytes", len(ip.Payload))),
tui.Dim(fmt.Sprintf("%d bytes", sz)),
).Push()
}
}

View file

@ -2,6 +2,7 @@ package net_sniff
import (
"fmt"
"net"
"github.com/bettercap/bettercap/packets"
@ -12,7 +13,7 @@ import (
"github.com/evilsocket/islazy/tui"
)
func upnpParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
func upnpParser(srcIP, dstIP net.IP, payload []byte, pkt gopacket.Packet, udp *layers.UDP) bool {
if data := packets.UPNPGetMeta(pkt); len(data) > 0 {
s := ""
for name, value := range data {
@ -22,13 +23,13 @@ func upnpParser(ip *layers.IPv4, pkt gopacket.Packet, udp *layers.UDP) bool {
NewSnifferEvent(
pkt.Metadata().Timestamp,
"upnp",
ip.SrcIP.String(),
ip.DstIP.String(),
srcIP.String(),
dstIP.String(),
nil,
"%s %s -> %s : %s",
tui.Wrap(tui.BACKRED+tui.FOREBLACK, "upnp"),
vIP(ip.SrcIP),
vIP(ip.DstIP),
vIP(srcIP),
vIP(dstIP),
str.Trim(s),
).Push()