aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarin Ivanov <[email protected]>2019-03-24 21:45:18 +0200
committerMarin Ivanov <[email protected]>2019-03-24 21:45:18 +0200
commit6ab1613157a6a5d3eabf9d2fe2adf4699d29a5ba (patch)
tree37d916734789e97096a78d907fd0046dfa349e82
parent317163b27c1b16687a1473b6b40e743a83964f6a (diff)
Make TCP connection tarpit
This first version of the command has support for SSH protocol tarpit.
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--handle.go31
-rw-r--r--main.go45
-rw-r--r--ssh.go33
5 files changed, 116 insertions, 0 deletions
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
+ }
+ }
+ }
+}