From 6ab1613157a6a5d3eabf9d2fe2adf4699d29a5ba Mon Sep 17 00:00:00 2001 From: Marin Ivanov Date: Sun, 24 Mar 2019 21:45:18 +0200 Subject: Make TCP connection tarpit This first version of the command has support for SSH protocol tarpit. --- go.mod | 5 +++++ go.sum | 2 ++ handle.go | 31 +++++++++++++++++++++++++++++++ main.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ ssh.go | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 handle.go create mode 100644 main.go create mode 100644 ssh.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..124f5c7 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module metala.org/pkg/tarpit + +go 1.12 + +require github.com/spf13/pflag v1.0.3 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..edd0bcf --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= diff --git a/handle.go b/handle.go new file mode 100644 index 0000000..622b68e --- /dev/null +++ b/handle.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "net" + "time" +) + +type protoHandler func(net.Conn) + +func protocolHandler(proto string) (protoHandler, error) { + switch proto { + case "ssh": + return sshHandler, nil + default: + return nil, fmt.Errorf("unknown protocol '%s'", proto) + } +} + +func logConn(conn net.Conn, msg string) { + now := time.Now().UTC() + fmt.Printf("%s, %s, %s\n", now.String(), conn.RemoteAddr().String(), msg) +} + +func connHandler(handler protoHandler, conn net.Conn) { + defer conn.Close() + + logConn(conn, "handling") + handler(conn) + logConn(conn, "closing") +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..8de0a5c --- /dev/null +++ b/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "math/rand" + "net" + "os" + "time" + + flag "github.com/spf13/pflag" +) + +func main() { + var protocol string + var bindAddr string + var port int + + flag.StringVarP(&protocol, "proto", "P", "ssh", "protocol to trap") + flag.StringVarP(&bindAddr, "bind-address", "b", "", "address to bind the socket to") + flag.IntVarP(&port, "port", "p", 22, "TCP port") + flag.Parse() + + handler, err := protocolHandler(protocol) + if err != nil { + fmt.Fprintln(os.Stderr, "Error: protocol handler;", err.Error()) + os.Exit(1) + } + + rand.Seed(time.Now().UnixNano()) + bind := fmt.Sprintf("%s:%d", bindAddr, port) + ln, err := net.Listen("tcp", bind) + if err != nil { + fmt.Fprintln(os.Stderr, "Error: server listen;", err.Error()) + os.Exit(1) + } + fmt.Fprintf(os.Stderr, "** Server listening on %s\n", bind) + for { + conn, err := ln.Accept() + if err != nil { + // handle error + continue + } + go connHandler(handler, conn) + } +} diff --git a/ssh.go b/ssh.go new file mode 100644 index 0000000..3d43a6c --- /dev/null +++ b/ssh.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "io" + "io/ioutil" + "math/rand" + "net" + "time" +) + +type empty struct{} + +func sshHandler(conn net.Conn) { + eof := make(chan empty) + go func() { + io.Copy(ioutil.Discard, conn) + eof <- empty{} + }() + + tick := time.Tick(10 * time.Second) + for { + select { + case <-eof: + return + case <-tick: + _, err := fmt.Fprintf(conn, "%x\r\n", rand.Uint32()) + if err != nil { + return + } + } + } +} -- cgit v1.2.3