mirror of
https://github.com/bettercap/bettercap
synced 2025-07-05 20:42:09 -07:00
new: basic ipv6 support
This commit is contained in:
parent
d0b5c34763
commit
bef4c6abaa
8 changed files with 115 additions and 35 deletions
|
@ -55,6 +55,11 @@ func httpGrabber(mod *SynScanner, ip string, port int) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/12260003/connect-returns-invalid-argument-with-ipv6-address
|
||||||
|
if strings.Contains(ip, ":") {
|
||||||
|
ip = fmt.Sprintf("[%s%%25%s]", ip, mod.Session.Interface.Name())
|
||||||
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("%s://%s:%d/", schema, ip, port)
|
url := fmt.Sprintf("%s://%s:%d/", schema, ip, port)
|
||||||
resp, err := client.Get(url)
|
resp, err := client.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -167,6 +167,12 @@ type scanJob struct {
|
||||||
func (mod *SynScanner) scanWorker(job async.Job) {
|
func (mod *SynScanner) scanWorker(job async.Job) {
|
||||||
scan := job.(scanJob)
|
scan := job.(scanJob)
|
||||||
|
|
||||||
|
fromHW := mod.Session.Interface.HW
|
||||||
|
fromIP := mod.Session.Interface.IP
|
||||||
|
if scan.Address.To4() == nil {
|
||||||
|
fromIP = mod.Session.Interface.IPv6
|
||||||
|
}
|
||||||
|
|
||||||
for dstPort := mod.startPort; dstPort < mod.endPort+1; dstPort++ {
|
for dstPort := mod.startPort; dstPort < mod.endPort+1; dstPort++ {
|
||||||
if !mod.Running() {
|
if !mod.Running() {
|
||||||
break
|
break
|
||||||
|
@ -174,7 +180,7 @@ func (mod *SynScanner) scanWorker(job async.Job) {
|
||||||
|
|
||||||
atomic.AddUint64(&mod.stats.doneProbes, 1)
|
atomic.AddUint64(&mod.stats.doneProbes, 1)
|
||||||
|
|
||||||
err, raw := packets.NewTCPSyn(mod.Session.Interface.IP, mod.Session.Interface.HW, scan.Address, scan.Mac, synSourcePort, dstPort)
|
err, raw := packets.NewTCPSyn(fromIP, fromHW, scan.Address, scan.Mac, synSourcePort, dstPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mod.Error("error creating SYN packet: %s", err)
|
mod.Error("error creating SYN packet: %s", err)
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -2,18 +2,30 @@ package syn_scan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/evilsocket/islazy/str"
|
"github.com/evilsocket/islazy/str"
|
||||||
"github.com/malfunkt/iprange"
|
"github.com/malfunkt/iprange"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mod *SynScanner) parseTargets(arg string) error {
|
func (mod *SynScanner) parseTargets(arg string) error {
|
||||||
if list, err := iprange.Parse(arg); err != nil {
|
if strings.Contains(arg, ":") {
|
||||||
return fmt.Errorf("error while parsing IP range '%s': %s", arg, err)
|
// parse as IPv6 address
|
||||||
|
if ip := net.ParseIP(arg); ip == nil {
|
||||||
|
return fmt.Errorf("error while parsing IPv6 '%s'", arg)
|
||||||
|
} else {
|
||||||
|
mod.addresses = []net.IP{ip}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mod.addresses = list.Expand()
|
if list, err := iprange.Parse(arg); err != nil {
|
||||||
|
return fmt.Errorf("error while parsing IP range '%s': %s", arg, err)
|
||||||
|
} else {
|
||||||
|
mod.addresses = list.Expand()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,26 +24,40 @@ func (mod *SynScanner) onPacket(pkt gopacket.Packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var eth layers.Ethernet
|
var eth layers.Ethernet
|
||||||
var ip layers.IPv4
|
var ip4 layers.IPv4
|
||||||
|
var ip6 layers.IPv6
|
||||||
var tcp layers.TCP
|
var tcp layers.TCP
|
||||||
foundLayerTypes := []gopacket.LayerType{}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
isIPv6 := false
|
||||||
|
foundLayerTypes := []gopacket.LayerType{}
|
||||||
parser := gopacket.NewDecodingLayerParser(
|
parser := gopacket.NewDecodingLayerParser(
|
||||||
layers.LayerTypeEthernet,
|
layers.LayerTypeEthernet,
|
||||||
ð,
|
ð,
|
||||||
&ip,
|
&ip4,
|
||||||
&tcp,
|
&tcp,
|
||||||
)
|
)
|
||||||
|
|
||||||
err := parser.DecodeLayers(pkt.Data(), &foundLayerTypes)
|
err := parser.DecodeLayers(pkt.Data(), &foundLayerTypes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
// try ipv6
|
||||||
|
parser := gopacket.NewDecodingLayerParser(
|
||||||
|
layers.LayerTypeEthernet,
|
||||||
|
ð,
|
||||||
|
&ip6,
|
||||||
|
&tcp,
|
||||||
|
)
|
||||||
|
err = parser.DecodeLayers(pkt.Data(), &foundLayerTypes)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isIPv6 = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK {
|
if tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK {
|
||||||
atomic.AddUint64(&mod.stats.openPorts, 1)
|
atomic.AddUint64(&mod.stats.openPorts, 1)
|
||||||
|
|
||||||
from := ip.SrcIP.String()
|
|
||||||
port := int(tcp.SrcPort)
|
port := int(tcp.SrcPort)
|
||||||
|
|
||||||
openPort := &OpenPort{
|
openPort := &OpenPort{
|
||||||
|
@ -53,12 +67,28 @@ func (mod *SynScanner) onPacket(pkt gopacket.Packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var host *network.Endpoint
|
var host *network.Endpoint
|
||||||
if ip.SrcIP.Equal(mod.Session.Interface.IP) {
|
|
||||||
host = mod.Session.Interface
|
from := ""
|
||||||
} else if ip.SrcIP.Equal(mod.Session.Gateway.IP) {
|
|
||||||
host = mod.Session.Gateway
|
if isIPv6 {
|
||||||
|
from = ip6.SrcIP.String()
|
||||||
|
if ip6.SrcIP.Equal(mod.Session.Interface.IPv6) {
|
||||||
|
host = mod.Session.Interface
|
||||||
|
} else if ip6.SrcIP.Equal(mod.Session.Gateway.IPv6) {
|
||||||
|
host = mod.Session.Gateway
|
||||||
|
} else {
|
||||||
|
host = mod.Session.Lan.GetByIp(from)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
host = mod.Session.Lan.GetByIp(from)
|
from = ip4.SrcIP.String()
|
||||||
|
|
||||||
|
if ip4.SrcIP.Equal(mod.Session.Interface.IP) {
|
||||||
|
host = mod.Session.Interface
|
||||||
|
} else if ip4.SrcIP.Equal(mod.Session.Gateway.IP) {
|
||||||
|
host = mod.Session.Gateway
|
||||||
|
} else {
|
||||||
|
host = mod.Session.Lan.GetByIp(from)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if host != nil {
|
if host != nil {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package network
|
||||||
|
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
var ArpTableParser = regexp.MustCompile(`^([\d\.]+)\s+dev\s+(\w+)\s+\w+\s+([a-f0-9:]{17})\s+\w+$`)
|
var ArpTableParser = regexp.MustCompile(`^([a-f\d\.:]+)\s+dev\s+(\w+)\s+\w+\s+([a-f0-9:]{17})\s+\w+$`)
|
||||||
var ArpTableTokens = 4
|
var ArpTableTokens = 4
|
||||||
var ArpTableTokenIndex = []int{1, 3, 2}
|
var ArpTableTokenIndex = []int{1, 3, 2}
|
||||||
var ArpCmd = "ip"
|
var ArpCmd = "ip"
|
||||||
|
|
|
@ -153,7 +153,7 @@ func (lan *LAN) shouldIgnore(ip, mac string) bool {
|
||||||
}
|
}
|
||||||
// skip everything which is not in our subnet (multicast noise)
|
// skip everything which is not in our subnet (multicast noise)
|
||||||
addr := net.ParseIP(ip)
|
addr := net.ParseIP(ip)
|
||||||
return !lan.iface.Net.Contains(addr)
|
return addr.To4() != nil && !lan.iface.Net.Contains(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lan *LAN) Has(ip string) bool {
|
func (lan *LAN) Has(ip string) bool {
|
||||||
|
|
|
@ -6,24 +6,50 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTCPSyn(from net.IP, from_hw net.HardwareAddr, to net.IP, to_hw net.HardwareAddr, srcPort int, dstPort int) (error, []byte) {
|
func NewTCPSyn(from net.IP, from_hw net.HardwareAddr, to net.IP, to_hw net.HardwareAddr, srcPort int, dstPort int) (error, []byte) {
|
||||||
eth := layers.Ethernet{
|
from4 := from.To4()
|
||||||
SrcMAC: from_hw,
|
to4 := to.To4()
|
||||||
DstMAC: to_hw,
|
|
||||||
EthernetType: layers.EthernetTypeIPv4,
|
|
||||||
}
|
|
||||||
ip4 := layers.IPv4{
|
|
||||||
Protocol: layers.IPProtocolTCP,
|
|
||||||
Version: 4,
|
|
||||||
TTL: 64,
|
|
||||||
SrcIP: from,
|
|
||||||
DstIP: to,
|
|
||||||
}
|
|
||||||
tcp := layers.TCP{
|
|
||||||
SrcPort: layers.TCPPort(srcPort),
|
|
||||||
DstPort: layers.TCPPort(dstPort),
|
|
||||||
SYN: true,
|
|
||||||
}
|
|
||||||
tcp.SetNetworkLayerForChecksum(&ip4)
|
|
||||||
|
|
||||||
return Serialize(ð, &ip4, &tcp)
|
if from4 != nil && to4 != nil {
|
||||||
|
eth := layers.Ethernet{
|
||||||
|
SrcMAC: from_hw,
|
||||||
|
DstMAC: to_hw,
|
||||||
|
EthernetType: layers.EthernetTypeIPv4,
|
||||||
|
}
|
||||||
|
ip4 := layers.IPv4{
|
||||||
|
Protocol: layers.IPProtocolTCP,
|
||||||
|
Version: 4,
|
||||||
|
TTL: 64,
|
||||||
|
SrcIP: from,
|
||||||
|
DstIP: to,
|
||||||
|
}
|
||||||
|
tcp := layers.TCP{
|
||||||
|
SrcPort: layers.TCPPort(srcPort),
|
||||||
|
DstPort: layers.TCPPort(dstPort),
|
||||||
|
SYN: true,
|
||||||
|
}
|
||||||
|
tcp.SetNetworkLayerForChecksum(&ip4)
|
||||||
|
|
||||||
|
return Serialize(ð, &ip4, &tcp)
|
||||||
|
} else {
|
||||||
|
eth := layers.Ethernet{
|
||||||
|
SrcMAC: from_hw,
|
||||||
|
DstMAC: to_hw,
|
||||||
|
EthernetType: layers.EthernetTypeIPv6,
|
||||||
|
}
|
||||||
|
ip6 := layers.IPv6{
|
||||||
|
Version: 6,
|
||||||
|
NextHeader: layers.IPProtocolTCP,
|
||||||
|
HopLimit: 64,
|
||||||
|
SrcIP: from,
|
||||||
|
DstIP: to,
|
||||||
|
}
|
||||||
|
tcp := layers.TCP{
|
||||||
|
SrcPort: layers.TCPPort(srcPort),
|
||||||
|
DstPort: layers.TCPPort(dstPort),
|
||||||
|
SYN: true,
|
||||||
|
}
|
||||||
|
tcp.SetNetworkLayerForChecksum(&ip6)
|
||||||
|
|
||||||
|
return Serialize(ð, &ip6, &tcp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
const (
|
const (
|
||||||
IPv4Validator = `^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$`
|
IPv4Validator = `^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$`
|
||||||
IPv6Validator = `^[:a-fA-F0-9]{6,}$`
|
IPv6Validator = `^[:a-fA-F0-9]{6,}$`
|
||||||
|
IPValidator = `^[\.:a-fA-F0-9]{6,}$`
|
||||||
)
|
)
|
||||||
|
|
||||||
type ModuleHandler struct {
|
type ModuleHandler struct {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue