Merge pull request #4 from mariocandela/tcp-honeypot

feat: Implemented TCP Honeypot
This commit is contained in:
Mario Candela
2022-07-03 17:20:13 +02:00
committed by GitHub
9 changed files with 87 additions and 10 deletions

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
apiVersion: "v1"
protocol: "tcp"
address: ":3306"
description: "Mysql 8.0.29"
banner: "8.0.29"
deadlineTimeoutSeconds: 10

View File

@ -10,6 +10,7 @@ services:
- "22:22"
- "8080:8080"
- "80:80"
- "3306:3306"
environment:
RABBITMQ_URI: ${RABBITMQ_URI}
volumes:

View File

@ -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

View File

@ -38,6 +38,7 @@ type BeelzebubServiceConfiguration struct {
DeadlineTimeoutSeconds int `yaml:"deadlineTimeoutSeconds"`
PasswordRegex string `yaml:"passwordRegex"`
Description string `yaml:"description"`
Banner string `yaml:"banner"`
}
type Command struct {

View File

@ -0,0 +1,57 @@
package protocols
import (
"beelzebub/parser"
"beelzebub/tracer"
"fmt"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"net"
"time"
)
type TransmissionControlProtocolStrategy struct {
}
func (TCPStrategy *TransmissionControlProtocolStrategy) Init(beelzebubServiceConfiguration parser.BeelzebubServiceConfiguration, tr tracer.Tracer) error {
listen, err := net.Listen("tcp", beelzebubServiceConfiguration.Address)
if err != nil {
log.Errorf("Error during init TCP Protocol: %s", err.Error())
return err
}
go func() {
for {
if conn, err := listen.Accept(); err == nil {
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()
}()
}
}
}()
log.WithFields(log.Fields{
"port": beelzebubServiceConfiguration.Address,
"banner": beelzebubServiceConfiguration.Banner,
}).Infof("Init service %s", beelzebubServiceConfiguration.Protocol)
return nil
}

View File

@ -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