Commit d9e24fa0 authored by Sophie Brun's avatar Sophie Brun

Update upstream source from tag 'upstream/2.12'

Update to upstream version '2.12'
with Debian dir d96648b2486bd6d0c3130f10b494579c3abe4e1b
parents 93f41318 4e474cb6
......@@ -11,7 +11,7 @@
[[projects]]
branch = "master"
digest = "1:d8ad15f83381fd0e1f6b75c55a3fa3c7070628dbf120a96725183d30dbb0cec9"
digest = "1:3bcf2d2ba964956de427fd779902ad115e564ce1d21033a01e97d8cb0947da40"
name = "github.com/bettercap/gatt"
packages = [
".",
......@@ -24,7 +24,7 @@
"xpc",
]
pruneopts = "UT"
revision = "66e7446993acb3de936b3f487e5933522ed16923"
revision = "7650429b6f92880240174d048f14d0762ca4dfcd"
[[projects]]
digest = "1:b95738a1e6ace058b5b8544303c0871fc01d224ef0d672f778f696265d0f2917"
......@@ -52,11 +52,11 @@
[[projects]]
branch = "master"
digest = "1:7dc5d77e0d21759f0ba62f928f15519c961eee6a4ada94558d94094ccd792faa"
digest = "1:f77360df85b686035d0bff3b3988b29eb7ce415328e37e82cc5ec8439822911c"
name = "github.com/elazarl/goproxy"
packages = ["."]
pruneopts = "UT"
revision = "f58a169a71a51037728990b2d3597a14f56b525b"
revision = "2ce16c963a8ac5bd6af851d4877e38701346983f"
[[projects]]
digest = "1:495dc25bbfe6025e945e3efe885801fc1aefc33d835cac453c0e36a35693d839"
......@@ -71,8 +71,8 @@
"zip",
]
pruneopts = "UT"
revision = "3d8400c74f9dbc626d913e0575cda05d914bea57"
version = "v1.9.1"
revision = "05aa0b30334a79a11bc2072179722d6de727490e"
version = "v1.9.2"
[[projects]]
branch = "master"
......@@ -185,7 +185,7 @@
[[projects]]
branch = "master"
digest = "1:a55df695568f48d84d2b5c3d250871bb9f74d9950c201190b6615a4f94727e3c"
digest = "1:0e2c7e1de0daaa759dac2b7feb90fdc944f1d23a6e0c8c20502cb635bcd2aaba"
name = "github.com/mdlayher/dhcp6"
packages = [
".",
......@@ -193,15 +193,15 @@
"internal/buffer",
]
pruneopts = "UT"
revision = "e26af0688e455a82b14ebdbecf43f87ead3c4624"
revision = "775147d26a880f77f6e06d1a28fbeb2ec4fec013"
[[projects]]
branch = "master"
digest = "1:6569c2877d56f921a8a459d182af16b700c0e588c94b9938aef0d15d13d596db"
digest = "1:450f3a64f7a76d3f229ff33a30f0a889629dde46b0f82ece7c53404528316665"
name = "github.com/mdlayher/raw"
packages = ["."]
pruneopts = "UT"
revision = "67a536258490ec29bca6d465b51dea32c0db3623"
revision = "fa5ef3332ca961deab5782da07b1616fea8a9dd8"
[[projects]]
branch = "master"
......@@ -220,12 +220,12 @@
version = "v1"
[[projects]]
digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = "UT"
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
version = "v0.8.1"
[[projects]]
branch = "master"
......@@ -257,15 +257,15 @@
name = "golang.org/x/net"
packages = ["bpf"]
pruneopts = "UT"
revision = "49bb7cea24b1df9410e1712aa6433dae904ff66a"
revision = "915654e7eabcea33ae277abbecf52f0d8b7a9fdc"
[[projects]]
branch = "master"
digest = "1:0a40b0bdd57a93e741d8557465be3a2edeec408e9b6399586ad65bbe8e355796"
digest = "1:f6f6d9d6f80c9e32acc0f4f3b904e0b9f5b18a7757c2ef941121bd79a10e7bdf"
name = "golang.org/x/sys"
packages = ["unix"]
pruneopts = "UT"
revision = "fa43e7bc11baaae89f3f902b2b4d832b68234844"
revision = "11f53e03133963fb11ae0588e08b5e0b85be8be5"
[[projects]]
digest = "1:9935525a8c49b8434a0b0a54e1980e94a6fae73aaff45c5d33ba8dff69de123e"
......
......@@ -2,7 +2,7 @@ package core
const (
Name = "bettercap"
Version = "2.11.1"
Version = "2.12"
Author = "Simone 'evilsocket' Margaritelli"
Website = "https://bettercap.org/"
)
......@@ -162,7 +162,7 @@ func (p *ArpSpoofer) unSpoof() error {
neighbours := list.Expand()
for _, address := range neighbours {
if !p.Session.Skip(address) {
if realMAC, err := findMAC(p.Session, address, false); err == nil {
if realMAC, err := p.Session.FindMAC(address, false); err == nil {
p.sendArp(address, realMAC, false, false)
}
}
......@@ -209,7 +209,7 @@ func (p *ArpSpoofer) sendArp(saddr net.IP, smac net.HardwareAddr, check_running
}
// do we have this ip mac address?
hw, err := findMAC(p.Session, ip, probe)
hw, err := p.Session.FindMAC(ip, probe)
if err != nil {
log.Debug("Could not find hardware address for %s, retrying in one second.", ip.String())
continue
......
......@@ -240,20 +240,23 @@ func (s *EventsStream) Start() error {
func (s *EventsStream) Show(limit int) error {
events := s.Session.Events.Sorted()
num := len(events)
from := 0
if limit > 0 && num > limit {
from = num - limit
selected := []session.Event{}
for i := range events {
e := events[num-1-i]
if !s.ignoreList.Ignored(e) {
selected = append(selected, e)
if len(selected) == limit {
break
}
}
}
selected := events[from:num]
if len(selected) > 0 {
if numSelected := len(selected); numSelected > 0 {
fmt.Println()
for _, e := range selected {
s.View(e, false)
for i := range selected {
s.View(selected[numSelected-1-i], false)
}
s.Session.Refresh()
}
......
......@@ -300,11 +300,11 @@ func (s *SSLStripper) Process(res *http.Response, ctx *goproxy.ProxyCtx) {
// are we getting redirected from http to https?
if orig.Scheme == "http" && location.Scheme == "https" {
log.Info("[%s] Got redirection from HTTPS to HTTP: %s -> %s", tui.Green("sslstrip"), tui.Yellow("http://"+origHost), tui.Bold("https://"+newHost))
log.Info("[%s] Got redirection from HTTP to HTTPS: %s -> %s", tui.Green("sslstrip"), tui.Yellow("http://"+origHost), tui.Bold("https://"+newHost))
// if we still did not reach max redirections, strip the URL down to
// an alternative HTTP version
if s.isMaxRedirs(origHost) {
if !s.isMaxRedirs(origHost) {
strippedURL := s.processURL(newURL)
u, _ := url.Parse(strippedURL)
hostStripped := u.Hostname()
......
......@@ -5,82 +5,127 @@ import (
"net"
"strconv"
"sync"
"sync/atomic"
"time"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/bettercap/bettercap/session"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/malfunkt/iprange"
"github.com/evilsocket/islazy/str"
"github.com/evilsocket/islazy/tui"
)
const synSourcePort = 666
type synScannerStats struct {
started time.Time
numPorts uint64
numAddresses uint64
totProbes uint64
doneProbes uint64
openPorts uint64
}
type SynScanner struct {
session.SessionModule
addresses []net.IP
startPort int
endPort int
waitGroup *sync.WaitGroup
addresses []net.IP
startPort int
endPort int
progressEvery time.Duration
stats synScannerStats
waitGroup *sync.WaitGroup
}
func NewSynScanner(s *session.Session) *SynScanner {
ss := &SynScanner{
SessionModule: session.NewSessionModule("syn.scan", s),
addresses: make([]net.IP, 0),
startPort: 0,
endPort: 0,
waitGroup: &sync.WaitGroup{},
progressEvery: time.Duration(1) * time.Second,
}
ss.AddParam(session.NewIntParameter("syn.scan.show-progress-every",
"1",
"Period in seconds for the scanning progress reporting."))
ss.AddHandler(session.NewModuleHandler("syn.scan stop", "syn\\.scan (stop|off)",
"Stop the current syn scanning session.",
func(args []string) error {
if !ss.Running() {
return fmt.Errorf("no syn.scan is running")
}
return ss.Stop()
}))
ss.AddHandler(session.NewModuleHandler("syn.scan IP-RANGE [START-PORT] [END-PORT]", "syn.scan ([^\\s]+) ?(\\d+)?([\\s\\d]*)?",
"Perform a syn port scanning against an IP address within the provided ports range.",
func(args []string) error {
period := 0
if ss.Running() {
return fmt.Errorf("A scan is already running, wait for it to end before starting a new one.")
} else if err := ss.parseTargets(args[0]); err != nil {
return err
} else if err = ss.parsePorts(args); err != nil {
return err
} else if err, period = ss.IntParam("syn.scan.show-progress-every"); err != nil {
return err
} else {
ss.progressEvery = time.Duration(period) * time.Second
}
return ss.synScan()
}))
list, err := iprange.Parse(args[0])
if err != nil {
return fmt.Errorf("Error while parsing IP range '%s': %s", args[0], err)
ss.AddHandler(session.NewModuleHandler("syn.scan.progress", "syn\\.scan\\.progress",
"Print progress of the current syn scanning session.",
func(args []string) error {
if !ss.Running() {
return fmt.Errorf("no syn.scan is running")
}
return ss.showProgress()
}))
argc := len(args)
ss.addresses = list.Expand()
ss.startPort = 1
ss.endPort = 65535
if argc > 1 && str.Trim(args[1]) != "" {
if ss.startPort, err = strconv.Atoi(str.Trim(args[1])); err != nil {
return fmt.Errorf("Invalid START-PORT: %s", err)
}
return ss
}
if ss.startPort > 65535 {
ss.startPort = 65535
}
ss.endPort = ss.startPort
}
func (s *SynScanner) parseTargets(arg string) error {
if list, err := iprange.Parse(arg); err != nil {
return fmt.Errorf("error while parsing IP range '%s': %s", arg, err)
} else {
s.addresses = list.Expand()
}
return nil
}
if argc > 2 && str.Trim(args[2]) != "" {
if ss.endPort, err = strconv.Atoi(str.Trim(args[2])); err != nil {
return fmt.Errorf("Invalid END-PORT: %s", err)
}
}
func (s *SynScanner) parsePorts(args []string) (err error) {
argc := len(args)
s.stats.totProbes = 0
s.stats.doneProbes = 0
s.startPort = 1
s.endPort = 65535
if argc > 1 && str.Trim(args[1]) != "" {
if s.startPort, err = strconv.Atoi(str.Trim(args[1])); err != nil {
return fmt.Errorf("invalid start port %s: %s", args[1], err)
} else if s.startPort > 65535 {
s.startPort = 65535
}
s.endPort = s.startPort
}
if ss.endPort < ss.startPort {
return fmt.Errorf("END-PORT is greater than START-PORT")
}
if argc > 2 && str.Trim(args[2]) != "" {
if s.endPort, err = strconv.Atoi(str.Trim(args[2])); err != nil {
return fmt.Errorf("invalid end port %s: %s", args[2], err)
}
}
return ss.synScan()
}))
if s.endPort < s.startPort {
return fmt.Errorf("end port %d is greater than start port %d", s.endPort, s.startPort)
}
return ss
return
}
func (s *SynScanner) Name() string {
......@@ -103,53 +148,34 @@ func (s *SynScanner) Start() error {
return nil
}
func (s *SynScanner) inRange(ip net.IP) bool {
for _, a := range s.addresses {
if a.Equal(ip) {
return true
}
func plural(n uint64) string {
if n > 1 {
return "s"
}
return false
return ""
}
func (s *SynScanner) onPacket(pkt gopacket.Packet) {
var eth layers.Ethernet
var ip layers.IPv4
var tcp layers.TCP
foundLayerTypes := []gopacket.LayerType{}
parser := gopacket.NewDecodingLayerParser(
layers.LayerTypeEthernet,
&eth,
&ip,
&tcp,
)
err := parser.DecodeLayers(pkt.Data(), &foundLayerTypes)
if err != nil {
return
}
if s.inRange(ip.SrcIP) && tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK {
from := ip.SrcIP.String()
port := int(tcp.SrcPort)
var host *network.Endpoint
if ip.SrcIP.Equal(s.Session.Interface.IP) {
host = s.Session.Interface
} else if ip.SrcIP.Equal(s.Session.Gateway.IP) {
host = s.Session.Gateway
} else {
host = s.Session.Lan.GetByIp(from)
}
if host != nil {
ports := host.Meta.GetIntsWith("tcp-ports", port, true)
host.Meta.SetInts("tcp-ports", ports)
}
func (s *SynScanner) showProgress() error {
progress := 100.0 * (float64(s.stats.doneProbes) / float64(s.stats.totProbes))
log.Info("[%s] [%.2f%%] found %d open port%s for %d address%s, sent %d/%d packets in %s",
tui.Green("syn.scan"),
progress,
s.stats.openPorts,
plural(s.stats.openPorts),
s.stats.numAddresses,
plural(s.stats.numAddresses),
s.stats.doneProbes,
s.stats.totProbes,
time.Since(s.stats.started))
return nil
}
NewSynScanEvent(from, host, port).Push()
}
func (s *SynScanner) Stop() error {
log.Info("[%s] stopping ...", tui.Green("syn.scan"))
return s.SetRunning(false, func() {
s.waitGroup.Wait()
s.showProgress()
})
}
func (s *SynScanner) synScan() error {
......@@ -159,29 +185,47 @@ func (s *SynScanner) synScan() error {
s.waitGroup.Add(1)
defer s.waitGroup.Done()
naddrs := len(s.addresses)
s.stats.openPorts = 0
s.stats.numPorts = uint64(s.endPort - s.startPort + 1)
s.stats.started = time.Now()
s.stats.numAddresses = uint64(len(s.addresses))
s.stats.totProbes = s.stats.numAddresses * s.stats.numPorts
s.stats.doneProbes = 0
plural := "es"
if naddrs == 1 {
if s.stats.numAddresses == 1 {
plural = ""
}
if s.startPort != s.endPort {
log.Info("SYN scanning %d address%s from port %d to port %d ...", naddrs, plural, s.startPort, s.endPort)
if s.stats.numPorts > 1 {
log.Info("scanning %d address%s from port %d to port %d ...", s.stats.numAddresses, plural, s.startPort, s.endPort)
} else {
log.Info("SYN scanning %d address%s on port %d ...", naddrs, plural, s.startPort)
log.Info("scanning %d address%s on port %d ...", s.stats.numAddresses, plural, s.startPort)
}
// set the collector
s.Session.Queue.OnPacket(s.onPacket)
defer s.Session.Queue.OnPacket(nil)
// start to show progress every second
go func() {
for {
time.Sleep(s.progressEvery)
if s.Running() {
s.showProgress()
} else {
break
}
}
}()
// start sending SYN packets and wait
for _, address := range s.addresses {
if !s.Running() {
break
}
mac, err := findMAC(s.Session, address, true)
mac, err := s.Session.FindMAC(address, true)
if err != nil {
atomic.AddUint64(&s.stats.doneProbes, s.stats.numPorts)
log.Debug("Could not get MAC for %s: %s", address.String(), err)
continue
}
......@@ -191,6 +235,8 @@ func (s *SynScanner) synScan() error {
break
}
atomic.AddUint64(&s.stats.doneProbes, 1)
err, raw := packets.NewTCPSyn(s.Session.Interface.IP, s.Session.Interface.HW, address, mac, synSourcePort, dstPort)
if err != nil {
log.Error("Error creating SYN packet: %s", err)
......@@ -202,18 +248,11 @@ func (s *SynScanner) synScan() error {
} else {
log.Debug("Sent %d bytes of SYN packet to %s for port %d", len(raw), address.String(), dstPort)
}
time.Sleep(time.Duration(10) * time.Millisecond)
}
}
nports := s.endPort - s.startPort + 1
time.Sleep(time.Duration(nports*500) * time.Millisecond)
})
return nil
}
func (s *SynScanner) Stop() error {
return s.SetRunning(false, func() {
s.waitGroup.Wait()
})
}
package modules
import (
"net"
"sync/atomic"
"github.com/bettercap/bettercap/network"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
func (s *SynScanner) isAddressInRange(ip net.IP) bool {
for _, a := range s.addresses {
if a.Equal(ip) {
return true
}
}
return false
}
func (s *SynScanner) onPacket(pkt gopacket.Packet) {
var eth layers.Ethernet
var ip layers.IPv4
var tcp layers.TCP
foundLayerTypes := []gopacket.LayerType{}
parser := gopacket.NewDecodingLayerParser(
layers.LayerTypeEthernet,
&eth,
&ip,
&tcp,
)
err := parser.DecodeLayers(pkt.Data(), &foundLayerTypes)
if err != nil {
return
}
if s.isAddressInRange(ip.SrcIP) && tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK {
atomic.AddUint64(&s.stats.openPorts, 1)
from := ip.SrcIP.String()
port := int(tcp.SrcPort)
var host *network.Endpoint
if ip.SrcIP.Equal(s.Session.Interface.IP) {
host = s.Session.Interface
} else if ip.SrcIP.Equal(s.Session.Gateway.IP) {
host = s.Session.Gateway
} else {
host = s.Session.Lan.GetByIp(from)
}
if host != nil {
ports := host.Meta.GetIntsWith("tcp-ports", port, true)
host.Meta.SetInts("tcp-ports", ports)
}
NewSynScanEvent(from, host, port).Push()
}
}
package modules
import (
"fmt"
"net"
"time"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/bettercap/bettercap/session"
)
func findMAC(s *session.Session, ip net.IP, probe bool) (net.HardwareAddr, error) {
var mac string
var hw net.HardwareAddr
var err error
// do we have this ip mac address?
mac, err = network.ArpLookup(s.Interface.Name(), ip.String(), false)
if err != nil && probe {
from := s.Interface.IP
from_hw := s.Interface.HW
if err, probe := packets.NewUDPProbe(from, from_hw, ip, 139); err != nil {
log.Error("Error while creating UDP probe packet for %s: %s", ip.String(), err)
} else {
s.Queue.Send(probe)
}
time.Sleep(500 * time.Millisecond)
mac, _ = network.ArpLookup(s.Interface.Name(), ip.String(), false)
}
if mac == "" {
return nil, fmt.Errorf("Could not find hardware address for %s.", ip.String())
}
mac = network.NormalizeMac(mac)
hw, err = net.ParseMAC(mac)
if err != nil {
return nil, fmt.Errorf("Error while parsing hardware address '%s' for %s: %s", mac, ip.String(), err)
}
return hw, nil
}
......@@ -33,6 +33,8 @@ type WiFiModule struct {
skipBroken bool
pktSourceChan chan gopacket.Packet
pktSourceChanClosed bool
deauthSkip []net.HardwareAddr
deauthSilent bool
apRunning bool
apConfig packets.Dot11ApConfig