From 58b6a827d0a236cbcd8f06b0631f8cbe4de3cb72 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 18 Feb 2021 03:14:39 +0100 Subject: [PATCH] arp-spoofer: new package --- Makefile | 6 ++- pkg/arp-spoofer/Dockerfile | 20 ++++++++ pkg/arp-spoofer/build.yml | 2 + pkg/arp-spoofer/cmd/arp.go | 97 +++++++++++++++++++++++++++++++++++++ pkg/arp-spoofer/cmd/main.go | 26 ++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 pkg/arp-spoofer/Dockerfile create mode 100644 pkg/arp-spoofer/build.yml create mode 100644 pkg/arp-spoofer/cmd/arp.go create mode 100644 pkg/arp-spoofer/cmd/main.go diff --git a/Makefile b/Makefile index 5d2edd3..278134f 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,10 @@ challenge-initrd.img: challenge.yml subject/adlin.6.gz subject/adlin-TP1-topolog linuxkit build -docker $< +pkg/arp-spoofer: pkg/arp-spoofer/cmd/main.go pkg/arp-spoofer/cmd/arp.go pkg/arp-spoofer/build.yml pkg/arp-spoofer/Dockerfile + linuxkit pkg build -org nemunaire $@ + touch $@ + pkg/login-validator: pkg/login-validator/cmd/login.go pkg/login-validator/cmd/main.go pkg/login-validator/cmd/pxetpl.go pkg/login-validator/cmd/logout.go pkg/login-validator/cmd/auth.go pkg/login-validator/cmd/arp.go pkg/login-validator/cmd/auth_krb5.go pkg/login-validator/cmd/auth_ldap.go pkg/login-validator/cmd/students.go pkg/login-validator/cmd/auth_fwd.go pkg/login-validator/cmd/ssh.go pkg/login-validator/build.yml pkg/login-validator/Dockerfile linuxkit pkg build -org nemunaire pkg/login-validator/ touch pkg/login-validator @@ -43,7 +47,7 @@ pkg/wg-manager: pkg/wg-manager/cmd/register.go pkg/wg-manager/cmd/main.go pkg/wg linuxkit pkg build -org nemunaire pkg/wg-manager/ touch pkg/wg-manager -server.iso: server.yml students.csv ssl/fullchain.pem ssl/privkey.pem challenge-initrd.img pkg/login-validator pkg/monit pkg/postfix pkg/tftpd pkg/unbound pkg/wg-manager challenge-kernel login-initrd.img +server.iso: server.yml students.csv ssl/fullchain.pem ssl/privkey.pem challenge-initrd.img pkg/arp-spoofer pkg/login-validator pkg/monit pkg/postfix pkg/tftpd pkg/unbound pkg/wg-manager challenge-kernel login-initrd.img linuxkit build -docker -format iso-bios $< tuto2-kernel: tuto2.yml diff --git a/pkg/arp-spoofer/Dockerfile b/pkg/arp-spoofer/Dockerfile new file mode 100644 index 0000000..a6c975b --- /dev/null +++ b/pkg/arp-spoofer/Dockerfile @@ -0,0 +1,20 @@ +FROM golang:alpine as gobuild + +RUN apk add --no-cache git + +WORKDIR /go/src/arp-spoofer + +ADD cmd ./ + +RUN go get -d -v +RUN go build -v + + +FROM alpine +MAINTAINER Pierre-Olivier Mercier + +COPY --from=gobuild /go/src/arp-spoofer/arp-spoofer /bin/arp-spoofer + +ENTRYPOINT ["/bin/arp-spoofer", "-bind=:8081"] + +LABEL org.mobyproject.config='{"capabilities": ["CAP_NET_ADMIN", "CAP_NET_RAW"]}' diff --git a/pkg/arp-spoofer/build.yml b/pkg/arp-spoofer/build.yml new file mode 100644 index 0000000..abce10c --- /dev/null +++ b/pkg/arp-spoofer/build.yml @@ -0,0 +1,2 @@ +image: adlin-arp-spoofer +network: true diff --git a/pkg/arp-spoofer/cmd/arp.go b/pkg/arp-spoofer/cmd/arp.go new file mode 100644 index 0000000..d5fd3d7 --- /dev/null +++ b/pkg/arp-spoofer/cmd/arp.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "math/rand" + "net" + "strings" + "time" + + "github.com/mdlayher/arp" +) + +var ARPTable string = "/proc/net/arp" + +type ARPEntry struct { + IP net.IP + HWType int + Flags int + HWAddress net.HardwareAddr + Mask string + Device string +} + +func ARPAnalyze() (ents []ARPEntry, err error) { + var content []byte + if content, err = ioutil.ReadFile(ARPTable); err != nil { + return + } + + for _, line := range strings.Split(string(content), "\n") { + f := strings.Fields(line) + if len(f) > 5 { + var e ARPEntry + + if _, err := fmt.Sscanf(f[1], "0x%x", &e.HWType); err != nil { + continue + } + if _, err := fmt.Sscanf(f[2], "0x%x", &e.Flags); err != nil { + continue + } + + e.IP = net.ParseIP(f[0]) + if e.HWAddress, err = net.ParseMAC(f[3]); err != nil { + continue + } + e.Mask = f[4] + e.Device = f[5] + + ents = append(ents, e) + } + } + + return +} + +func ARPContainsIP(ents []ARPEntry, ip net.IP) *ARPEntry { + for i, e := range ents { + if e.IP.Equal(ip) && (e.Flags == 2 || e.Flags == 6) { + return &ents[i] + } + } + + return nil +} + +func ARPSpoof(iface *net.Interface, ipS net.IP) { + clt, err := arp.Dial(iface) + if err != nil { + log.Println("Unable to initiate ARP spoofing:", err) + return + } + defer clt.Close() + + for { + ents, err := ARPAnalyze() + if err != nil { + time.Sleep(2 * time.Second) + continue + } + + randHW := net.HardwareAddr{0, byte(rand.Intn(255)), byte(rand.Intn(255)), byte(rand.Intn(255)), byte(rand.Intn(255)), byte(rand.Intn(255))} + + for _, e := range ents { + if e.IP[0] == ipS[0] && e.IP[1] == ipS[1] { + req := &arp.Packet{ + SenderHardwareAddr: e.HWAddress, + SenderIP: e.IP, + } + clt.Reply(req, randHW, ipS) + } + } + + time.Sleep(150 * time.Millisecond) + } +} diff --git a/pkg/arp-spoofer/cmd/main.go b/pkg/arp-spoofer/cmd/main.go new file mode 100644 index 0000000..1c86c11 --- /dev/null +++ b/pkg/arp-spoofer/cmd/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "flag" + "log" + "net" +) + +func main() { + var ifacestr = flag.String("iface", "eth0", "Interface to use") + var ipspoof = flag.String("ip-spoof", "", "IP to ARP spoof") + flag.Parse() + + iface, err := net.InterfaceByName(*ifacestr) + if err != nil { + log.Fatal("Unable to find interface to do ARP spoof:", err) + } + + ipS := net.ParseIP(*ipspoof) + if ipS == nil { + log.Fatal("No IP given to ARP spoof. Skipping it") + } + + // Start ARP spoofing + ARPSpoof(iface, ipS) +}