From 882066f0a67cf6a59131a212d1bbfd2ba1a8f3e5 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 3 Jul 2022 17:15:38 +0200 Subject: [PATCH] Implemented tcp honeypot --- .github/dependabot.yml | 9 +--- .github/workflows/ci.yml | 2 +- README.md | 14 ++++++- configurations/services/tcp-3306.yaml | 6 +-- docker-compose.yml | 1 + main.go | 4 ++ .../transmissionControlProtocolStrategy.go | 42 +++++++++++-------- tracer/tracer.go | 3 +- 8 files changed, 51 insertions(+), 30 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b444581..3938344 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,11 +1,6 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - version: 2 updates: - - package-ecosystem: "gomod" # See documentation for possible values - directory: "/" # Location of package manifests + - package-ecosystem: "gomod" + directory: "/" schedule: interval: "daily" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6fc69ca..f43477b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: echo "Quality Gate: checking test coverage is above threshold ..." echo "Threshold : $TESTCOVERAGE_THRESHOLD %" # Excluded the concrete strategy - cat coverage.tmp.out | grep -v "secureShellStrategy.go" | grep -v "hypertextTransferProtocolStrategy.go" > coverage.out + cat coverage.tmp.out | grep -v "secureShellStrategy.go" | grep -v "hypertextTransferProtocolStrategy.go" | grep -v "transmissionControlProtocolStrategy.go" > coverage.out totalCoverage=`go tool cover -func=coverage.out | grep total | grep -Eo '[0-9]+\.[0-9]+'` echo "Current test coverage : $totalCoverage %" if (( $(echo "$totalCoverage $TESTCOVERAGE_THRESHOLD" | awk '{print ($1 > $2)}') )); then diff --git a/README.md b/README.md index d587439..35b32dd 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ $ go build $ ./beelzebub ``` +Unit Test: + +```bash +$ go test ./... + ``` + ## Example configuration service The configurations are inside the /configurations/services directory, just add a new file for each service/port. @@ -116,6 +122,7 @@ deadlineTimeoutSeconds: 60 - SSH Honeypot - HTTP Honeypot +- TCP Honeypot - Easy to create a new strategy - Easy to extend event tracking logic - Strong code quality @@ -125,7 +132,12 @@ deadlineTimeoutSeconds: 60 ## TODO - telnet -- tcp +- UDP + +# ROADMAP + +- SaaS Platform + ## Documentation diff --git a/configurations/services/tcp-3306.yaml b/configurations/services/tcp-3306.yaml index 3e66c4b..b3e9ec5 100644 --- a/configurations/services/tcp-3306.yaml +++ b/configurations/services/tcp-3306.yaml @@ -1,6 +1,6 @@ apiVersion: "v1" protocol: "tcp" address: ":3306" -description: "Mysql" -banner: "mysql 4.0" -deadlineTimeoutSeconds: 60 \ No newline at end of file +description: "Mysql 8.0.29" +banner: "8.0.29" +deadlineTimeoutSeconds: 10 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 48eb8df..f40a391 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: - "22:22" - "8080:8080" - "80:80" + - "3306:3306" environment: RABBITMQ_URI: ${RABBITMQ_URI} volumes: diff --git a/main.go b/main.go index 3b28ee7..60ff49c 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,7 @@ func main() { // Init Protocol strategies secureShellStrategy := &protocols.SecureShellStrategy{} hypertextTransferProtocolStrategy := &protocols.HypertextTransferProtocolStrategy{} + transmissionControlProtocolStrategy := &protocols.TransmissionControlProtocolStrategy{} // Init protocol manager, with simple log on stout trace strategy and default protocol HTTP protocolManager := protocols.InitProtocolManager(traceStrategyStdoutAndRabbitMQ, hypertextTransferProtocolStrategy) @@ -57,6 +58,9 @@ func main() { case "ssh": protocolManager.SetProtocolStrategy(secureShellStrategy) break + case "tcp": + protocolManager.SetProtocolStrategy(transmissionControlProtocolStrategy) + break default: log.Fatalf("Protocol %s not managed", beelzebubServiceConfiguration.Protocol) continue diff --git a/protocols/transmissionControlProtocolStrategy.go b/protocols/transmissionControlProtocolStrategy.go index 0950f48..53b0b96 100644 --- a/protocols/transmissionControlProtocolStrategy.go +++ b/protocols/transmissionControlProtocolStrategy.go @@ -3,6 +3,8 @@ package protocols import ( "beelzebub/parser" "beelzebub/tracer" + "fmt" + "github.com/google/uuid" log "github.com/sirupsen/logrus" "net" "time" @@ -12,18 +14,37 @@ type TransmissionControlProtocolStrategy struct { } func (TCPStrategy *TransmissionControlProtocolStrategy) Init(beelzebubServiceConfiguration parser.BeelzebubServiceConfiguration, tr tracer.Tracer) error { - listen, err := net.Listen("TCP", beelzebubServiceConfiguration.Address) + listen, err := net.Listen("tcp", beelzebubServiceConfiguration.Address) if err != nil { log.Errorf("Error during init TCP Protocol: %s", err.Error()) return err } - defer listen.Close() go func() { for { if conn, err := listen.Accept(); err == nil { - conn.SetDeadline(time.Now().Add(time.Duration(beelzebubServiceConfiguration.DeadlineTimeoutSeconds) * time.Second)) - go handleIncomingRequest(conn) + go func() { + conn.SetDeadline(time.Now().Add(time.Duration(beelzebubServiceConfiguration.DeadlineTimeoutSeconds) * time.Second)) + conn.Write([]byte(fmt.Sprintf("%s\n", beelzebubServiceConfiguration.Banner))) + + buffer := make([]byte, 1024) + command := "" + + if n, err := conn.Read(buffer); err == nil { + command = string(buffer[:n]) + } + + tr.TraceEvent(tracer.Event{ + Msg: "New TCP attempt", + Protocol: tracer.TCP.String(), + Command: command, + Status: tracer.Stateless.String(), + RemoteAddr: conn.RemoteAddr().String(), + ID: uuid.New().String(), + Description: beelzebubServiceConfiguration.Description, + }) + conn.Close() + }() } } }() @@ -34,16 +55,3 @@ func (TCPStrategy *TransmissionControlProtocolStrategy) Init(beelzebubServiceCon }).Infof("Init service %s", beelzebubServiceConfiguration.Protocol) return nil } - -func handleIncomingRequest(conn net.Conn) { - buffer := make([]byte, 1024) - _, err := conn.Read(buffer) - if err != nil { - log.Fatal(err) - } - // respond - conn.Write([]byte("Hi back!\n")) - - // close conn - conn.Close() -} diff --git a/tracer/tracer.go b/tracer/tracer.go index cc05355..9c6f0d8 100644 --- a/tracer/tracer.go +++ b/tracer/tracer.go @@ -52,10 +52,11 @@ type Protocol int const ( HTTP Protocol = iota SSH + TCP ) func (status Protocol) String() string { - return [...]string{"HTTP", "SSH"}[status] + return [...]string{"HTTP", "SSH", "TCP"}[status] } type Status int