This commit is contained in:
Krzysiekk310895 2022-08-10 01:32:42 +00:00 committed by GitHub
commit 15ce350767
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 785 additions and 512 deletions

View file

@ -83,6 +83,7 @@ matrix:
- name: OSX - amd64
if: tag IS present
os: osx
osx_image: xcode12.5
arch: amd64
addons:
homebrew:
@ -142,6 +143,7 @@ matrix:
- name: OSX - tests
if: tag IS blank
os: osx
osx_image: xcode12.5
arch: amd64
allow_failures:
- go: master

View file

@ -3,8 +3,8 @@ FROM golang:alpine AS build-env
ENV SRC_DIR $GOPATH/src/github.com/bettercap/bettercap
RUN apk add --update ca-certificates
RUN apk add --no-cache --update bash iptables wireless-tools build-base libpcap-dev libusb-dev linux-headers libnetfilter_queue-dev git
RUN apk add --no-cache ca-certificates
RUN apk add --no-cache bash iptables wireless-tools build-base libpcap-dev libusb-dev linux-headers libnetfilter_queue-dev git
WORKDIR $SRC_DIR
ADD . $SRC_DIR
@ -16,8 +16,8 @@ RUN git clone https://github.com/bettercap/caplets /usr/local/share/bettercap/ca
# final stage
FROM alpine
RUN apk add --update ca-certificates
RUN apk add --no-cache --update bash iproute2 libpcap libusb-dev libnetfilter_queue wireless-tools
RUN apk add --no-cache ca-certificates
RUN apk add --no-cache bash iproute2 libpcap libusb-dev libnetfilter_queue wireless-tools
COPY --from=build-env /go/src/github.com/bettercap/bettercap/bettercap /app/
COPY --from=build-env /usr/local/share/bettercap/caplets /app/
WORKDIR /app

View file

@ -2,15 +2,14 @@ TARGET ?= bettercap
PACKAGES ?= core firewall log modules network packets session tls
PREFIX ?= /usr/local
GO ?= go
GOFLAGS ?=
all: build
build: resources
$(GO) $(GOFLAGS) build -o $(TARGET) .
$(GOFLAGS) $(GO) build -o $(TARGET) .
build_with_race_detector: resources
$(GO) $(GOFLAGS) build -race -o $(TARGET) .
$(GOFLAGS) $(GO) build -race -o $(TARGET) .
resources: network/manuf.go
@ -18,20 +17,20 @@ network/manuf.go:
@python3 ./network/make_manuf.py
install:
@mkdir -p $(PREFIX)/share/bettercap/caplets
@cp bettercap $(PREFIX)/bin/
@mkdir -p $(DESTDIR)$(PREFIX)/share/bettercap/caplets
@cp bettercap $(DESTDIR)$(PREFIX)/bin/
docker:
@docker build -t bettercap:latest .
test:
$(GO) $(GOFLAGS) test -covermode=atomic -coverprofile=cover.out ./...
$(GOFLAGS) $(GO) test -covermode=atomic -coverprofile=cover.out ./...
html_coverage: test
$(GO) $(GOFLAGS) tool cover -html=cover.out -o cover.out.html
$(GOFLAGS) $(GO) tool cover -html=cover.out -o cover.out.html
benchmark: server_deps
$(GO) $(GOFLAGS) test -v -run=doNotRunTests -bench=. -benchmem ./...
$(GOFLAGS) $(GO) test -v -run=doNotRunTests -bench=. -benchmem ./...
fmt:
$(GO) fmt -s -w $(PACKAGES)

View file

@ -2,7 +2,7 @@ package core
const (
Name = "bettercap"
Version = "2.31.0"
Version = "2.32.0"
Author = "Simone 'evilsocket' Margaritelli"
Website = "https://bettercap.org/"
)

View file

@ -41,7 +41,7 @@ func Exec(executable string, args []string) (string, error) {
raw, err := exec.Command(path, args...).CombinedOutput()
if err != nil {
return "", err
return str.Trim(string(raw)), err
} else {
return str.Trim(string(raw)), nil
}

View file

@ -1,13 +1,10 @@
package core
import (
"bytes"
"io"
"os"
"testing"
"github.com/evilsocket/islazy/fs"
"github.com/evilsocket/islazy/str"
)
func hasInt(a []int, v int) bool {
@ -81,85 +78,6 @@ func TestCoreUniqueIntsSorted(t *testing.T) {
}
}
func sameStrings(a []string, b []string) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
func TestCoreExec(t *testing.T) {
var units = []struct {
exec string
args []string
out string
err string
stdout string
}{
{"foo", []string{}, "", `exec: "foo": executable file not found in $PATH`, ""},
{"ps", []string{"-someinvalidflag"}, "", "exit status 1", ""},
{"true", []string{}, "", "", ""},
{"head", []string{"/path/to/file/that/does/not/exist"}, "", "exit status 1", ""},
}
for _, u := range units {
var buf bytes.Buffer
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
gotOut, gotErr := Exec(u.exec, u.args)
w.Close()
io.Copy(&buf, r)
os.Stdout = oldStdout
gotStdout := str.Trim(buf.String())
if gotOut != u.out {
t.Fatalf("expected output '%s', got '%s'", u.out, gotOut)
} else if u.err == "" && gotErr != nil {
t.Fatalf("expected no error, got '%s'", gotErr)
} else if u.err != "" && gotErr == nil {
t.Fatalf("expected error '%s', got none", u.err)
} else if u.err != "" && gotErr != nil && gotErr.Error() != u.err {
t.Fatalf("expected error '%s', got '%s'", u.err, gotErr)
} else if gotStdout != "" {
t.Fatalf("expected empty stdout, got '%s'", gotStdout)
}
}
for _, u := range units {
var buf bytes.Buffer
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
gotOut, gotErr := Exec(u.exec, u.args)
w.Close()
io.Copy(&buf, r)
os.Stdout = oldStdout
gotStdout := str.Trim(buf.String())
if gotOut != u.out {
t.Fatalf("expected output '%s', got '%s'", u.out, gotOut)
} else if u.err == "" && gotErr != nil {
t.Fatalf("expected no error, got '%s'", gotErr)
} else if u.err != "" && gotErr == nil {
t.Fatalf("expected error '%s', got none", u.err)
} else if u.err != "" && gotErr != nil && gotErr.Error() != u.err {
t.Fatalf("expected error '%s', got '%s'", u.err, gotErr)
} else if gotStdout != u.stdout {
t.Fatalf("expected stdout '%s', got '%s'", u.stdout, gotStdout)
}
}
}
func TestCoreExists(t *testing.T) {
var units = []struct {
what string

View file

@ -1,6 +1,8 @@
package core
import "flag"
import (
"flag"
)
type Options struct {
InterfaceName *string
@ -18,6 +20,7 @@ type Options struct {
MemProfile *string
CapletsPath *string
Script *string
PcapBufSize *int
}
func ParseOptions() (Options, error) {
@ -37,6 +40,7 @@ func ParseOptions() (Options, error) {
MemProfile: flag.String("mem-profile", "", "Write memory profile to `file`."),
CapletsPath: flag.String("caplets-path", "", "Specify an alternative base path for caplets."),
Script: flag.String("script", "", "Load a session script."),
PcapBufSize: flag.Int("pcap-buf-size", -1, "PCAP buffer size, leave to 0 for the default value."),
}
flag.Parse()

View file

@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/bettercap/bettercap/core"
"github.com/bettercap/bettercap/network"
@ -73,10 +74,18 @@ func (f LinuxFirewall) EnableForwarding(enabled bool) error {
func (f *LinuxFirewall) getCommandLine(r *Redirection, enabled bool) (cmdLine []string) {
action := "-A"
destination := ""
if !enabled {
action = "-D"
}
if strings.Count(r.DstAddress, ":") < 2 {
destination = r.DstAddress
} else {
destination = fmt.Sprintf("[%s]", r.DstAddress)
}
if r.SrcAddress == "" {
cmdLine = []string{
"-t", "nat",
@ -85,7 +94,7 @@ func (f *LinuxFirewall) getCommandLine(r *Redirection, enabled bool) (cmdLine []
"-p", r.Protocol,
"--dport", fmt.Sprintf("%d", r.SrcPort),
"-j", "DNAT",
"--to", fmt.Sprintf("%s:%d", r.DstAddress, r.DstPort),
"--to", fmt.Sprintf("%s:%d", destination, r.DstPort),
}
} else {
cmdLine = []string{
@ -96,7 +105,7 @@ func (f *LinuxFirewall) getCommandLine(r *Redirection, enabled bool) (cmdLine []
"-d", r.SrcAddress,
"--dport", fmt.Sprintf("%d", r.SrcPort),
"-j", "DNAT",
"--to", fmt.Sprintf("%s:%d", r.DstAddress, r.DstPort),
"--to", fmt.Sprintf("%s:%d", destination, r.DstPort),
}
}
@ -107,6 +116,13 @@ func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error {
cmdLine := f.getCommandLine(r, enabled)
rkey := r.String()
_, found := f.redirections[rkey]
cmd := ""
if strings.Count(r.DstAddress, ":") < 2 {
cmd = "iptables"
} else {
cmd = "ip6tables"
}
if enabled {
if found {
@ -116,9 +132,9 @@ func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error {
f.redirections[rkey] = r
// accept all
if _, err := core.Exec("iptables", []string{"-P", "FORWARD", "ACCEPT"}); err != nil {
if _, err := core.Exec(cmd, []string{"-P", "FORWARD", "ACCEPT"}); err != nil {
return err
} else if _, err := core.Exec("iptables", cmdLine); err != nil {
} else if _, err := core.Exec(cmd, cmdLine); err != nil {
return err
}
} else {
@ -128,7 +144,7 @@ func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error {
delete(f.redirections, r.String())
if _, err := core.Exec("iptables", cmdLine); err != nil {
if _, err := core.Exec(cmd, cmdLine); err != nil {
return err
}
}

35
go.mod
View file

@ -1,13 +1,13 @@
module github.com/bettercap/bettercap
go 1.12
go 1.16
require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/adrianmo/go-nmea v1.3.0
github.com/antchfx/jsonquery v1.1.4
github.com/antchfx/xpath v1.1.11 // indirect
github.com/bettercap/gatt v0.0.0-20210412143611-7a3c1c59fe92
github.com/antchfx/xpath v1.2.0 // indirect
github.com/bettercap/gatt v0.0.0-20210514133428-df6e615f2f67
github.com/bettercap/nrf24 v0.0.0-20190219153547-aa37e6d0e0eb
github.com/bettercap/readline v0.0.0-20210228151553-655e48bcb7bf
github.com/bettercap/recording v0.0.0-20190408083647-3ce1dcf032e3
@ -15,7 +15,7 @@ require (
github.com/chzyer/logex v1.1.10 // indirect
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
github.com/dustin/go-humanize v1.0.0
github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e
github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4
github.com/elazarl/goproxy/ext v0.0.0-20210110162100-a92cc753f88e // indirect
github.com/evilsocket/islazy v1.10.6
github.com/gobwas/glob v0.0.0-20181002190808-e7a84e9525fe
@ -24,34 +24,25 @@ require (
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gopacket v1.1.19
github.com/google/gousb v2.1.0+incompatible
github.com/google/gousb v1.1.2
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.4.2
github.com/hashicorp/mdns v1.0.3
github.com/hashicorp/mdns v1.0.4
github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b
github.com/jpillora/go-tld v1.1.1
github.com/koppacetic/go-gpsd v0.4.0
github.com/kr/binarydist v0.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/malfunkt/iprange v0.9.0
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mdlayher/dhcp6 v0.0.0-20190311162359-2a67805d7d0b
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab // indirect
github.com/miekg/dns v1.1.41
github.com/miekg/dns v1.1.43
github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/errors v0.9.1 // indirect
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac
github.com/stretchr/testify v1.7.0 // indirect
github.com/robertkrimen/otto v0.0.0-20210614181706-373ff5438452
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07
github.com/thoj/go-ircevent v0.0.0-20190807115034-8e7ce4b5a1eb
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
honnef.co/go/tools v0.0.0-2019.2.1 // indirect
)

197
go.sum
View file

@ -1,38 +1,16 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/adrianmo/go-nmea v1.1.0 h1:0NILSj14nj6LvVQHo/afHbyPgGz5qvp5PM6jmMyAQzY=
github.com/adrianmo/go-nmea v1.1.0/go.mod h1:HHPxPAm2kmev+61qmkZh7xgZF/7qHtSpsWppip2Ipv8=
github.com/adrianmo/go-nmea v1.3.0 h1:BFrLRj/oIh+DYujIKpuQievq7X3NDHYq57kNgsfr2GY=
github.com/adrianmo/go-nmea v1.3.0/go.mod h1:u8bPnpKt/D/5rll/5l9f6iDfeq5WZW0+/SXdkwix6Tg=
github.com/antchfx/jsonquery v0.0.0-20180821084212-a2896be8c82b h1:oREWiN8d6BYorETYz2PH2Kk0CtUdp0RETyab7ep4jNY=
github.com/antchfx/jsonquery v0.0.0-20180821084212-a2896be8c82b/go.mod h1:h7950pvPrUZzJIflNqsELgDQovTpPNa0rAHf8NwjegY=
github.com/antchfx/jsonquery v1.0.0 h1:1Yhk496SrCoY6fJkFZqpXEqbwOw5sFtLns9la4NoK3I=
github.com/antchfx/jsonquery v1.0.0/go.mod h1:h7950pvPrUZzJIflNqsELgDQovTpPNa0rAHf8NwjegY=
github.com/antchfx/jsonquery v1.1.4 h1:+OlFO3QS9wjU0MKx9MgHm5f6o6hdd4e9mUTp0wTjxlM=
github.com/antchfx/jsonquery v1.1.4/go.mod h1:cHs8r6Bymd8j6HI6Ej1IJbjahKvLBcIEh54dfmo+E9A=
github.com/antchfx/xpath v1.0.0 h1:Q5gFgh2O40VTSwMOVbFE7nFNRBu3tS21Tn0KAWeEjtk=
github.com/antchfx/xpath v1.0.0/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xpath v1.1.0 h1:mJTvYpiHvxNQRD4Lbfin/FodHVCHh2a5KrOFr4ZxMOI=
github.com/antchfx/xpath v1.1.0/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xpath v1.1.7/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xpath v1.1.10 h1:cJ0pOvEdN/WvYXxvRrzQH9x5QWKpzHacYO8qzCcDYAg=
github.com/antchfx/xpath v1.1.10/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xpath v1.1.11 h1:WOFtK8TVAjLm3lbgqeP0arlHpvCEeTANeWZ/csPpJkQ=
github.com/antchfx/xpath v1.1.11/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/bettercap/gatt v0.0.0-20190418085356-fac16c0ad797 h1:P9DK7Ij21WQAPFTUix8rblTVKDdwJEimCVO5foIr2ik=
github.com/bettercap/gatt v0.0.0-20190418085356-fac16c0ad797/go.mod h1:xbRFD+l8RcbQ3DscCiYX0dgEnXbwozZgm6oP2GXic+0=
github.com/bettercap/gatt v0.0.0-20191018133023-569d3d9372bb h1:GOaknHS3DCZcBbQRScDl6uecgkrkK7YFToIA5Uc6lHU=
github.com/bettercap/gatt v0.0.0-20191018133023-569d3d9372bb/go.mod h1:xbRFD+l8RcbQ3DscCiYX0dgEnXbwozZgm6oP2GXic+0=
github.com/bettercap/gatt v0.0.0-20210323182651-e1a2422767ff h1:P99kfm6Ll1/yNvxAl/j2vF6pDZZnbwG4ThZCIALWEXE=
github.com/bettercap/gatt v0.0.0-20210323182651-e1a2422767ff/go.mod h1:t65axQjKQ5V+fav0omkETW5+OGOOPjV8b7q63/GF79E=
github.com/bettercap/gatt v0.0.0-20210412143611-7a3c1c59fe92 h1:+cZAjtR7zFbFx5/Hoyxm7WKbhAZHvXqFj9C7oYQFj1s=
github.com/bettercap/gatt v0.0.0-20210412143611-7a3c1c59fe92/go.mod h1:oafnPgaBI4gqJiYkueCyR4dqygiWGXTGOE0gmmAVeeQ=
github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8=
github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/bettercap/gatt v0.0.0-20210514133428-df6e615f2f67 h1:xzN6806c01hWTz8gjGsRjhOPlYj5/dNoZIR8CN9+O1c=
github.com/bettercap/gatt v0.0.0-20210514133428-df6e615f2f67/go.mod h1:oafnPgaBI4gqJiYkueCyR4dqygiWGXTGOE0gmmAVeeQ=
github.com/bettercap/nrf24 v0.0.0-20190219153547-aa37e6d0e0eb h1:JWAAJk4ny+bT3VrtcX+e7mcmWtWUeUM0xVcocSAUuWc=
github.com/bettercap/nrf24 v0.0.0-20190219153547-aa37e6d0e0eb/go.mod h1:g6WiaSRgMTiChuk7jYyFSEtpgaw1F0wAsBfspG3bu0M=
github.com/bettercap/readline v0.0.0-20180208083827-9cec905dd291 h1:6GtREdpf6N/trykGvhwfr0nyo3V/yncz0JvNbu+z7S8=
github.com/bettercap/readline v0.0.0-20180208083827-9cec905dd291/go.mod h1:03rWiUf60r1miMVzMEtgtkq7RdZniecZFw3/Zgvyxcs=
github.com/bettercap/readline v0.0.0-20210228151553-655e48bcb7bf h1:pwGPRc5PIp4KCF9QbKn0iLVMhfigUMw4IzGZEZ81m1I=
github.com/bettercap/readline v0.0.0-20210228151553-655e48bcb7bf/go.mod h1:03rWiUf60r1miMVzMEtgtkq7RdZniecZFw3/Zgvyxcs=
github.com/bettercap/recording v0.0.0-20190408083647-3ce1dcf032e3 h1:pC4ZAk7UtDIbrRKzMMiIL1TVkiKlgtgcJodqKB53Rl4=
@ -49,27 +27,15 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8=
github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d h1:rtM8HsT3NG37YPjz8sYSbUSdElP9lUsQENYzJDZDUBE=
github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e h1:/cwV7t2xezilMljIftb7WlFtzGANRCnoOhPjtl2ifcs=
github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhPhOPHULCQQDnGhRelpFWHMLhQVWDsS0v4=
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 h1:lS3P5Nw3oPO05Lk2gFiYUOL3QPaH+fRoI1wFOc4G1UY=
github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/elazarl/goproxy/ext v0.0.0-20210110162100-a92cc753f88e h1:CQn2/8fi3kmpT9BTiHEELgdxAOQNVZc9GoPA4qnQzrs=
github.com/elazarl/goproxy/ext v0.0.0-20210110162100-a92cc753f88e/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/evilsocket/islazy v1.10.4 h1:Z5373Kn5Gh2EWch1Tb/Qxb6vyQ7lw704bmKi7sY4Ecs=
github.com/evilsocket/islazy v1.10.4/go.mod h1:OrwQGYg3DuZvXUfmH+KIZDjwTCbrjy48T24TUpGqVVw=
github.com/evilsocket/islazy v1.10.6 h1:MFq000a1ByoumoJWlytqg0qon0KlBeUfPsDjY0hK0bo=
github.com/evilsocket/islazy v1.10.6/go.mod h1:OrwQGYg3DuZvXUfmH+KIZDjwTCbrjy48T24TUpGqVVw=
github.com/gobwas/glob v0.0.0-20181002190808-e7a84e9525fe h1:8P+/htb3mwwpeGdJg69yBF/RofK7c6Fjz5Ypa/bTqbY=
github.com/gobwas/glob v0.0.0-20181002190808-e7a84e9525fe/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -78,217 +44,106 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY=
github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/gousb v0.0.0-20190525092738-2dc560e6bea3 h1:3RtjTHQgWbD7dsPreVSkA5/LGfNnAZyjOtDXhargyEE=
github.com/google/gousb v0.0.0-20190525092738-2dc560e6bea3/go.mod h1:Tl4HdAs1ThE3gECkNwz+1MWicX6FXddhJEw7L8jRDiI=
github.com/google/gousb v0.0.0-20190812193832-18f4c1d8a750 h1:DVKHLo3yE4psTjD9aM2pY7EHoicaQbgmaxxvvHC6ZSM=
github.com/google/gousb v0.0.0-20190812193832-18f4c1d8a750/go.mod h1:Tl4HdAs1ThE3gECkNwz+1MWicX6FXddhJEw7L8jRDiI=
github.com/google/gousb v2.1.0+incompatible h1:ApzMDjF3FeO219QwWybJxYfFhXQzPLOEy0o+w9k5DNI=
github.com/google/gousb v2.1.0+incompatible/go.mod h1:Tl4HdAs1ThE3gECkNwz+1MWicX6FXddhJEw7L8jRDiI=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/google/gousb v1.1.2 h1:1BwarNB3inFTFhPgUEfah4hwOPuDz/49I0uX8XNginU=
github.com/google/gousb v1.1.2/go.mod h1:GGWUkK0gAXDzxhwrzetW592aOmkkqSGcj5KLEgmCVUg=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8=
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/mdns v1.0.3 h1:hPneYJlzSjxFBmUlnDGXRykxBZ++dQAJhU57gCO7TzI=
github.com/hashicorp/mdns v1.0.3/go.mod h1:P9sIDVQGUBr2GtS4qS2QCBdtgqP7TBt6d8looU5l5r4=
github.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b h1:IpLPmn6Re21F0MaV6Zsc5RdSE6KuoFpWmHiUSEs3PrE=
github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b/go.mod h1:aA6DnFhALT3zH0y+A39we+zbrdMC2N0X/q21e6FI0LU=
github.com/jpillora/go-tld v0.0.0-20190202073305-f16ca3b7b383 h1:/ODEnccTd4m/1YbCDCZBIoo+W1BC+PjOzvfX8y++b5s=
github.com/jpillora/go-tld v0.0.0-20190202073305-f16ca3b7b383/go.mod h1:7H/4k+TVAFSXCq+KcvelJ5hClsXnabjF52BLYqgaqcQ=
github.com/jpillora/go-tld v1.0.0 h1:W0Wz3fYT9WCDNJXcXc58uV7sriLnVeELeOU5MP5X42M=
github.com/jpillora/go-tld v1.0.0/go.mod h1:kitBxOF//DR5FxYeIGw+etdiiTIq5S7bx0dwy1GUNAk=
github.com/jpillora/go-tld v1.1.1 h1:P1ZwtKDHBYYUl235R/D64cdBARfGYzEy1Hg2Ikir3FQ=
github.com/jpillora/go-tld v1.1.1/go.mod h1:kitBxOF//DR5FxYeIGw+etdiiTIq5S7bx0dwy1GUNAk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/koppacetic/go-gpsd v0.4.0 h1:/T3cRvi1ZsWbxCZPB9pPor0HjIw3HuD+MSvaxV5QqQ8=
github.com/koppacetic/go-gpsd v0.4.0/go.mod h1:mhcLuh9X++WHepbL3jEmEwnx1OkQDepZMihv12RO4qk=
github.com/kr/binarydist v0.1.0 h1:6kAoLA9FMMnNGSehX0s1PdjbEaACznAv/W219j2uvyo=
github.com/kr/binarydist v0.1.0/go.mod h1:DY7S//GCoz1BCd0B0EVrinCKAZN3pXe+MDaIZbXQVgM=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/malfunkt/iprange v0.9.0 h1:VCs0PKLUPotNVQTpVNszsut4lP7OCGNBwX+lOYBrnVQ=
github.com/malfunkt/iprange v0.9.0/go.mod h1:TRGqO/f95gh3LOndUGTL46+W0GXA91WTqyZ0Quwvt4U=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mdlayher/dhcp6 v0.0.0-20190311162359-2a67805d7d0b h1:r12blE3QRYlW1WBiBEe007O6NrTb/P54OjR5d4WLEGk=
github.com/mdlayher/dhcp6 v0.0.0-20190311162359-2a67805d7d0b/go.mod h1:p4K2+UAoap8Jzsadsxc0KG0OZjmmCthTPUyZqAVkjBY=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab h1:n8cgpHzJ5+EDyDri2s/GC7a9+qK3/YEGnBsd0uS/8PY=
github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab/go.mod h1:y1pL58r5z2VvAjeG1VLGc8zOQgSOzbKN7kMHPvFXJ+8=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.14 h1:wkQWn9wIp4mZbwW8XV6Km6owkvRPbOiV004ZM2CkGvA=
github.com/miekg/dns v1.1.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.22 h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc=
github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4=
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac h1:kYPjbEN6YPYWWHI6ky1J813KzIq/8+Wg4TO4xU7A/KU=
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/robertkrimen/otto v0.0.0-20210614181706-373ff5438452 h1:ewTtJ72GFy2e0e8uyiDwMG3pKCS5mBh+hdSTYsPKEP8=
github.com/robertkrimen/otto v0.0.0-20210614181706-373ff5438452/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/thoj/go-ircevent v0.0.0-20190807115034-8e7ce4b5a1eb h1:EavwSqheIJl3nb91HhkL73DwnT2Fk8W3yM7T7TuLZvA=
github.com/thoj/go-ircevent v0.0.0-20190807115034-8e7ce4b5a1eb/go.mod h1:I0ZT9x8wStY6VOxtNOrLpnDURFs7HS0z1e1vhuKUEVc=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64 h1:l/T7dYuJEQZOwVOpjIXr1180aM9PZL/d1MnMVIxefX4=
github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64/go.mod h1:Q1NAJOuRdQCqN/VIWdnaaEhV8LpeO2rtlBP7/iDJNII=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190310074541-c10a0554eabf/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321 h1:lleNcKRbcaC8MqgLwghIkzZ2JBQAb7QQ9MiwRt1BisA=
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191018095205-727590c5006e h1:ZtoklVMHQy6BFRHkbG6JzK+S6rX82//Yeok1vMlizfQ=
golang.org/x/sys v0.0.0-20191018095205-727590c5006e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIwSCiDQJxpBxmvqb1N1c=
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-2019.2.1 h1:fW1wbZIKRbRK56ETe5SYloH5SdLzhXOFet2KlpRKDqg=
honnef.co/go/tools v0.0.0-2019.2.1/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

View file

@ -4,6 +4,7 @@ import (
"bytes"
"compress/gzip"
"encoding/base64"
"github.com/robertkrimen/otto"
)
@ -13,6 +14,7 @@ func btoa(call otto.FunctionCall) otto.Value {
if err != nil {
return ReportError("Could not convert to string: %s", varValue)
}
return v
}
@ -21,10 +23,12 @@ func atob(call otto.FunctionCall) otto.Value {
if err != nil {
return ReportError("Could not decode string: %s", call.Argument(0).String())
}
v, err := otto.ToValue(string(varValue))
if err != nil {
return ReportError("Could not convert to string: %s", varValue)
}
return v
}

View file

@ -3,12 +3,13 @@ package js
import (
"bytes"
"fmt"
"github.com/robertkrimen/otto"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/robertkrimen/otto"
)
type httpPackage struct {
@ -26,7 +27,10 @@ func (c httpPackage) Encode(s string) string {
return url.QueryEscape(s)
}
func (c httpPackage) Request(method string, uri string, headers map[string]string, form map[string]string, json string) httpResponse {
func (c httpPackage) Request(method string, uri string,
headers map[string]string,
form map[string]string,
json string) httpResponse {
var reader io.Reader
if form != nil {

View file

@ -3,7 +3,6 @@ package js
import (
"github.com/evilsocket/islazy/log"
"github.com/evilsocket/islazy/plugin"
"github.com/robertkrimen/otto"
)

View file

@ -44,7 +44,7 @@ func NewAnyProxy(s *session.Session) *AnyProxy {
mod.AddParam(session.NewStringParameter("any.proxy.dst_address",
session.ParamIfaceAddress,
session.IPv4Validator,
"",
"Address where the proxy is listening."))
mod.AddParam(session.NewIntParameter("any.proxy.dst_port",

View file

@ -3,6 +3,7 @@ package arp_spoof
import (
"bytes"
"net"
"strings"
"sync"
"time"
@ -22,6 +23,7 @@ type ArpSpoofer struct {
fullDuplex bool
internal bool
ban bool
skipRestore bool
waitGroup *sync.WaitGroup
}
@ -35,6 +37,7 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
ban: false,
internal: false,
fullDuplex: false,
skipRestore: false,
waitGroup: &sync.WaitGroup{},
}
@ -52,6 +55,20 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
"false",
"If true, both the targets and the gateway will be attacked, otherwise only the target (if the router has ARP spoofing protections in place this will make the attack fail)."))
noRestore := session.NewBoolParameter("arp.spoof.skip_restore",
"false",
"If set to true, targets arp cache won't be restored when spoofing is stopped.")
mod.AddObservableParam(noRestore, func(v string) {
if strings.ToLower(v) == "true" || v == "1" {
mod.skipRestore = true
mod.Warning("arp cache restoration after spoofing disabled")
} else {
mod.skipRestore = false
mod.Debug("arp cache restoration after spoofing enabled")
}
})
mod.AddHandler(session.NewModuleHandler("arp.spoof on", "",
"Start ARP spoofer.",
func(args []string) error {
@ -171,6 +188,7 @@ func (mod *ArpSpoofer) Start() error {
}
func (mod *ArpSpoofer) unSpoof() error {
if !mod.skipRestore {
nTargets := len(mod.addresses) + len(mod.macs)
mod.Info("restoring ARP cache of %d targets.", nTargets)
mod.arpSpoofTargets(mod.Session.Gateway.IP, mod.Session.Gateway.HW, false, false)
@ -186,6 +204,9 @@ func (mod *ArpSpoofer) unSpoof() error {
}
}
}
} else {
mod.Warning("arp cache restoration is disabled")
}
return nil
}
@ -260,7 +281,10 @@ func (mod *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, chec
}
}
for ip, mac := range mod.getTargets(probe) {
if targets := mod.getTargets(probe); len(targets) == 0 {
mod.Warning("could not find spoof targets")
} else {
for ip, mac := range targets {
if check_running && !mod.Running() {
return
} else if mod.isWhitelisted(ip, mac) {
@ -306,3 +330,4 @@ func (mod *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, chec
}
}
}
}

View file

@ -9,6 +9,7 @@ import (
"sync"
"time"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/bettercap/bettercap/session"
@ -83,7 +84,7 @@ func (mod *DHCP6Spoofer) Configure() error {
return session.ErrAlreadyStarted(mod.Name())
}
if mod.Handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil {
if mod.Handle, err = network.Capture(mod.Session.Interface.Name()); err != nil {
return err
}

View file

@ -8,6 +8,7 @@ import (
"sync"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/bettercap/bettercap/session"
@ -100,7 +101,7 @@ func (mod *DNSSpoofer) Configure() error {
if mod.Running() {
return session.ErrAlreadyStarted(mod.Name())
} else if mod.Handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil {
} else if mod.Handle, err = network.Capture(mod.Session.Interface.Name()); err != nil {
return err
} else if err = mod.Handle.SetBPFFilter("udp"); err != nil {
return err

View file

@ -2,12 +2,13 @@ package events_stream
import (
"fmt"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/session"
"io"
"os"
"strings"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/session"
"github.com/bettercap/bettercap/modules/net_sniff"
"github.com/bettercap/bettercap/modules/syn_scan"
@ -119,6 +120,8 @@ func (mod *EventsStream) Render(output io.Writer, e session.Event) {
mod.viewBLEEvent(output, e)
} else if strings.HasPrefix(e.Tag, "hid.") {
mod.viewHIDEvent(output, e)
} else if strings.HasPrefix(e.Tag, "gps.") {
mod.viewGPSEvent(output, e)
} else if strings.HasPrefix(e.Tag, "mod.") {
mod.viewModuleEvent(output, e)
} else if strings.HasPrefix(e.Tag, "net.sniff.") {
@ -129,7 +132,7 @@ func (mod *EventsStream) Render(output io.Writer, e session.Event) {
mod.viewUpdateEvent(output, e)
} else if e.Tag == "gateway.change" {
mod.viewGatewayEvent(output, e)
} else if e.Tag != "tick" {
} else if e.Tag != "tick" && e.Tag != "session.started" && e.Tag != "session.stopped" {
fmt.Fprintf(output, "[%s] [%s] %v\n", e.Time.Format(mod.timeFormat), tui.Green(e.Tag), e)
}
}

View file

@ -0,0 +1,24 @@
package events_stream
import (
"fmt"
"io"
"github.com/bettercap/bettercap/session"
"github.com/evilsocket/islazy/tui"
)
func (mod *EventsStream) viewGPSEvent(output io.Writer, e session.Event) {
if e.Tag == "gps.new" {
gps := e.Data.(session.GPS)
fmt.Fprintf(output, "[%s] [%s] latitude:%f longitude:%f quality:%s satellites:%d altitude:%f\n",
e.Time.Format(mod.timeFormat),
tui.Green(e.Tag),
gps.Latitude,
gps.Longitude,
gps.FixQuality,
gps.NumSatellites,
gps.Altitude)
}
}

View file

@ -138,16 +138,7 @@ func (mod *GPS) readFromSerial() {
if line, err := mod.readLine(); err == nil {
if s, err := nmea.Parse(line); err == nil {
// http://aprs.gids.nl/nmea/#gga
if m, ok := s.(nmea.GNGGA); ok {
mod.Session.GPS.Updated = time.Now()
mod.Session.GPS.Latitude = m.Latitude
mod.Session.GPS.Longitude = m.Longitude
mod.Session.GPS.FixQuality = m.FixQuality
mod.Session.GPS.NumSatellites = m.NumSatellites
mod.Session.GPS.HDOP = m.HDOP
mod.Session.GPS.Altitude = m.Altitude
mod.Session.GPS.Separation = m.Separation
} else if m, ok := s.(nmea.GPGGA); ok {
if m, ok := s.(nmea.GGA); ok {
mod.Session.GPS.Updated = time.Now()
mod.Session.GPS.Latitude = m.Latitude
mod.Session.GPS.Longitude = m.Longitude
@ -156,6 +147,8 @@ func (mod *GPS) readFromSerial() {
mod.Session.GPS.HDOP = m.HDOP
mod.Session.GPS.Altitude = m.Altitude
mod.Session.GPS.Separation = m.Separation
mod.Session.Events.Add("gps.new", mod.Session.GPS)
}
} else {
mod.Debug("error parsing line '%s': %s", line, err)
@ -173,6 +166,8 @@ func (mod *GPS) runFromGPSD() {
mod.Session.GPS.Longitude = report.Lon
mod.Session.GPS.FixQuality = ModeInfo[report.Mode]
mod.Session.GPS.Altitude = report.Alt
mod.Session.Events.Add("gps.new", mod.Session.GPS)
})
mod.gpsd.Subscribe("SKY", func(r interface{}) {

View file

@ -116,13 +116,7 @@ func (p *HTTPProxy) onResponseFilter(res *http.Response, ctx *goproxy.ProxyCtx)
if jsres != nil {
// the response has been changed by the script
p.logResponseAction(res.Request, jsres)
raw, err := ioutil.ReadAll(jsres.ToResponse(res.Request).Body)
if err == nil {
html := string(raw)
res.Header.Set("Content-Length", strconv.Itoa(len(html)))
// reset the response body to the original unread state
res.Body = ioutil.NopCloser(strings.NewReader(html))
}
return jsres.ToResponse(res.Request)
}
}

View file

@ -5,12 +5,13 @@ import (
"net/http"
"net/url"
"regexp"
"strings"
"strconv"
"strings"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/session"
"github.com/bettercap/bettercap/modules/dns_spoof"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/session"
"github.com/elazarl/goproxy"
"github.com/google/gopacket"
@ -83,7 +84,7 @@ func (s *SSLStripper) Enable(enabled bool) {
if enabled && s.handle == nil {
var err error
if s.handle, err = pcap.OpenLive(s.session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil {
if s.handle, err = network.Capture(s.session.Interface.Name()); err != nil {
panic(err)
}

View file

@ -32,7 +32,9 @@ func NewNDPSpoofer(s *session.Session) *NDPSpoofer {
mod.AddParam(session.NewStringParameter("ndp.spoof.targets", "", "",
"Comma separated list of IPv6 victim addresses."))
mod.AddParam(session.NewStringParameter("ndp.spoof.neighbour", "fe80::1", "",
mod.AddParam(session.NewStringParameter("ndp.spoof.neighbour",
"fe80::1",
session.IPv6Validator,
"Neighbour IPv6 address to spoof, clear to disable NA."))
mod.AddParam(session.NewStringParameter("ndp.spoof.prefix", "d00d::", "",
@ -122,7 +124,7 @@ func (mod *NDPSpoofer) Start() error {
}
return mod.SetRunning(true, func() {
mod.Info("ndp spoofer started - neighbour=%s prefix=%s", mod.neighbour, mod.prefix)
mod.Info("ndp spoofer started - targets=%s neighbour=%s prefix=%s", mod.addresses, mod.neighbour, mod.prefix)
mod.waitGroup.Add(1)
defer mod.waitGroup.Done()
@ -179,6 +181,8 @@ func (mod *NDPSpoofer) getTargets(probe bool) map[string]net.HardwareAddr {
// do we have this ip mac address?
if hw, err := mod.Session.FindMAC(ip, probe); err == nil {
targets[ip.String()] = hw
} else {
mod.Info("couldn't get MAC for ip=%s, put it into the neighbour table manually e.g. ping -6")
}
}

View file

@ -6,6 +6,7 @@ import (
"time"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/session"
"github.com/google/gopacket/pcap"
@ -42,7 +43,7 @@ func (mod *Sniffer) GetContext() (error, *SnifferContext) {
* could hang waiting for a timeout to expire ...
*/
readTimeout := 500 * time.Millisecond
if ctx.Handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, readTimeout); err != nil {
if ctx.Handle, err = network.CaptureWithTimeout(mod.Session.Interface.Name(), readTimeout); err != nil {
return err, ctx
}
} else {

View file

@ -7,6 +7,7 @@ import (
"sync/atomic"
"time"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/bettercap/bettercap/session"
@ -115,7 +116,7 @@ func (mod *SynScanner) Configure() (err error) {
return session.ErrAlreadyStarted(mod.Name())
}
if mod.handle == nil {
if mod.handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil {
if mod.handle, err = network.Capture(mod.Session.Interface.Name()); err != nil {
return err
} else if err = mod.handle.SetBPFFilter(fmt.Sprintf("tcp dst port %d", synSourcePort)); err != nil {
return err

View file

@ -9,6 +9,7 @@ import (
"os"
"path/filepath"
"regexp"
"runtime"
"github.com/bettercap/bettercap/session"
@ -29,6 +30,13 @@ type UIModule struct {
uiPath string
}
func getDefaultInstallBase() string {
if runtime.GOOS == "windows" {
return filepath.Join(os.Getenv("ALLUSERSPROFILE"), "bettercap")
}
return "/usr/local/share/bettercap/"
}
func NewUIModule(s *session.Session) *UIModule {
mod := &UIModule{
SessionModule: session.NewSessionModule("ui", s),
@ -36,7 +44,7 @@ func NewUIModule(s *session.Session) *UIModule {
}
mod.AddParam(session.NewStringParameter("ui.basepath",
"/usr/local/share/bettercap/",
getDefaultInstallBase(),
"",
"UI base installation path."))

View file

@ -54,6 +54,8 @@ type WiFiModule struct {
assocSilent bool
assocOpen bool
assocAcquired bool
csaSilent bool
fakeAuthSilent bool
filterProbeSTA *regexp.Regexp
filterProbeAP *regexp.Regexp
apRunning bool
@ -88,6 +90,8 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
assocSilent: false,
assocOpen: false,
assocAcquired: false,
csaSilent: false,
fakeAuthSilent: false,
showManuf: false,
shakesAggregate: true,
writes: &sync.WaitGroup{},
@ -215,6 +219,50 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
mod.AddHandler(probe)
channelSwitchAnnounce := session.NewModuleHandler("wifi.channel_switch_announce bssid channel ", `wifi\.channel_switch_announce ((?:[a-fA-F0-9:]{11,}))\s+((?:[0-9]+))`,
"Start a 802.11 channel hop attack, all client will be force to change the channel lead to connection down.",
func(args []string) error {
bssid, err := net.ParseMAC(args[0])
if err != nil {
return err
}
channel, _ := strconv.Atoi(args[1])
if channel > 180 || channel < 1 {
return fmt.Errorf("%d is not a valid channel number", channel)
}
return mod.startCSA(bssid, int8(channel))
})
channelSwitchAnnounce.Complete("wifi.channel_switch_announce", s.WiFiCompleterFull)
mod.AddHandler(channelSwitchAnnounce)
fakeAuth := session.NewModuleHandler("wifi.fake_auth bssid client", `wifi\.fake_auth ((?:[a-fA-F0-9:]{11,}))\s+((?:[a-fA-F0-9:]{11,}))`,
"send an fake authentication with client mac to ap lead to client disconnect",
func(args []string) error {
bssid, err := net.ParseMAC(args[0])
if err != nil {
return err
}
client, err := net.ParseMAC(args[1])
if err != nil {
return err
}
return mod.startFakeAuth(bssid, client)
})
fakeAuth.Complete("wifi.fake_auth", s.WiFiCompleterFull)
mod.AddHandler(fakeAuth)
mod.AddParam(session.NewBoolParameter("wifi.channel_switch_announce.silent",
"false",
"If true, messages from wifi.channel_switch_announce will be suppressed."))
mod.AddParam(session.NewBoolParameter("wifi.fake_auth.silent",
"false",
"If true, messages from wifi.fake_auth will be suppressed."))
mod.AddParam(session.NewStringParameter("wifi.deauth.skip",
"",
"",
@ -502,60 +550,40 @@ func (mod *WiFiModule) Configure() error {
if mod.txPower > 0 {
if err := network.SetInterfaceTxPower(ifName, mod.txPower); err != nil {
mod.Warning("could not set interface %s txpower to %d, 'Set Tx Power' requests not supported", ifName, mod.txPower)
mod.Warning("could not set interface %s txpower to %d, 'Set Tx Power' requests not supported: %v", ifName, mod.txPower, err)
} else {
mod.Debug("interface %s txpower set to %d", ifName, mod.txPower)
}
}
setRFMonMaybeFatal := false
for retry := 0; ; retry++ {
ihandle, err := pcap.NewInactiveHandle(ifName)
if err != nil {
return fmt.Errorf("error while opening interface %s: %s", ifName, err)
}
defer ihandle.CleanUp()
/*
* Calling SetRFMon is fatal when the interface is already in monitor mode.
* gopacket has no GetRFMon analogue to SetRFMon with which we could check this, however ...
*/
if !setRFMonMaybeFatal {
if err = ihandle.SetRFMon(true); err != nil {
return fmt.Errorf("error while setting interface %s in monitor mode: %s", tui.Bold(ifName), err)
}
} else {
mod.Debug("SetRFMon on interface %s might be fatal, skipping this time", tui.Bold(ifName))
}
if err = ihandle.SetSnapLen(65536); err != nil {
return fmt.Errorf("error while settng snapshot length: %s", err)
}
/*
* We don't want to pcap.BlockForever otherwise pcap_close(handle)
* could hang waiting for a timeout to expire ...
*/
readTimeout := 500 * time.Millisecond
if err = ihandle.SetTimeout(readTimeout); err != nil {
return fmt.Errorf("error while setting timeout: %s", err)
} else if mod.handle, err = ihandle.Activate(); err != nil {
if retry == 0 && err.Error() == ErrIfaceNotUp {
mod.Debug("interface %s is down, bringing it up ...", ifName)
opts := network.CAPTURE_DEFAULTS
opts.Timeout = 500 * time.Millisecond
opts.Monitor = true
for retry := 0; ; retry++ {
if mod.handle, err = network.CaptureWithOptions(ifName, opts); err == nil {
// we're done
break
} else if retry == 0 && err.Error() == ErrIfaceNotUp {
// try to bring interface up and try again
mod.Info("interface %s is down, bringing it up ...", ifName)
if err := network.ActivateInterface(ifName); err != nil {
return err
}
continue
}
if setRFMonMaybeFatal {
} else if !opts.Monitor {
// second fatal error, just bail
return fmt.Errorf("error while activating handle: %s", err)
} else {
// first fatal error, try again without setting the interface in monitor mode
mod.Warning("error while activating handle: %s, %s", err, tui.Bold("interface might already be monitoring. retrying!"))
setRFMonMaybeFatal = true
continue
opts.Monitor = false
}
}
break
}
}
if err, mod.skipBroken = mod.BoolParam("wifi.skip-broken"); err != nil {

86
modules/wifi/wifi_csa.go Normal file
View file

@ -0,0 +1,86 @@
package wifi
import (
"bytes"
"fmt"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/google/gopacket/layers"
"net"
)
func (mod *WiFiModule) isCSASilent() bool {
if err, is := mod.BoolParam("wifi.channel_switch_announce.silent"); err != nil {
mod.Warning("%v", err)
} else {
mod.csaSilent = is
}
return mod.csaSilent
}
func (mod *WiFiModule) sendBeaconWithCSAPacket(ap *network.AccessPoint, toChan int8) {
ssid := ap.ESSID()
if ssid == "<hidden>" {
ssid = ""
}
hw, _ := net.ParseMAC(ap.BSSID())
for seq := uint16(0); seq < 256 && mod.Running(); seq++ {
if err, pkt := packets.NewDot11Beacon(packets.Dot11ApConfig{
SSID: ssid,
BSSID: hw,
Channel: ap.Channel,
Encryption: false,
SpectrumManagement: true,
}, 0, packets.Dot11Info(layers.Dot11InformationElementIDSwitchChannelAnnounce, []byte{0, byte(toChan), 1})); err != nil {
mod.Error("could not create beacon packet: %s", err)
continue
} else {
mod.injectPacket(pkt)
}
}
}
func (mod *WiFiModule) startCSA(to net.HardwareAddr, toChan int8) error {
// if not already running, temporarily enable the pcap handle
// for packet injection
if !mod.Running() {
if err := mod.Configure(); err != nil {
return err
}
defer mod.handle.Close()
}
var ap *network.AccessPoint = nil
for _, _ap := range mod.Session.WiFi.List() {
if bytes.Equal(_ap.HW, to) {
ap = _ap
}
}
if ap == nil {
return fmt.Errorf("%s is an unknown BSSID", to.String())
}
mod.writes.Add(1)
go func() {
defer mod.writes.Done()
if mod.Running() {
logger := mod.Info
if mod.isCSASilent() {
logger = mod.Debug
}
logger("channel hop attack in AP %s (channel:%d encryption:%s), hop to channel %d ", ap.ESSID(), ap.Channel, ap.Encryption, toChan)
// send the beacon frame with channel switch announce element id
mod.onChannel(ap.Channel, func() {
mod.sendBeaconWithCSAPacket(ap, toChan)
})
}
}()
return nil
}

View file

@ -0,0 +1,71 @@
package wifi
import (
"bytes"
"fmt"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"net"
)
func (mod *WiFiModule) isFakeAuthSilent() bool {
if err, is := mod.BoolParam("wifi.fake_auth.silent"); err != nil {
mod.Warning("%v", err)
} else {
mod.csaSilent = is
}
return mod.csaSilent
}
func(mod *WiFiModule)sendFakeAuthPacket(bssid,client net.HardwareAddr){
err,pkt:=packets.NewDot11Auth(client,bssid,0)
if err!=nil{
mod.Error("could not create authentication packet: %s", err)
return
}
for i:=0;i<32;i++{
mod.injectPacket(pkt)
}
}
func (mod *WiFiModule) startFakeAuth(bssid,client net.HardwareAddr) error {
// if not already running, temporarily enable the pcap handle
// for packet injection
if !mod.Running() {
if err := mod.Configure(); err != nil {
return err
}
defer mod.handle.Close()
}
var ap *network.AccessPoint = nil
for _, _ap := range mod.Session.WiFi.List() {
if bytes.Equal(_ap.HW, bssid) {
ap = _ap
}
}
if ap == nil {
return fmt.Errorf("%s is an unknown BSSID", bssid.String())
}
mod.writes.Add(1)
go func() {
defer mod.writes.Done()
if mod.Running() {
logger := mod.Info
if mod.isFakeAuthSilent() {
logger = mod.Debug
}
logger("fake authentication attack in AP: %s client: %s", ap.ESSID(), client.String())
// send the beacon frame with channel switch announce element id
mod.onChannel(ap.Channel, func() {
mod.sendFakeAuthPacket(bssid,client)
})
}
}()
return nil
}

View file

@ -29,11 +29,19 @@ const (
var (
BroadcastHw = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
IPv4Validator = regexp.MustCompile(`^[0-9\.]+/?\d*$`)
IPv4RangeValidator = regexp.MustCompile(`^[0-9\.\-]+/?\d*$`)
MACValidator = regexp.MustCompile(`(?i)^[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}$`)
IPv4BlockValidator = regexp.MustCompile(`^` +
`(?:(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])\.){3}` +
`(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])` +
`/(?:3[0-2]|2[0-9]|[1]?[0-9])` + `$`)
IPv4RangeValidator = regexp.MustCompile(`^` +
`(?:(?:(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])-)?(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])\.){3}` +
`(?:(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])-)?(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])` + `$`)
IPv4Validator = regexp.MustCompile(`^` +
`(?:(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])\.){3}` +
`(?:25[0-5]|2[0-4][0-9]|[1][0-9]{2}|[1-9]?[0-9])` + `$`)
MACValidator = regexp.MustCompile(`(?i)^(?:[a-f0-9]{2}:){5}[a-f0-9]{2}$`)
// lulz this sounds like a hamburger
macParser = regexp.MustCompile(`(?i)([a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2})`)
macParser = regexp.MustCompile(`(?i)((?:[a-f0-9]{2}:){5}[a-f0-9]{2})`)
aliasParser = regexp.MustCompile(`(?i)([a-z_][a-z_0-9]+)`)
)
@ -247,7 +255,7 @@ func FindInterface(name string) (*Endpoint, error) {
// user did not provide an interface name,
// return the first one with a valid ipv4
// address
// address that does not loop back
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err != nil {
@ -257,7 +265,7 @@ func FindInterface(name string) (*Endpoint, error) {
for _, address := range addrs {
ip := address.String()
if !strings.Contains(ip, "127.0.0.1") && IPv4Validator.MatchString(ip) {
if !strings.HasPrefix(ip, "127.0.0.1") && IPv4BlockValidator.MatchString(ip) {
return buildEndpointFromInterface(iface)
}
}
@ -279,7 +287,11 @@ func SetWiFiRegion(region string) error {
func ActivateInterface(name string) error {
if out, err := core.Exec("ifconfig", []string{name, "up"}); err != nil {
if out != "" {
return fmt.Errorf("%v: %s", err, out)
} else {
return err
}
} else if out != "" {
return fmt.Errorf("unexpected output while activating interface %s: %s", name, out)
}
@ -289,8 +301,7 @@ func ActivateInterface(name string) error {
func SetInterfaceTxPower(name string, txpower int) error {
if core.HasBinary("iw") {
Debug("SetInterfaceTxPower(%s, %d) iw based", name, txpower)
if _, err := core.Exec("iw", []string{"dev", name, "set", "txpower", "fixed", fmt.Sprintf("%d",
txpower)}); err != nil {
if _, err := core.Exec("iw", []string{"dev", name, "set", "txpower", "fixed", fmt.Sprintf("%d", txpower)}); err != nil {
return err
}
} else if core.HasBinary("iwconfig") {

View file

@ -73,7 +73,7 @@ func iwlistSupportedFrequencies(iface string) ([]int, error) {
}
var iwPhyParser = regexp.MustCompile(`^\s*wiphy\s+(\d+)$`)
var iwFreqParser = regexp.MustCompile(`^\s+\*\s+(\d+)\s+MHz.+$`)
var iwFreqParser = regexp.MustCompile(`^\s+\*\s+(\d+)\s+MHz.+dBm.+$`)
func iwSupportedFrequencies(iface string) ([]int, error) {
// first determine phy index
@ -123,10 +123,12 @@ func iwSupportedFrequencies(iface string) ([]int, error) {
}
func GetSupportedFrequencies(iface string) ([]int, error) {
if core.HasBinary("iw") {
return iwSupportedFrequencies(iface)
} else if core.HasBinary("iwlist") {
// give priority to iwlist because of https://github.com/bettercap/bettercap/issues/881
if core.HasBinary("iwlist") {
return iwlistSupportedFrequencies(iface)
} else if core.HasBinary("iw") {
return iwSupportedFrequencies(iface)
}
return nil, fmt.Errorf("no iw or iwlist binaries found in $PATH")
}

71
network/pcap.go Normal file
View file

@ -0,0 +1,71 @@
package network
import (
"fmt"
"time"
"github.com/evilsocket/islazy/tui"
"github.com/google/gopacket/pcap"
)
const (
PCAP_DEFAULT_SETRF = false
PCAP_DEFAULT_SNAPLEN = 65536
PCAP_DEFAULT_BUFSIZE = 2_097_152
PCAP_DEFAULT_PROMISC = true
PCAP_DEFAULT_TIMEOUT = pcap.BlockForever
)
var CAPTURE_DEFAULTS = CaptureOptions{
Monitor: PCAP_DEFAULT_SETRF,
Snaplen: PCAP_DEFAULT_SNAPLEN,
Bufsize: PCAP_DEFAULT_BUFSIZE,
Promisc: PCAP_DEFAULT_PROMISC,
Timeout: PCAP_DEFAULT_TIMEOUT,
}
type CaptureOptions struct {
Monitor bool
Snaplen int
Bufsize int
Promisc bool
Timeout time.Duration
}
func CaptureWithOptions(ifName string, options CaptureOptions) (*pcap.Handle, error) {
Debug("creating capture for '%s' with options: %+v", ifName, options)
ihandle, err := pcap.NewInactiveHandle(ifName)
if err != nil {
return nil, fmt.Errorf("error while opening interface %s: %s", ifName, err)
}
defer ihandle.CleanUp()
if options.Monitor {
if err = ihandle.SetRFMon(true); err != nil {
return nil, fmt.Errorf("error while setting interface %s in monitor mode: %s", tui.Bold(ifName), err)
}
}
if err = ihandle.SetSnapLen(options.Snaplen); err != nil {
return nil, fmt.Errorf("error while settng snapshot length: %s", err)
} else if err = ihandle.SetBufferSize(options.Bufsize); err != nil {
return nil, fmt.Errorf("error while settng buffer size: %s", err)
} else if err = ihandle.SetPromisc(options.Promisc); err != nil {
return nil, fmt.Errorf("error while settng promiscuous mode to %v: %s", options.Promisc, err)
} else if err = ihandle.SetTimeout(options.Timeout); err != nil {
return nil, fmt.Errorf("error while settng snapshot length: %s", err)
}
return ihandle.Activate()
}
func Capture(ifName string) (*pcap.Handle, error) {
return CaptureWithOptions(ifName, CAPTURE_DEFAULTS)
}
func CaptureWithTimeout(ifName string, timeout time.Duration) (*pcap.Handle, error) {
var opts = CAPTURE_DEFAULTS
opts.Timeout = timeout
return CaptureWithOptions(ifName, opts)
}

View file

@ -23,6 +23,8 @@ func Dot11Freq2Chan(freq int) int {
return 14
} else if freq >= 5035 && freq <= 5865 {
return ((freq - 5035) / 5) + 7
} else if freq >= 5875 && freq <= 5895 {
return 177
}
return 0
}
@ -34,6 +36,8 @@ func Dot11Chan2Freq(channel int) int {
return 2484
} else if channel <= 173 {
return ((channel - 7) * 5) + 5035
} else if channel == 177 {
return 5885
}
return 0

View file

@ -6,26 +6,39 @@ import (
"github.com/evilsocket/islazy/data"
)
// Define test data for dot11 frequency <-> channel tests
type dot11pair struct {
frequency int
channel int
}
var dot11TestVector = []dot11pair{
{2472, 13},
{2484, 14},
{5825, 165},
{5885, 177},
}
func buildExampleWiFi() *WiFi {
aliases := &data.UnsortedKV{}
return NewWiFi(buildExampleEndpoint(), aliases, func(ap *AccessPoint) {}, func(ap *AccessPoint) {})
}
func TestDot11Freq2Chan(t *testing.T) {
exampleFreq := 2472
exp := 13
got := Dot11Freq2Chan(exampleFreq)
if got != exp {
t.Fatalf("expected '%v', got '%v'", exp, got)
for _, entry := range dot11TestVector {
gotChannel := Dot11Freq2Chan(entry.frequency)
if gotChannel != entry.channel {
t.Fatalf("expected '%v', got '%v'", entry.channel, gotChannel)
}
}
}
func TestDot11Chan2Freq(t *testing.T) {
exampleChan := 13
exp := 2472
got := Dot11Chan2Freq(exampleChan)
if got != exp {
t.Fatalf("expected '%v', got '%v'", exp, got)
for _, entry := range dot11TestVector {
gotFrequency := Dot11Chan2Freq(entry.channel)
if gotFrequency != entry.frequency {
t.Fatalf("expected '%v', got '%v'", entry.frequency, gotFrequency)
}
}
}

View file

@ -13,6 +13,7 @@ import (
var (
openFlags = 1057
wpaFlags = 1041
specManFlag = 1<<8
durationID = uint16(0x013a)
capabilityInfo = uint16(0x0411)
listenInterval = uint16(3)
@ -41,6 +42,7 @@ type Dot11ApConfig struct {
BSSID net.HardwareAddr
Channel int
Encryption bool
SpectrumManagement bool
}
func Dot11Info(id layers.Dot11InformationElementID, info []byte) *layers.Dot11InformationElement {
@ -51,12 +53,14 @@ func Dot11Info(id layers.Dot11InformationElementID, info []byte) *layers.Dot11In
}
}
func NewDot11Beacon(conf Dot11ApConfig, seq uint16) (error, []byte) {
func NewDot11Beacon(conf Dot11ApConfig, seq uint16, extendDot11Info ...*layers.Dot11InformationElement) (error, []byte) {
flags := openFlags
if conf.Encryption {
flags = wpaFlags
}
if conf.SpectrumManagement {
flags |= specManFlag
}
stack := []gopacket.SerializableLayer{
&layers.RadioTap{
DBMAntennaSignal: int8(-10),
@ -77,7 +81,9 @@ func NewDot11Beacon(conf Dot11ApConfig, seq uint16) (error, []byte) {
Dot11Info(layers.Dot11InformationElementIDRates, fakeApRates),
Dot11Info(layers.Dot11InformationElementIDDSSet, []byte{byte(conf.Channel & 0xff)}),
}
for _, v := range extendDot11Info {
stack = append(stack, v)
}
if conf.Encryption {
stack = append(stack, &layers.Dot11InformationElement{
ID: layers.Dot11InformationElementIDRSNInfo,

View file

@ -177,14 +177,22 @@ func dot11ParseWPSVendorExtension(data []byte, info *map[string]string) string {
size := len(data)
for offset := 3; offset < size; {
idByte := uint8(data[offset])
sizeByte := uint8(data[offset+1])
if next := offset + 1; next < size {
sizeByte := uint8(data[next])
if idByte == wpsVersion2ID {
verByte := fmt.Sprintf("%x", data[offset+2])
if next = offset + 2; next < size {
verByte := fmt.Sprintf("%x", data[next])
(*info)["Version"] = wpsVersionDesc[verByte]
data = data[offset+3:]
if next = offset + 3; next < size {
data = data[next:]
}
break
}
}
offset += int(sizeByte) + 2
} else {
break
}
}
}
return hex.EncodeToString(data)

View file

@ -5,7 +5,6 @@ import (
"strings"
"github.com/evilsocket/islazy/str"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)

View file

@ -69,7 +69,7 @@ func NewQueue(iface *network.Endpoint) (q *Queue, err error) {
}
if q.active {
if q.handle, err = pcap.OpenLive(iface.Name(), 1024, true, pcap.BlockForever); err != nil {
if q.handle, err = network.Capture(iface.Name()); err != nil {
return
}

View file

@ -1,10 +1,11 @@
package routing
import (
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
"regexp"
"strings"
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
)
var parser = regexp.MustCompile(`^([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+).*$`)

View file

@ -1,45 +1,78 @@
package routing
import (
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
"regexp"
"strings"
"github.com/bettercap/bettercap/core"
"github.com/evilsocket/islazy/str"
)
var parser = regexp.MustCompile(`^(.+)\sdev\s([^\s]+)\s(.+)$`)
var (
routeHeadings []string
whitespaceParser = regexp.MustCompile(`\s+`)
)
func update() ([]Route, error) {
table = make([]Route, 0)
for ip, inet := range map[RouteType]string{IPv4: "inet", IPv6: "inet6"} {
output, err := core.Exec("ip", []string{"-f", inet, "route"})
output, err := core.Exec("netstat", []string{"-r", "-n", "-4", "-6"})
if err != nil {
return nil, err
}
// because entries are separated by whitespace
output = strings.ReplaceAll(output, "Next Hop", "Gateway")
for _, line := range strings.Split(output, "\n") {
if line = str.Trim(line); len(line) > 0 {
matches := parser.FindStringSubmatch(line)
if num := len(matches); num == 4 {
route := Route{
Type: ip,
Destination: matches[1],
Device: matches[2],
Flags: matches[3],
Default: strings.Index(matches[1], "default ") == 0,
if line = str.Trim(line); len(line) != 0 {
parts := whitespaceParser.Split(line, -1)
if parts[0] == "Kernel" {
continue
}
if idx := strings.Index(route.Destination, " via "); idx >= 0 {
route.Gateway = route.Destination[idx + len(" via "):]
route.Destination = route.Destination[:idx]
if parts[0] == "Destination" {
routeHeadings = parts
continue
}
route := Route{}
for i, s := range parts {
switch routeHeadings[i] {
case "Destination":
route.Destination = s
break
case "Flag":
route.Flags = s
break
case "Flags":
route.Flags = s
break
case "Gateway":
route.Gateway = s
break
case "If":
route.Device = s
break
case "Iface":
route.Device = s
break
case "Netif":
route.Device = s
break
}
}
route.Default = strings.Contains(route.Flags, "G")
if strings.ContainsRune(route.Destination, '.') || strings.ContainsRune(route.Gateway, '.') {
route.Type = IPv4
} else {
route.Type = IPv6
}
table = append(table, route)
}
}
}
}
return table, nil
}

View file

@ -59,7 +59,7 @@ func NewIntParameter(name string, def_value string, desc string) *ModuleParam {
}
func NewDecimalParameter(name string, def_value string, desc string) *ModuleParam {
return NewModuleParameter(name, def_value, FLOAT, "^[\\d]+(\\.\\d+)?$", desc)
return NewModuleParameter(name, def_value, FLOAT, `^[\-\+]?[\d]+(\.\d+)?$`, desc)
}
func (p ModuleParam) validate(value string) (error, interface{}) {

View file

@ -2,15 +2,17 @@ package session
import (
"fmt"
"github.com/bettercap/bettercap/caplets"
_ "github.com/bettercap/bettercap/js"
"github.com/evilsocket/islazy/fs"
"github.com/evilsocket/islazy/plugin"
"github.com/evilsocket/islazy/str"
"io/ioutil"
"path/filepath"
"regexp"
"strings"
"github.com/bettercap/bettercap/caplets"
_ "github.com/bettercap/bettercap/js"
"github.com/evilsocket/islazy/fs"
"github.com/evilsocket/islazy/plugin"
"github.com/evilsocket/islazy/str"
)
// require("telegram.js")
@ -37,7 +39,7 @@ func preprocess(basePath string, code string, level int) (string, error) {
filepath.Join(caplets.InstallBase, fileName),
}
if strings.Contains(fileName, ".js") == false {
if !strings.Contains(fileName, ".js") {
searchPaths = append(searchPaths, []string{
filepath.Join(basePath, fileName) + ".js",
filepath.Join(caplets.InstallBase, fileName) + ".js",

View file

@ -2,12 +2,18 @@ package session
import (
"encoding/json"
"io/ioutil"
"os"
"github.com/bettercap/bettercap/js"
"github.com/evilsocket/islazy/fs"
"github.com/evilsocket/islazy/log"
"github.com/robertkrimen/otto"
)
// see https://github.com/robertkrimen/otto/issues/213
var jsRuntime = otto.New()
func jsRunFunc(call otto.FunctionCall) otto.Value {
argv := call.ArgumentList
argc := len(argv)
@ -67,15 +73,89 @@ func jsOnEventFunc(call otto.FunctionCall) otto.Value {
I.Events.Log(log.ERROR, "error serializing event %s: %v", event.Tag, err)
}
// lock vm
// lock vm if ready and available
locked := false
if I.script != nil {
I.script.Lock()
locked = true
}
if _, err := cb.Call(otto.NullValue(), opaque); err != nil {
I.Events.Log(log.ERROR, "error dispatching event %s: %v", event.Tag, err)
}
// unlock vm if ready and available
if locked {
I.script.Unlock()
}
}
}
}(filterExpr, cb)
return js.NullValue
}
func jsSaveJSONFunc(call otto.FunctionCall) otto.Value {
argv := call.ArgumentList
argc := len(argv)
if argc != 2 {
return js.ReportError("saveJSON accepts one object and one string arguments")
} else if argv[0].IsObject() == false {
return js.ReportError("saveJSON accepts one object and one string arguments")
} else if argv[1].IsString() == false {
return js.ReportError("saveJSON accepts one object and one string arguments")
}
obj := argv[0]
if fileName, err := fs.Expand(argv[1].String()); err != nil {
return js.ReportError("can't expand '%s': %v", fileName, err)
} else if exp, err := obj.Export(); err != nil {
return js.ReportError("error exporting object: %v", err)
} else if raw, err := json.Marshal(exp); err != nil {
return js.ReportError("error serializing object: %v", err)
} else if err = ioutil.WriteFile(fileName, raw, os.ModePerm); err != nil {
return js.ReportError("error writing to '%s': %v", fileName, err)
}
return js.NullValue
}
func jsLoadJSONFunc(call otto.FunctionCall) otto.Value {
argv := call.ArgumentList
argc := len(argv)
if argc != 1 {
return js.ReportError("loadJSON accepts one string argument")
} else if argv[0].IsString() == false {
return js.ReportError("loadJSON accepts one string argument")
}
var obj interface{}
if fileName, err := fs.Expand(argv[0].String()); err != nil {
return js.ReportError("can't expand '%s': %v", fileName, err)
} else if rawData, err := ioutil.ReadFile(fileName); err != nil {
return js.ReportError("can't read '%s': %v", fileName, err)
} else if err = json.Unmarshal(rawData, &obj); err != nil {
return js.ReportError("can't parse '%s': %v", fileName, err)
} else if v, err := jsRuntime.ToValue(obj); err != nil {
return js.ReportError("could not convert '%s' to javascript object: %s", fileName, err)
} else {
return v
}
}
func jsFileExistsFunc(call otto.FunctionCall) otto.Value {
argv := call.ArgumentList
argc := len(argv)
if argc != 1 {
return js.ReportError("fileExists accepts one string argument")
} else if argv[0].IsString() == false {
return js.ReportError("fileExists accepts one string argument")
} else if fileName, err := fs.Expand(argv[0].String()); err != nil {
return js.ReportError("can't expand '%s': %v", fileName, err)
} else if fs.Exists(fileName) {
return otto.TrueValue()
}
return otto.FalseValue()
}

View file

@ -127,6 +127,10 @@ func New() (*Session, error) {
}
}
if bufSize := *s.Options.PcapBufSize; bufSize != -1 {
network.CAPTURE_DEFAULTS.Bufsize = bufSize
}
if s.Env, err = NewEnvironment(*s.Options.EnvFile); err != nil {
return nil, err
}
@ -302,14 +306,15 @@ func (s *Session) Start() error {
s.startNetMon()
if *s.Options.Debug {
s.Events.Add("session.started", nil)
}
// register js functions here to avoid cyclic dependency between
// js and session
plugin.Defines["env"] = jsEnvFunc
plugin.Defines["run"] = jsRunFunc
plugin.Defines["fileExists"] = jsFileExistsFunc
plugin.Defines["loadJSON"] = jsLoadJSONFunc
plugin.Defines["saveJSON"] = jsSaveJSONFunc
plugin.Defines["onEvent"] = jsOnEventFunc
plugin.Defines["session"] = s

View file

@ -155,6 +155,9 @@ func (s *Session) activeHandler(args []string, sess *Session) error {
}
func (s *Session) exitHandler(args []string, sess *Session) error {
// notify any listener that the session is about to end
s.Events.Add("session.stopped", nil)
for _, mod := range s.Modules {
if mod.Running() {
mod.Stop()