mirror of
https://github.com/bettercap/bettercap
synced 2025-07-11 23:57:01 -07:00
new: centralized logging and implemented DELETE /api/events route, closes #5
This commit is contained in:
parent
269d7d845b
commit
f1f146d3d7
21 changed files with 144 additions and 184 deletions
1
Makefile
1
Makefile
|
@ -32,7 +32,6 @@ deps:
|
||||||
@go get github.com/malfunkt/iprange
|
@go get github.com/malfunkt/iprange
|
||||||
@go get github.com/rogpeppe/go-charset/charset
|
@go get github.com/rogpeppe/go-charset/charset
|
||||||
@go get github.com/chzyer/readline
|
@go get github.com/chzyer/readline
|
||||||
@go get github.com/op/go-logging
|
|
||||||
@go get github.com/robertkrimen/otto
|
@go get github.com/robertkrimen/otto
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/op/go-logging"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.MustGetLogger("mitm")
|
|
||||||
|
|
||||||
func Exec(executable string, args []string) (string, error) {
|
func Exec(executable string, args []string) (string, error) {
|
||||||
path, err := exec.LookPath(executable)
|
path, err := exec.LookPath(executable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf(DIM+"Exec( '%s %s' )"+RESET+"\n", path, strings.Join(args, " "))
|
|
||||||
raw, err := exec.Command(path, args...).CombinedOutput()
|
raw, err := exec.Command(path, args...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(" err=%s out='%s'\n", err, raw)
|
fmt.Printf("ERROR: path=%s args=%s err=%s out='%s'\n", path, args, err, raw)
|
||||||
return "", err
|
return "", err
|
||||||
} else {
|
} else {
|
||||||
return strings.Trim(string(raw), "\r\n\t "), nil
|
return strings.Trim(string(raw), "\r\n\t "), nil
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
"github.com/evilsocket/bettercap-ng/core"
|
||||||
"github.com/op/go-logging"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type LinuxFirewall struct {
|
type LinuxFirewall struct {
|
||||||
|
@ -15,8 +14,6 @@ type LinuxFirewall struct {
|
||||||
redirections map[string]*Redirection
|
redirections map[string]*Redirection
|
||||||
}
|
}
|
||||||
|
|
||||||
var log = logging.MustGetLogger("mitm")
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IPV4ForwardingFile = "/proc/sys/net/ipv4/ip_forward"
|
IPV4ForwardingFile = "/proc/sys/net/ipv4/ip_forward"
|
||||||
IPV4ICMPBcastFile = "/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts"
|
IPV4ICMPBcastFile = "/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts"
|
||||||
|
@ -31,8 +28,6 @@ func Make() FirewallManager {
|
||||||
|
|
||||||
firewall.forwarding = firewall.IsForwardingEnabled()
|
firewall.forwarding = firewall.IsForwardingEnabled()
|
||||||
|
|
||||||
log.Debugf("Created Linux Firewall ( forwarding=%v )\n", firewall.forwarding)
|
|
||||||
|
|
||||||
return firewall
|
return firewall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +55,6 @@ func (f LinuxFirewall) enableFeature(filename string, enable bool) error {
|
||||||
func (f LinuxFirewall) IsForwardingEnabled() bool {
|
func (f LinuxFirewall) IsForwardingEnabled() bool {
|
||||||
|
|
||||||
if out, err := ioutil.ReadFile(IPV4ForwardingFile); err != nil {
|
if out, err := ioutil.ReadFile(IPV4ForwardingFile); err != nil {
|
||||||
log.Error(err)
|
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
return strings.Trim(string(out), "\r\n\t ") == "1"
|
return strings.Trim(string(out), "\r\n\t ") == "1"
|
||||||
|
@ -90,8 +84,6 @@ func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error {
|
||||||
return fmt.Errorf("Redirection '%s' already enabled.", rkey)
|
return fmt.Errorf("Redirection '%s' already enabled.", rkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Enabling redirection %s\n", rkey)
|
|
||||||
|
|
||||||
f.redirections[rkey] = r
|
f.redirections[rkey] = r
|
||||||
|
|
||||||
// accept all
|
// accept all
|
||||||
|
@ -126,12 +118,9 @@ func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if found == false {
|
if found == false {
|
||||||
log.Debugf("Did not remove redirection '%s' as it was already removed.\n", r.String())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Disabling redirection %s\n", r.String())
|
|
||||||
|
|
||||||
delete(f.redirections, r.String())
|
delete(f.redirections, r.String())
|
||||||
|
|
||||||
if r.SrcAddress == "" {
|
if r.SrcAddress == "" {
|
||||||
|
@ -165,14 +154,13 @@ func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f LinuxFirewall) Restore() {
|
func (f LinuxFirewall) Restore() {
|
||||||
log.Debugf("Restoring firewall state.\n")
|
|
||||||
for _, r := range f.redirections {
|
for _, r := range f.redirections {
|
||||||
if err := f.EnableRedirection(r, false); err != nil {
|
if err := f.EnableRedirection(r, false); err != nil {
|
||||||
log.Error(err)
|
fmt.Printf("%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := f.EnableForwarding(f.forwarding); err != nil {
|
if err := f.EnableForwarding(f.forwarding); err != nil {
|
||||||
log.Error(err)
|
fmt.Printf("%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
main.go
13
main.go
|
@ -5,15 +5,12 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/op/go-logging"
|
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
"github.com/evilsocket/bettercap-ng/core"
|
||||||
"github.com/evilsocket/bettercap-ng/session"
|
"github.com/evilsocket/bettercap-ng/session"
|
||||||
"github.com/evilsocket/bettercap-ng/session/modules"
|
"github.com/evilsocket/bettercap-ng/session/modules"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sess *session.Session
|
var sess *session.Session
|
||||||
var log = logging.MustGetLogger("mitm")
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -32,7 +29,7 @@ func main() {
|
||||||
sess.Register(session_modules.NewRestAPI(sess))
|
sess.Register(session_modules.NewRestAPI(sess))
|
||||||
|
|
||||||
if err = sess.Start(); err != nil {
|
if err = sess.Start(); err != nil {
|
||||||
log.Fatal(err)
|
sess.Events.Log(session.FATAL, "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
|
@ -41,21 +38,21 @@ func main() {
|
||||||
for _, cmd := range strings.Split(*sess.Options.Commands, ";") {
|
for _, cmd := range strings.Split(*sess.Options.Commands, ";") {
|
||||||
cmd = strings.Trim(cmd, "\r\n\t ")
|
cmd = strings.Trim(cmd, "\r\n\t ")
|
||||||
if err = sess.Run(cmd); err != nil {
|
if err = sess.Run(cmd); err != nil {
|
||||||
log.Fatal(err)
|
sess.Events.Log(session.FATAL, "%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *sess.Options.Caplet != "" {
|
if *sess.Options.Caplet != "" {
|
||||||
if err = sess.RunCaplet(*sess.Options.Caplet); err != nil {
|
if err = sess.RunCaplet(*sess.Options.Caplet); err != nil {
|
||||||
log.Fatal(err)
|
sess.Events.Log(session.FATAL, "%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for sess.Active {
|
for sess.Active {
|
||||||
line, err := sess.ReadLine()
|
line, err := sess.ReadLine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
sess.Events.Log(session.FATAL, "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if line == "" || line[0] == '#' {
|
if line == "" || line[0] == '#' {
|
||||||
|
@ -63,7 +60,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = sess.Run(line); err != nil {
|
if err = sess.Run(line); err != nil {
|
||||||
log.Error(err)
|
sess.Events.Log(session.ERROR, "%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/op/go-logging"
|
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
"github.com/evilsocket/bettercap-ng/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArpTable map[string]string
|
type ArpTable map[string]string
|
||||||
|
|
||||||
var (
|
var (
|
||||||
log = logging.MustGetLogger("mitm")
|
|
||||||
arp_parsed = false
|
arp_parsed = false
|
||||||
arp_lock = &sync.Mutex{}
|
arp_lock = &sync.Mutex{}
|
||||||
arp_table = make(ArpTable)
|
arp_table = make(ArpTable)
|
||||||
|
|
|
@ -50,7 +50,6 @@ func NewEndpoint(ip, mac string) *Endpoint {
|
||||||
if names, err := net.LookupAddr(e.IpAddress); err == nil {
|
if names, err := net.LookupAddr(e.IpAddress); err == nil {
|
||||||
e.Hostname = names[0]
|
e.Hostname = names[0]
|
||||||
if e.ResolvedCallback != nil {
|
if e.ResolvedCallback != nil {
|
||||||
// log.Debugf("Endpoint %s is now known as %s\n", e.IpAddress, core.Green(e.Hostname))
|
|
||||||
e.ResolvedCallback(e)
|
e.ResolvedCallback(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,18 +76,15 @@ func FindGateway(iface *Endpoint) (*Endpoint, error) {
|
||||||
|
|
||||||
if ifname == iface.Name() && flags == "UG" {
|
if ifname == iface.Name() && flags == "UG" {
|
||||||
gateway := m[2]
|
gateway := m[2]
|
||||||
// log.Debugf("Gateway ip is %s", gateway)
|
|
||||||
if gateway == iface.IpAddress {
|
if gateway == iface.IpAddress {
|
||||||
// log.Debug("Gateway == Interface")
|
|
||||||
return iface, nil
|
return iface, nil
|
||||||
} else {
|
} else {
|
||||||
// we have the address, now we need its mac
|
// we have the address, now we need its mac
|
||||||
mac, err := ArpLookup(iface.Name(), gateway, false)
|
mac, err := ArpLookup(iface.Name(), gateway, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// log.Debugf("Gateway mac is %s", mac)
|
|
||||||
return NewEndpoint(gateway, mac), nil
|
return NewEndpoint(gateway, mac), nil
|
||||||
} else {
|
} else {
|
||||||
log.Error(err)
|
fmt.Printf("%s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
net/oui.go
10
net/oui.go
|
@ -17,7 +17,7 @@ func OuiInit() {
|
||||||
data := string(bytes)
|
data := string(bytes)
|
||||||
lines := strings.Split(data, "\n")
|
lines := strings.Split(data, "\n")
|
||||||
|
|
||||||
for lineno, line := range lines {
|
for _, line := range lines {
|
||||||
line = strings.Trim(line, " \n\r\t")
|
line = strings.Trim(line, " \n\r\t")
|
||||||
if len(line) == 0 || line[0] == '#' {
|
if len(line) == 0 || line[0] == '#' {
|
||||||
continue
|
continue
|
||||||
|
@ -25,7 +25,6 @@ func OuiInit() {
|
||||||
|
|
||||||
parts := strings.SplitN(line, " ", 2)
|
parts := strings.SplitN(line, " ", 2)
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
log.Warningf("Skipping line %d '%s'\n", lineno+1, line)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +33,6 @@ func OuiInit() {
|
||||||
|
|
||||||
oui[prefix] = vendor
|
oui[prefix] = vendor
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Loaded %d vendors signatures.\n", len(oui))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func OuiLookup(mac string) string {
|
func OuiLookup(mac string) string {
|
||||||
|
@ -46,9 +43,6 @@ func OuiLookup(mac string) string {
|
||||||
if vendor, found := oui[prefix]; found == true {
|
if vendor, found := oui[prefix]; found == true {
|
||||||
return vendor
|
return vendor
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.Warningf("Unexpected mac '%s' in net.OuiLookup\n", mac)
|
|
||||||
}
|
}
|
||||||
|
return ""
|
||||||
return "???"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,9 @@ package packets
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/gopacket/pcap"
|
"github.com/google/gopacket/pcap"
|
||||||
"github.com/op/go-logging"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.MustGetLogger("mitm")
|
|
||||||
|
|
||||||
type Queue struct {
|
type Queue struct {
|
||||||
iface string
|
iface string
|
||||||
handle *pcap.Handle
|
handle *pcap.Handle
|
||||||
|
@ -17,7 +14,6 @@ type Queue struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQueue(iface string) (*Queue, error) {
|
func NewQueue(iface string) (*Queue, error) {
|
||||||
log.Debugf("Creating packet queue for interface %s.\n", iface)
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
q := &Queue{
|
q := &Queue{
|
||||||
|
@ -39,7 +35,6 @@ func (q *Queue) Send(raw []byte) error {
|
||||||
q.lock.Lock()
|
q.lock.Lock()
|
||||||
defer q.lock.Unlock()
|
defer q.lock.Unlock()
|
||||||
|
|
||||||
log.Debugf("Sending %d bytes to packet queue.\n", len(raw))
|
|
||||||
if q.active {
|
if q.active {
|
||||||
return q.handle.WritePacketData(raw)
|
return q.handle.WritePacketData(raw)
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,8 +46,6 @@ func (q *Queue) Stop() {
|
||||||
q.lock.Lock()
|
q.lock.Lock()
|
||||||
defer q.lock.Unlock()
|
defer q.lock.Unlock()
|
||||||
|
|
||||||
log.Debugf("Stopping packet queue.\n")
|
|
||||||
|
|
||||||
q.handle.Close()
|
q.handle.Close()
|
||||||
q.active = false
|
q.active = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,22 @@ package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
"github.com/evilsocket/bettercap-ng/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DEBUG = iota
|
||||||
|
INFO
|
||||||
|
IMPORTANT
|
||||||
|
WARNING
|
||||||
|
ERROR
|
||||||
|
FATAL
|
||||||
|
)
|
||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
|
@ -23,16 +33,20 @@ func NewEvent(tag string, data interface{}) Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Event) Print() {
|
func (e Event) Print() {
|
||||||
fmt.Printf("[%s] [%s] [%s] %+v\n", e.Time, core.Bold("event"), core.Green(e.Tag), e.Data)
|
fmt.Printf("[%s] [%s] %v\n", e.Time, core.Green(e.Tag), e.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventPool struct {
|
type EventPool struct {
|
||||||
|
debug bool
|
||||||
|
silent bool
|
||||||
events []Event
|
events []Event
|
||||||
lock *sync.Mutex
|
lock *sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEventPool() *EventPool {
|
func NewEventPool(debug bool, silent bool) *EventPool {
|
||||||
return &EventPool{
|
return &EventPool{
|
||||||
|
debug: debug,
|
||||||
|
silent: silent,
|
||||||
events: make([]Event, 0),
|
events: make([]Event, 0),
|
||||||
lock: &sync.Mutex{},
|
lock: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
@ -46,6 +60,32 @@ func (p *EventPool) Add(tag string, data interface{}) {
|
||||||
e.Print()
|
e.Print()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *EventPool) Log(level int, format string, args ...interface{}) {
|
||||||
|
if level == DEBUG && p.debug == false {
|
||||||
|
return
|
||||||
|
} else if level < ERROR && p.silent == true {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Add("sys.log", struct {
|
||||||
|
Level int
|
||||||
|
Message string
|
||||||
|
}{
|
||||||
|
level,
|
||||||
|
fmt.Sprintf(format, args...),
|
||||||
|
})
|
||||||
|
|
||||||
|
if level == FATAL {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *EventPool) Clear() {
|
||||||
|
p.lock.Lock()
|
||||||
|
defer p.lock.Unlock()
|
||||||
|
p.events = make([]Event, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *EventPool) Events() []Event {
|
func (p *EventPool) Events() []Event {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
defer p.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
|
||||||
"github.com/evilsocket/bettercap-ng/session"
|
"github.com/evilsocket/bettercap-ng/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ func (api *RestAPI) sessRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
js, err := json.Marshal(api.Session)
|
js, err := json.Marshal(api.Session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while returning session: %s", err)
|
api.Session.Events.Log(session.ERROR, "Error while returning session: %s", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -103,7 +102,7 @@ func (api *RestAPI) sessRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
js, err := json.Marshal(res)
|
js, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while returning response: %s", err)
|
api.Session.Events.Log(session.ERROR, "Error while returning response: %s", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -142,13 +141,18 @@ func (api *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
js, err := json.Marshal(events[0:n])
|
js, err := json.Marshal(events[0:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while returning events: %s", err)
|
api.Session.Events.Log(session.ERROR, "Error while returning events: %s", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write(js)
|
w.Write(js)
|
||||||
|
} else if r.Method == "DELETE" {
|
||||||
|
api.Session.Events.Clear()
|
||||||
|
api.Session.Events.Add("sys.log.cleared", nil)
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.Write([]byte("{}"))
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Not Found", 404)
|
http.Error(w, "Not Found", 404)
|
||||||
}
|
}
|
||||||
|
@ -156,7 +160,7 @@ func (api *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func (api RestAPI) checkAuth(w http.ResponseWriter, r *http.Request) bool {
|
func (api RestAPI) checkAuth(w http.ResponseWriter, r *http.Request) bool {
|
||||||
if api.Authenticated(w, r) == false {
|
if api.Authenticated(w, r) == false {
|
||||||
log.Warningf("Unauthenticated access!")
|
api.Session.Events.Log(session.WARNING, "Unauthenticated access!")
|
||||||
http.Error(w, "Not authorized", 401)
|
http.Error(w, "Not authorized", 401)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -250,10 +254,11 @@ func (api *RestAPI) Start() error {
|
||||||
|
|
||||||
api.server.Addr = fmt.Sprintf("%s:%d", address, port)
|
api.server.Addr = fmt.Sprintf("%s:%d", address, port)
|
||||||
go func() {
|
go func() {
|
||||||
fmt.Printf("[%s] starting on http://%s/ ...\n", core.Green("api"), api.server.Addr)
|
|
||||||
|
api.Session.Events.Log(session.INFO, "API server starting on http://%s", api.server.Addr)
|
||||||
err := api.server.ListenAndServe()
|
err := api.server.ListenAndServe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[%s] %s\n", core.Green("api"), err)
|
api.Session.Events.Log(session.ERROR, "%s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ func (p *ArpSpoofer) getMAC(ip net.IP, probe bool) (net.HardwareAddr, error) {
|
||||||
from_hw := p.Session.Interface.HW
|
from_hw := p.Session.Interface.HW
|
||||||
|
|
||||||
if err, probe := packets.NewUDPProbe(from, from_hw, ip, 139); err != nil {
|
if err, probe := packets.NewUDPProbe(from, from_hw, ip, 139); err != nil {
|
||||||
log.Errorf("Error while creating UDP probe packet for %s: %s\n", ip.String(), err)
|
p.Session.Events.Log(session.ERROR, "Error while creating UDP probe packet for %s: %s\n", ip.String(), err)
|
||||||
} else {
|
} else {
|
||||||
p.Session.Queue.Send(probe)
|
p.Session.Queue.Send(probe)
|
||||||
}
|
}
|
||||||
|
@ -110,21 +110,21 @@ func (p *ArpSpoofer) getMAC(ip net.IP, probe bool) (net.HardwareAddr, error) {
|
||||||
func (p *ArpSpoofer) sendArp(addresses []net.IP, saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) {
|
func (p *ArpSpoofer) sendArp(addresses []net.IP, saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) {
|
||||||
for _, ip := range addresses {
|
for _, ip := range addresses {
|
||||||
if p.shouldSpoof(ip) == false {
|
if p.shouldSpoof(ip) == false {
|
||||||
log.Debugf("Skipping address %s from ARP spoofing.\n", ip)
|
p.Session.Events.Log(session.DEBUG, "Skipping address %s from ARP spoofing.\n", ip)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have this ip mac address?
|
// do we have this ip mac address?
|
||||||
hw, err := p.getMAC(ip, probe)
|
hw, err := p.getMAC(ip, probe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Error while looking up hardware address for %s: %s\n", ip.String(), err)
|
p.Session.Events.Log(session.DEBUG, "Error while looking up hardware address for %s: %s\n", ip.String(), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, pkt := packets.NewARPReply(saddr, smac, ip, hw); err != nil {
|
if err, pkt := packets.NewARPReply(saddr, smac, ip, hw); err != nil {
|
||||||
log.Errorf("Error while creating ARP spoof packet for %s: %s\n", ip.String(), err)
|
p.Session.Events.Log(session.ERROR, "Error while creating ARP spoof packet for %s: %s\n", ip.String(), err)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Sending %d bytes of ARP packet to %s:%s.\n", len(pkt), ip.String(), hw.String())
|
p.Session.Events.Log(session.DEBUG, "Sending %d bytes of ARP packet to %s:%s.\n", len(pkt), ip.String(), hw.String())
|
||||||
p.Session.Queue.Send(pkt)
|
p.Session.Queue.Send(pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ func (p *ArpSpoofer) unSpoof() error {
|
||||||
from := p.Session.Gateway.IP
|
from := p.Session.Gateway.IP
|
||||||
from_hw := p.Session.Gateway.HW
|
from_hw := p.Session.Gateway.HW
|
||||||
|
|
||||||
log.Infof("Restoring ARP cache of %d targets (%s).\n", len(addresses), targets)
|
p.Session.Events.Log(session.INFO, "Restoring ARP cache of %d targets (%s).\n", len(addresses), targets)
|
||||||
|
|
||||||
p.sendArp(addresses, from, from_hw, false, false)
|
p.sendArp(addresses, from, from_hw, false, false)
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ func (p *ArpSpoofer) Start() error {
|
||||||
from := p.Session.Gateway.IP
|
from := p.Session.Gateway.IP
|
||||||
from_hw := p.Session.Interface.HW
|
from_hw := p.Session.Interface.HW
|
||||||
|
|
||||||
log.Infof("ARP spoofer started, probing %d targets (%s).\n", len(addresses), targets)
|
p.Session.Events.Log(session.INFO, "ARP spoofer started, probing %d targets (%s).\n", len(addresses), targets)
|
||||||
|
|
||||||
for p.Running() {
|
for p.Running() {
|
||||||
p.sendArp(addresses, from, from_hw, true, false)
|
p.sendArp(addresses, from, from_hw, true, false)
|
||||||
|
@ -190,7 +190,6 @@ func (p *ArpSpoofer) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Done <- true
|
p.Done <- true
|
||||||
log.Info("ARP spoofer stopped.\n")
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -203,7 +202,7 @@ func (p *ArpSpoofer) Stop() error {
|
||||||
if p.Running() == true {
|
if p.Running() == true {
|
||||||
p.SetRunning(false)
|
p.SetRunning(false)
|
||||||
|
|
||||||
log.Info("Waiting for ARP spoofer to stop ...\n")
|
p.Session.Events.Log(session.INFO, "Waiting for ARP spoofer to stop ...")
|
||||||
|
|
||||||
<-p.Done
|
<-p.Done
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/op/go-logging"
|
|
||||||
|
|
||||||
"github.com/elazarl/goproxy"
|
"github.com/elazarl/goproxy"
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
|
||||||
"github.com/evilsocket/bettercap-ng/firewall"
|
"github.com/evilsocket/bettercap-ng/firewall"
|
||||||
"github.com/evilsocket/bettercap-ng/session"
|
"github.com/evilsocket/bettercap-ng/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.MustGetLogger("mitm")
|
|
||||||
|
|
||||||
type HttpProxy struct {
|
type HttpProxy struct {
|
||||||
session.SessionModule
|
session.SessionModule
|
||||||
|
|
||||||
|
@ -27,13 +22,19 @@ type HttpProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p HttpProxy) logAction(req *http.Request, jsres *JSResponse) {
|
func (p HttpProxy) logAction(req *http.Request, jsres *JSResponse) {
|
||||||
fmt.Printf("[%s] %s > '%s %s%s' | Sending %d bytes of spoofed response.\n",
|
p.Session.Events.Add("http.proxy.spoofed-response", struct {
|
||||||
core.Green("http.proxy"),
|
To string
|
||||||
core.Bold(strings.Split(req.RemoteAddr, ":")[0]),
|
Method string
|
||||||
|
Host string
|
||||||
|
Path string
|
||||||
|
Size int
|
||||||
|
}{
|
||||||
|
strings.Split(req.RemoteAddr, ":")[0],
|
||||||
req.Method,
|
req.Method,
|
||||||
req.Host,
|
req.Host,
|
||||||
req.URL.Path,
|
req.URL.Path,
|
||||||
len(jsres.Body))
|
len(jsres.Body),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpProxy(s *session.Session) *HttpProxy {
|
func NewHttpProxy(s *session.Session) *HttpProxy {
|
||||||
|
@ -169,12 +170,13 @@ func (p *HttpProxy) Start() error {
|
||||||
if err, p.script = LoadProxyScript(scriptPath, p.Session); err != nil {
|
if err, p.script = LoadProxyScript(scriptPath, p.Session); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Proxy script %s loaded.", scriptPath)
|
p.Session.Events.Log(session.DEBUG, "Proxy script %s loaded.", scriptPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Session.Firewall.IsForwardingEnabled() == false {
|
if p.Session.Firewall.IsForwardingEnabled() == false {
|
||||||
|
p.Session.Events.Log(session.INFO, "Enabling forwarding.")
|
||||||
p.Session.Firewall.EnableForwarding(true)
|
p.Session.Firewall.EnableForwarding(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,15 +190,15 @@ func (p *HttpProxy) Start() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
address := fmt.Sprintf("%s:%d", p.address, proxy_port)
|
p.Session.Events.Log(session.DEBUG, "Applied redirection %s", p.redirection.String())
|
||||||
log.Infof("Starting proxy on %s.\n", address)
|
|
||||||
|
|
||||||
|
address := fmt.Sprintf("%s:%d", p.address, proxy_port)
|
||||||
p.server = http.Server{Addr: address, Handler: p.proxy}
|
p.server = http.Server{Addr: address, Handler: p.proxy}
|
||||||
go func() {
|
go func() {
|
||||||
p.SetRunning(true)
|
p.SetRunning(true)
|
||||||
if err := p.server.ListenAndServe(); err != nil {
|
if err := p.server.ListenAndServe(); err != nil {
|
||||||
p.SetRunning(false)
|
p.SetRunning(false)
|
||||||
log.Warning(err)
|
p.Session.Events.Log(session.WARNING, "%s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -207,8 +209,8 @@ func (p *HttpProxy) Stop() error {
|
||||||
if p.Running() == true {
|
if p.Running() == true {
|
||||||
p.SetRunning(false)
|
p.SetRunning(false)
|
||||||
p.server.Shutdown(nil)
|
p.server.Shutdown(nil)
|
||||||
log.Info("HTTP proxy stopped.\n")
|
|
||||||
if p.redirection != nil {
|
if p.redirection != nil {
|
||||||
|
p.Session.Events.Log(session.DEBUG, "Disabling redirection %s", p.redirection.String())
|
||||||
if err := p.Session.Firewall.EnableRedirection(p.redirection, false); err != nil {
|
if err := p.Session.Firewall.EnableRedirection(p.redirection, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -228,13 +230,13 @@ func (p HttpProxy) doProxy(req *http.Request) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Host == "" {
|
if req.Host == "" {
|
||||||
log.Errorf("Got request with empty host: %v\n", req)
|
p.Session.Events.Log(session.ERROR, "Got request with empty host: %v", req)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, blacklisted := range blacklist {
|
for _, blacklisted := range blacklist {
|
||||||
if strings.HasPrefix(req.Host, blacklisted) {
|
if strings.HasPrefix(req.Host, blacklisted) {
|
||||||
log.Errorf("Got request with blacklisted host: %s\n", req.Host)
|
p.Session.Events.Log(session.ERROR, "Got request with blacklisted host: %s", req.Host)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ func NewJSRequest(req *http.Request) JSRequest {
|
||||||
func (j *JSRequest) ReadBody() string {
|
func (j *JSRequest) ReadBody() string {
|
||||||
raw, err := ioutil.ReadAll(j.req.Body)
|
raw, err := ioutil.ReadAll(j.req.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Could not read request body: %s", err)
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,6 @@ func (j *JSResponse) ToResponse(req *http.Request) (resp *http.Response) {
|
||||||
parts := strings.SplitN(header, ":", 2)
|
parts := strings.SplitN(header, ":", 2)
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
resp.Header.Add(parts[0], parts[1])
|
resp.Header.Add(parts[0], parts[1])
|
||||||
} else {
|
|
||||||
log.Warningf("Unexpected header '%s'", header)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +65,6 @@ func (j *JSResponse) ReadBody() string {
|
||||||
|
|
||||||
raw, err := ioutil.ReadAll(j.resp.Body)
|
raw, err := ioutil.ReadAll(j.resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Could not read response body: %s", err)
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ type ProxyScript struct {
|
||||||
Source string
|
Source string
|
||||||
VM *otto.Otto
|
VM *otto.Otto
|
||||||
|
|
||||||
|
sess *session.Session
|
||||||
gil *sync.Mutex
|
gil *sync.Mutex
|
||||||
onRequestScript *otto.Script
|
onRequestScript *otto.Script
|
||||||
onResponseScript *otto.Script
|
onResponseScript *otto.Script
|
||||||
|
@ -23,7 +24,7 @@ type ProxyScript struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScript) {
|
func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScript) {
|
||||||
log.Infof("Loading proxy script %s ...", path)
|
sess.Events.Log(session.INFO, "Loading proxy script %s ...", path)
|
||||||
|
|
||||||
raw, err := ioutil.ReadFile(path)
|
raw, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -35,6 +36,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr
|
||||||
Source: string(raw),
|
Source: string(raw),
|
||||||
VM: otto.New(),
|
VM: otto.New(),
|
||||||
|
|
||||||
|
sess: sess,
|
||||||
gil: &sync.Mutex{},
|
gil: &sync.Mutex{},
|
||||||
onRequestScript: nil,
|
onRequestScript: nil,
|
||||||
onResponseScript: nil,
|
onResponseScript: nil,
|
||||||
|
@ -51,7 +53,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr
|
||||||
// define session pointer
|
// define session pointer
|
||||||
err = s.VM.Set("env", sess.Env.Storage)
|
err = s.VM.Set("env", sess.Env.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while defining environment: %s", err)
|
sess.Events.Log(session.ERROR, "Error while defining environment: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +61,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr
|
||||||
if s.hasCallback("onLoad") {
|
if s.hasCallback("onLoad") {
|
||||||
_, err = s.VM.Run("onLoad()")
|
_, err = s.VM.Run("onLoad()")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while executing onLoad callback: %s", err)
|
sess.Events.Log(session.ERROR, "Error while executing onLoad callback: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +70,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr
|
||||||
if s.hasCallback("onRequest") {
|
if s.hasCallback("onRequest") {
|
||||||
s.onRequestScript, err = s.VM.Compile("", "onRequest(req, res)")
|
s.onRequestScript, err = s.VM.Compile("", "onRequest(req, res)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while compiling onRequest callback: %s", err)
|
sess.Events.Log(session.ERROR, "Error while compiling onRequest callback: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +79,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr
|
||||||
if s.hasCallback("onResponse") {
|
if s.hasCallback("onResponse") {
|
||||||
s.onResponseScript, err = s.VM.Compile("", "onResponse(req, res)")
|
s.onResponseScript, err = s.VM.Compile("", "onResponse(req, res)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while compiling onResponse callback: %s", err)
|
sess.Events.Log(session.ERROR, "Error while compiling onResponse callback: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,13 +111,13 @@ func (s *ProxyScript) doRequestDefines(req *http.Request) (err error, jsres *JSR
|
||||||
// convert request and define empty response to be optionally filled
|
// convert request and define empty response to be optionally filled
|
||||||
jsreq := NewJSRequest(req)
|
jsreq := NewJSRequest(req)
|
||||||
if err = s.VM.Set("req", &jsreq); err != nil {
|
if err = s.VM.Set("req", &jsreq); err != nil {
|
||||||
log.Errorf("Error while defining request: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while defining request: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jsres = &JSResponse{}
|
jsres = &JSResponse{}
|
||||||
if err = s.VM.Set("res", jsres); err != nil {
|
if err = s.VM.Set("res", jsres); err != nil {
|
||||||
log.Errorf("Error while defining response: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while defining response: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,13 +128,13 @@ func (s *ProxyScript) doResponseDefines(res *http.Response) (err error, jsres *J
|
||||||
// convert both request and response
|
// convert both request and response
|
||||||
jsreq := NewJSRequest(res.Request)
|
jsreq := NewJSRequest(res.Request)
|
||||||
if err = s.VM.Set("req", jsreq); err != nil {
|
if err = s.VM.Set("req", jsreq); err != nil {
|
||||||
log.Errorf("Error while defining request: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while defining request: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jsres = NewJSResponse(res)
|
jsres = NewJSResponse(res)
|
||||||
if err = s.VM.Set("res", jsres); err != nil {
|
if err = s.VM.Set("res", jsres); err != nil {
|
||||||
log.Errorf("Error while defining response: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while defining response: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,13 +148,13 @@ func (s *ProxyScript) OnRequest(req *http.Request) *JSResponse {
|
||||||
|
|
||||||
err, jsres := s.doRequestDefines(req)
|
err, jsres := s.doRequestDefines(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while running bootstrap definitions: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while running bootstrap definitions: %s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.VM.Run(s.onRequestScript)
|
_, err = s.VM.Run(s.onRequestScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while executing onRequest callback: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while executing onRequest callback: %s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,13 +173,13 @@ func (s *ProxyScript) OnResponse(res *http.Response) *JSResponse {
|
||||||
|
|
||||||
err, jsres := s.doResponseDefines(res)
|
err, jsres := s.doResponseDefines(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while running bootstrap definitions: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while running bootstrap definitions: %s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.VM.Run(s.onResponseScript)
|
_, err = s.VM.Run(s.onResponseScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while executing onRequest callback: %s", err)
|
s.sess.Events.Log(session.ERROR, "Error while executing onRequest callback: %s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,12 @@ package session_modules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
// "github.com/evilsocket/bettercap-ng/packets"
|
|
||||||
"github.com/evilsocket/bettercap-ng/session"
|
|
||||||
"github.com/malfunkt/iprange"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/evilsocket/bettercap-ng/session"
|
||||||
|
|
||||||
|
"github.com/malfunkt/iprange"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Prober struct {
|
type Prober struct {
|
||||||
|
@ -72,11 +73,11 @@ func (p Prober) OnSessionEnded(s *session.Session) {
|
||||||
func (p *Prober) sendProbe(from net.IP, from_hw net.HardwareAddr, ip net.IP) {
|
func (p *Prober) sendProbe(from net.IP, from_hw net.HardwareAddr, ip net.IP) {
|
||||||
name := fmt.Sprintf("%s:137", ip)
|
name := fmt.Sprintf("%s:137", ip)
|
||||||
if addr, err := net.ResolveUDPAddr("udp", name); err != nil {
|
if addr, err := net.ResolveUDPAddr("udp", name); err != nil {
|
||||||
log.Errorf("Could not resolve %s.", name)
|
p.Session.Events.Log(session.ERROR, "Could not resolve %s.", name)
|
||||||
} else if con, err := net.DialUDP("udp", nil, addr); err != nil {
|
} else if con, err := net.DialUDP("udp", nil, addr); err != nil {
|
||||||
log.Errorf("Could not dial %s.", name)
|
p.Session.Events.Log(session.ERROR, "Could not dial %s.", name)
|
||||||
} else {
|
} else {
|
||||||
// log.Debugf("UDP connection to %s enstablished.\n", name)
|
// p.Session.Events.Log(session.DEBUG,"UDP connection to %s enstablished.\n", name)
|
||||||
defer con.Close()
|
defer con.Close()
|
||||||
con.Write([]byte{0xde, 0xad, 0xbe, 0xef})
|
con.Write([]byte{0xde, 0xad, 0xbe, 0xef})
|
||||||
}
|
}
|
||||||
|
@ -89,7 +90,7 @@ func (p *Prober) Start() error {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
throttle = v.(int)
|
throttle = v.(int)
|
||||||
log.Debugf("Throttling packets of %d ms.\n", throttle)
|
p.Session.Events.Log(session.DEBUG, "Throttling packets of %d ms.", throttle)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.SetRunning(true)
|
p.SetRunning(true)
|
||||||
|
@ -97,19 +98,17 @@ func (p *Prober) Start() error {
|
||||||
go func() {
|
go func() {
|
||||||
list, err := iprange.Parse(p.Session.Interface.CIDR())
|
list, err := iprange.Parse(p.Session.Interface.CIDR())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
p.Session.Events.Log(session.FATAL, "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
from := p.Session.Interface.IP
|
from := p.Session.Interface.IP
|
||||||
from_hw := p.Session.Interface.HW
|
from_hw := p.Session.Interface.HW
|
||||||
addresses := list.Expand()
|
addresses := list.Expand()
|
||||||
|
|
||||||
log.Infof("Network prober started, probing %d possible addresses.\n", len(addresses))
|
|
||||||
|
|
||||||
for p.Running() {
|
for p.Running() {
|
||||||
for _, ip := range addresses {
|
for _, ip := range addresses {
|
||||||
if p.shouldProbe(ip) == false {
|
if p.shouldProbe(ip) == false {
|
||||||
log.Debugf("Skipping address %s from UDP probing.\n", ip)
|
p.Session.Events.Log(session.DEBUG, "Skipping address %s from UDP probing.", ip)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +121,6 @@ func (p *Prober) Start() error {
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Network prober stopped.\n")
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -70,7 +70,7 @@ func (d *Discovery) Start() error {
|
||||||
d.SetRunning(true)
|
d.SetRunning(true)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Info("Network discovery started.\n")
|
d.Session.Events.Log(session.INFO, "Network discovery started.")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -78,7 +78,7 @@ func (d *Discovery) Start() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if d.current, err = net.ArpUpdate(d.Session.Interface.Name()); err != nil {
|
if d.current, err = net.ArpUpdate(d.Session.Interface.Name()); err != nil {
|
||||||
log.Error(err)
|
d.Session.Events.Log(session.ERROR, "%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ func (d *Discovery) Start() error {
|
||||||
b = ""
|
b = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warningf("WARNING: Found %d endpoint%s which share%s the same MAC of the gateway (%s), there're might be some IP isolation going on, skipping.\n", n_gw_shared, a, b, d.Session.Gateway.HwAddress)
|
d.Session.Events.Log(session.WARNING, "WARNING: Found %d endpoint%s which share%s the same MAC of the gateway (%s), there're might be some IP isolation going on, skipping.", n_gw_shared, a, b, d.Session.Gateway.HwAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh target pool
|
// refresh target pool
|
||||||
|
@ -127,7 +127,7 @@ func (d *Discovery) Start() error {
|
||||||
d.before = d.current
|
d.before = d.current
|
||||||
|
|
||||||
case <-d.quit:
|
case <-d.quit:
|
||||||
log.Info("Network discovery stopped.\n")
|
d.Session.Events.Log(session.INFO, "Network discovery stopped.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,34 +45,30 @@ var (
|
||||||
yes = core.Green("yes")
|
yes = core.Green("yes")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *SnifferContext) Log() {
|
func (c *SnifferContext) Log(sess *session.Session) {
|
||||||
log.Info("\n")
|
|
||||||
|
|
||||||
if c.DumpLocal {
|
if c.DumpLocal {
|
||||||
log.Info(" Skip local packets : " + no)
|
sess.Events.Log(session.INFO, "Skip local packets : "+no)
|
||||||
} else {
|
} else {
|
||||||
log.Info(" Skip local packets : " + yes)
|
sess.Events.Log(session.INFO, "Skip local packets : "+yes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Verbose {
|
if c.Verbose {
|
||||||
log.Info(" Verbose : " + yes)
|
sess.Events.Log(session.INFO, "Verbose : "+yes)
|
||||||
} else {
|
} else {
|
||||||
log.Info(" Verbose : " + no)
|
sess.Events.Log(session.INFO, "Verbose : "+no)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Filter != "" {
|
if c.Filter != "" {
|
||||||
log.Info(" BPF Filter : '" + core.Yellow(c.Filter) + "'")
|
sess.Events.Log(session.INFO, "BPF Filter : '"+core.Yellow(c.Filter)+"'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Expression != "" {
|
if c.Expression != "" {
|
||||||
log.Info(" Regular expression : '" + core.Yellow(c.Expression) + "'")
|
sess.Events.Log(session.INFO, "Regular expression : '"+core.Yellow(c.Expression)+"'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Output != "" {
|
if c.Output != "" {
|
||||||
log.Info(" File output : '" + core.Yellow(c.Output) + "'")
|
sess.Events.Log(session.INFO, "File output : '"+core.Yellow(c.Output)+"'")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SnifferContext) Close() {
|
func (c *SnifferContext) Close() {
|
||||||
|
@ -272,7 +268,7 @@ func (s *Sniffer) PrintStats() error {
|
||||||
return fmt.Errorf("No stats yet.")
|
return fmt.Errorf("No stats yet.")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Ctx.Log()
|
s.Ctx.Log(s.Session)
|
||||||
|
|
||||||
first := "never"
|
first := "never"
|
||||||
last := "never"
|
last := "never"
|
||||||
|
@ -285,13 +281,13 @@ func (s *Sniffer) PrintStats() error {
|
||||||
last = s.Stats.LastPacket.String()
|
last = s.Stats.LastPacket.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof(" Sniffer Started : %s\n", s.Stats.Started)
|
s.Session.Events.Log(session.INFO, "Sniffer Started : %s", s.Stats.Started)
|
||||||
log.Infof(" First Packet Seen : %s\n", first)
|
s.Session.Events.Log(session.INFO, "First Packet Seen : %s", first)
|
||||||
log.Infof(" Last Packet Seen : %s\n", last)
|
s.Session.Events.Log(session.INFO, "Last Packet Seen : %s", last)
|
||||||
log.Infof(" Local Packets : %d\n", s.Stats.NumLocal)
|
s.Session.Events.Log(session.INFO, "Local Packets : %d", s.Stats.NumLocal)
|
||||||
log.Infof(" Matched Packets : %d\n", s.Stats.NumMatched)
|
s.Session.Events.Log(session.INFO, "Matched Packets : %d", s.Stats.NumMatched)
|
||||||
log.Infof(" Dumped Packets : %d\n", s.Stats.NumDumped)
|
s.Session.Events.Log(session.INFO, "Dumped Packets : %d", s.Stats.NumDumped)
|
||||||
log.Infof(" Wrote Packets : %d\n", s.Stats.NumWrote)
|
s.Session.Events.Log(session.INFO, "Wrote Packets : %d", s.Stats.NumWrote)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -314,8 +310,6 @@ func (s *Sniffer) Start() error {
|
||||||
go func() {
|
go func() {
|
||||||
defer s.Ctx.Close()
|
defer s.Ctx.Close()
|
||||||
|
|
||||||
log.Info("Network sniffer started.\n")
|
|
||||||
|
|
||||||
src := gopacket.NewPacketSource(s.Ctx.Handle, s.Ctx.Handle.LinkType())
|
src := gopacket.NewPacketSource(s.Ctx.Handle, s.Ctx.Handle.LinkType())
|
||||||
for packet := range src.Packets() {
|
for packet := range src.Packets() {
|
||||||
if s.Running() == false {
|
if s.Running() == false {
|
||||||
|
@ -351,8 +345,6 @@ func (s *Sniffer) Start() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Network sniffer stopped.\n")
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/chzyer/readline"
|
"github.com/chzyer/readline"
|
||||||
"github.com/op/go-logging"
|
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
"github.com/evilsocket/bettercap-ng/core"
|
||||||
"github.com/evilsocket/bettercap-ng/firewall"
|
"github.com/evilsocket/bettercap-ng/firewall"
|
||||||
|
@ -51,30 +50,22 @@ func New() (*Session, error) {
|
||||||
Modules: make([]Module, 0),
|
Modules: make([]Module, 0),
|
||||||
HelpPadding: 0,
|
HelpPadding: 0,
|
||||||
|
|
||||||
Events: NewEventPool(),
|
Events: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Env = NewEnvironment(s)
|
|
||||||
|
|
||||||
if s.Options, err = core.ParseOptions(); err != nil {
|
if s.Options, err = core.ParseOptions(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.Env = NewEnvironment(s)
|
||||||
|
s.Events = NewEventPool(*s.Options.Debug, *s.Options.Silent)
|
||||||
|
|
||||||
if u, err := user.Current(); err != nil {
|
if u, err := user.Current(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if u.Uid != "0" {
|
} else if u.Uid != "0" {
|
||||||
return nil, fmt.Errorf("This software must run as root.")
|
return nil, fmt.Errorf("This software must run as root.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup logging
|
|
||||||
if *s.Options.Debug == true {
|
|
||||||
logging.SetLevel(logging.DEBUG, "")
|
|
||||||
} else if *s.Options.Silent == true {
|
|
||||||
logging.SetLevel(logging.ERROR, "")
|
|
||||||
} else {
|
|
||||||
logging.SetLevel(logging.INFO, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.registerCoreHandlers()
|
s.registerCoreHandlers()
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
|
@ -206,7 +197,6 @@ func (s *Session) registerCoreHandlers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Env.Set(key, value)
|
s.Env.Set(key, value)
|
||||||
fmt.Printf(" %s => '%s'\n", core.Green(key), core.Yellow(value))
|
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -251,21 +241,6 @@ func (s *Session) setupInput() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// now that we have the readline instance, we can set logging to its
|
|
||||||
// console writer so the whole thing gets correctly updated when something
|
|
||||||
// is logged to screen (it won't overlap with the prompt).
|
|
||||||
log_be := logging.NewLogBackend(s.Input.Stderr(), "", 0)
|
|
||||||
log_level := logging.AddModuleLevel(log_be)
|
|
||||||
if *s.Options.Debug == true {
|
|
||||||
log_level.SetLevel(logging.DEBUG, "")
|
|
||||||
} else if *s.Options.Silent == true {
|
|
||||||
log_level.SetLevel(logging.ERROR, "")
|
|
||||||
} else {
|
|
||||||
log_level.SetLevel(logging.INFO, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
logging.SetBackend(log_level)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,11 +277,8 @@ func (s *Session) Start() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("[%s%s%s] %s\n", core.GREEN, s.Interface.Name(), core.RESET, s.Interface)
|
|
||||||
log.Debugf("[%ssubnet%s] %s\n", core.GREEN, core.RESET, s.Interface.CIDR())
|
|
||||||
|
|
||||||
if s.Gateway, err = net.FindGateway(s.Interface); err != nil {
|
if s.Gateway, err = net.FindGateway(s.Interface); err != nil {
|
||||||
log.Warningf("%s\n", err)
|
s.Events.Log(WARNING, "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Gateway == nil || s.Gateway.IpAddress == s.Interface.IpAddress {
|
if s.Gateway == nil || s.Gateway.IpAddress == s.Interface.IpAddress {
|
||||||
|
@ -316,8 +288,6 @@ func (s *Session) Start() error {
|
||||||
s.Env.Set("gateway.address", s.Gateway.IpAddress)
|
s.Env.Set("gateway.address", s.Gateway.IpAddress)
|
||||||
s.Env.Set("gateway.mac", s.Gateway.HwAddress)
|
s.Env.Set("gateway.mac", s.Gateway.HwAddress)
|
||||||
|
|
||||||
log.Debugf("[%sgateway%s] %s\n", core.GREEN, core.RESET, s.Gateway)
|
|
||||||
|
|
||||||
s.Targets = NewTargets(s, s.Interface, s.Gateway)
|
s.Targets = NewTargets(s, s.Interface, s.Gateway)
|
||||||
s.Firewall = firewall.Make()
|
s.Firewall = firewall.Make()
|
||||||
|
|
||||||
|
@ -350,7 +320,7 @@ func (s *Session) Start() error {
|
||||||
go func() {
|
go func() {
|
||||||
<-c
|
<-c
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
log.Warning("Got SIGTERM ...")
|
s.Events.Log(WARNING, "Got SIGTERM")
|
||||||
s.Close()
|
s.Close()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}()
|
}()
|
||||||
|
@ -373,7 +343,7 @@ func (s *Session) ReadLine() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) RunCaplet(filename string) error {
|
func (s *Session) RunCaplet(filename string) error {
|
||||||
log.Infof("Reading from caplet %s ...\n", filename)
|
s.Events.Log(INFO, "Reading from caplet %s ...\n", filename)
|
||||||
|
|
||||||
input, err := os.Open(filename)
|
input, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,14 +5,10 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/op/go-logging"
|
|
||||||
|
|
||||||
"github.com/evilsocket/bettercap-ng/core"
|
"github.com/evilsocket/bettercap-ng/core"
|
||||||
"github.com/evilsocket/bettercap-ng/net"
|
"github.com/evilsocket/bettercap-ng/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.MustGetLogger("mitm")
|
|
||||||
|
|
||||||
type Targets struct {
|
type Targets struct {
|
||||||
Session *Session `json:"-"`
|
Session *Session `json:"-"`
|
||||||
Interface *net.Endpoint
|
Interface *net.Endpoint
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue