new: SNI packet sniffer + sniffer refactoring.

This commit is contained in:
evilsocket 2018-01-10 01:48:41 +01:00
commit 9cdf365b13
5 changed files with 182 additions and 22 deletions

View file

@ -9,28 +9,42 @@ const (
GREEN = "\033[32m"
YELLOW = "\033[33m"
FG_BLACK = "\033[30m"
FG_WHITE = "\033[97m"
BG_DGRAY = "\033[100m"
BG_RED = "\033[41m"
BG_GREEN = "\033[42m"
BG_YELLOW = "\033[43m"
BG_LBLUE = "\033[104m"
RESET = "\033[0m"
)
const ON = GREEN + "✔" + RESET
const OFF = RED + "✘" + RESET
// W for Wrap
func W(e, s string) string {
return e + s + RESET
}
func Bold(s string) string {
return BOLD + s + RESET
return W(BOLD, s)
}
func Dim(s string) string {
return DIM + s + RESET
return W(DIM, s)
}
func Red(s string) string {
return RED + s + RESET
return W(RED, s)
}
func Green(s string) string {
return GREEN + s + RESET
return W(GREEN, s)
}
func Yellow(s string) string {
return YELLOW + s + RESET
return W(YELLOW, s)
}

View file

@ -121,19 +121,9 @@ func (s *Sniffer) onPacketMatched(pkt gopacket.Packet) {
return
}
dumped := false
for _, parser := range PacketParsers {
if parser(pkt) == true {
dumped = true
break
}
if mainParser(pkt) == true {
s.Stats.NumDumped++
}
if dumped == false {
noParser(pkt)
}
s.Stats.NumDumped++
}
func (s *Sniffer) Start() error {

View file

@ -2,15 +2,80 @@ package modules
import (
"fmt"
// "github.com/evilsocket/bettercap-ng/session"
"github.com/evilsocket/bettercap-ng/core"
"github.com/evilsocket/bettercap-ng/log"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
type SnifferPacketParser func(pkt gopacket.Packet) bool
func tcpParser(ip *layers.IPv4, pkt gopacket.Packet) {
tcp := pkt.Layer(layers.LayerTypeTCP).(*layers.TCP)
var PacketParsers = []SnifferPacketParser{}
if sniParser(ip, pkt, tcp) {
return
}
fmt.Printf("[%s] %s %s:%s > %s:%s %s\n",
vTime(pkt.Metadata().Timestamp),
core.W(core.BG_LBLUE+core.FG_BLACK, "tcp"),
vIP(ip.SrcIP),
vPort(tcp.SrcPort),
vIP(ip.DstIP),
vPort(tcp.DstPort),
core.Dim(fmt.Sprintf("%d bytes", len(ip.Payload))))
}
func udpParser(ip *layers.IPv4, pkt gopacket.Packet) {
udp := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP)
fmt.Printf("[%s] %s %s:%s > %s:%s %s\n",
vTime(pkt.Metadata().Timestamp),
core.W(core.BG_DGRAY+core.FG_WHITE, "udp"),
vIP(ip.SrcIP),
vPort(udp.SrcPort),
vIP(ip.DstIP),
vPort(udp.DstPort),
core.Dim(fmt.Sprintf("%d bytes", len(ip.Payload))))
}
func unkParser(ip *layers.IPv4, pkt gopacket.Packet) {
fmt.Printf("[%s] [%s] %s > %s (%d bytes)\n",
vTime(pkt.Metadata().Timestamp),
pkt.TransportLayer().LayerType(),
vIP(ip.SrcIP),
vIP(ip.DstIP),
len(ip.Payload))
}
func mainParser(pkt gopacket.Packet) bool {
nlayer := pkt.NetworkLayer()
if nlayer == nil {
log.Warning("Missing network layer skipping packet.")
return false
}
if nlayer.LayerType() != layers.LayerTypeIPv4 {
log.Warning("Unexpected layer type %s, skipping packet.", nlayer.LayerType())
return false
}
ip := nlayer.(*layers.IPv4)
tlayer := pkt.TransportLayer()
if tlayer == nil {
log.Warning("Missing transport layer skipping packet.")
return false
}
if tlayer.LayerType() == layers.LayerTypeTCP {
tcpParser(ip, pkt)
} else if tlayer.LayerType() == layers.LayerTypeUDP {
udpParser(ip, pkt)
} else {
unkParser(ip, pkt)
}
func noParser(pkt gopacket.Packet) bool {
fmt.Println(pkt.Dump())
return true
}

41
modules/net_sniff_sni.go Normal file
View file

@ -0,0 +1,41 @@
package modules
import (
"fmt"
"github.com/evilsocket/bettercap-ng/core"
"regexp"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
// 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 {
data := tcp.Payload
dataSize := len(data)
if dataSize < 2 || data[0] != 0x16 || data[1] != 0x03 {
return false
}
m := sniRe.FindSubmatch(data)
if len(m) < 2 {
return false
}
domain := string(m[1])
if tcp.DstPort != 443 {
domain = fmt.Sprintf("%s:%d", domain, tcp.DstPort)
}
fmt.Printf("[%s] %s %s > %s\n",
vTime(pkt.Metadata().Timestamp),
core.W(core.BG_YELLOW+core.FG_WHITE, "sni"),
vIP(ip.SrcIP),
core.Yellow("https://"+domain))
return true
}

View file

@ -0,0 +1,50 @@
package modules
import (
"fmt"
"net"
"time"
"github.com/google/gopacket/layers"
"github.com/evilsocket/bettercap-ng/core"
"github.com/evilsocket/bettercap-ng/session"
)
func vTime(t time.Time) string {
return t.Format("15:04:05")
}
func vIP(ip net.IP) string {
if session.I.Interface.IP.Equal(ip) {
return core.Dim("-")
} else if session.I.Gateway.IP.Equal(ip) {
return "gateway"
}
address := ip.String()
host, found := session.I.Targets.Targets[address]
if found == true {
if host.Hostname != "" {
return host.Hostname
}
}
return address
}
func vPort(p interface{}) string {
sp := fmt.Sprintf("%d", p)
if tcp, ok := p.(layers.TCPPort); ok {
if name, found := layers.TCPPortNames[tcp]; found {
sp = core.Yellow(name)
}
} else if udp, ok := p.(layers.UDPPort); ok {
if name, found := layers.UDPPortNames[udp]; found {
sp = core.Yellow(name)
}
}
return sp
}