Skip to content

Commit

Permalink
more event handling
Browse files Browse the repository at this point in the history
  • Loading branch information
glaslos committed Sep 27, 2023
1 parent a16f62c commit b87d8f2
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 33 deletions.
42 changes: 32 additions & 10 deletions protocols/bittorrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,37 @@ type bittorrentMsg struct {
PeerID [20]uint8 `json:"peer_id,omitempty"`
}

type parsedBittorrent struct {
Direction string `json:"direction,omitempty"`
Message bittorrentMsg `json:"message,omitempty"`
Payload []byte `json:"payload,omitempty"`
}

type bittorrentServer struct {
events []parsedBittorrent
}

// HandleBittorrent handles a Bittorrent connection
func HandleBittorrent(ctx context.Context, conn net.Conn, logger Logger, h Honeypot) error {
var err error
server := bittorrentServer{
events: []parsedBittorrent{},
}
defer func() {
if err = conn.Close(); err != nil {
md, err := h.MetadataByConnection(conn)
if err != nil {
logger.Error("failed to fetch meta data", zap.Error(err), zap.String("handler", "bittorrent"))
}
if err = h.Produce("bittorrent", conn, md, firstOrEmpty[parsedBittorrent](server.events).Payload, server.events); err != nil {
logger.Error("failed to produce message", zap.Error(err), zap.String("handler", "bittorrent"))
}
if err := conn.Close(); err != nil {
logger.Error("failed to close connection", zap.Error(err), zap.String("handler", "bittorrent"))
return
}
}()

logger.Info("new bittorrent connection")

md, err := h.MetadataByConnection(conn)
if err != nil {
return err
}

for {
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
Expand All @@ -43,9 +57,12 @@ func HandleBittorrent(ctx context.Context, conn net.Conn, logger Logger, h Honey
logger.Error("failed to read message", zap.Error(err), zap.String("handler", "bittorrent"))
break
}
if err = h.Produce("bittorrent", conn, md, buffer[:n], msg); err != nil {
logger.Error("failed to produce message", zap.Error(err), zap.String("handler", "bittorrent"))
}

server.events = append(server.events, parsedBittorrent{
Direction: "read",
Message: msg,
Payload: buffer[:n],
})

logger.Info(
"bittorrent received",
Expand All @@ -54,6 +71,11 @@ func HandleBittorrent(ctx context.Context, conn net.Conn, logger Logger, h Honey
zap.Uint8s("inf_hash", msg.InfoHash[:]),
)

server.events = append(server.events, parsedBittorrent{
Direction: "write",
Message: msg,
Payload: buffer[:n],
})
if err = binary.Write(conn, binary.BigEndian, msg); err != nil {
logger.Error("failed to write message", zap.Error(err), zap.String("handler", "bittorrent"))
break
Expand Down
8 changes: 8 additions & 0 deletions protocols/protocols.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,11 @@ func MapProtocolHandlers(log Logger, h Honeypot) map[string]HandlerFunc {
}
return protocolHandlers
}

func firstOrEmpty[T any](s []T) T {
if len(s) > 0 {
return s[0]
}
var t T
return t
}
7 changes: 1 addition & 6 deletions protocols/rdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,7 @@ func HandleRDP(ctx context.Context, conn net.Conn, logger Logger, h Honeypot) er
if err != nil {
logger.Error("failed to get metadata", zap.Error(err))
}
var payload []byte
if len(server.events) > 0 {
payload = server.events[0].Payload
}

if err := h.Produce("rdp", conn, md, payload, server.events); err != nil {
if err := h.Produce("rdp", conn, md, firstOrEmpty[parsedRDP](server.events).Payload, server.events); err != nil {
logger.Error("failed to produce message", zap.String("protocol", "rdp"), zap.Error(err))
}
if err := conn.Close(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion protocols/smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func HandleSMB(ctx context.Context, conn net.Conn, logger Logger, h Honeypot) er
if err != nil {
logger.Error("failed to get metadata", zap.Error(err))
}
if err := h.Produce("smb", conn, md, nil, server.events); err != nil {
if err := h.Produce("smb", conn, md, firstOrEmpty[parsedSMB](server.events).Payload, server.events); err != nil {
logger.Error("failed to produce message", zap.String("protocol", "smb"), zap.Error(err))
}

Expand Down
61 changes: 46 additions & 15 deletions protocols/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ import (
"go.uber.org/zap"
)

type parsedTCP struct {
Direction string `json:"direction,omitempty"`
Payload []byte `json:"payload,omitempty"`
PayloadHash string `json:"payload_hash,omitempty"`
}

type tcpServer struct {
events []parsedTCP
}

func storePayload(data []byte) (string, error) {
sum := sha256.Sum256(data)
if err := os.MkdirAll("payloads", os.ModePerm); err != nil {
Expand All @@ -37,21 +47,45 @@ func storePayload(data []byte) (string, error) {
return sha256Hash, nil
}

func (s *tcpServer) sendRandom(conn net.Conn) error {
randomBytes := make([]byte, 12+rand.Intn(500))
if _, err := rand.Read(randomBytes); err != nil {
return err
}
s.events = append(s.events, parsedTCP{
Direction: "write",
PayloadHash: hex.EncodeToString(randomBytes),
Payload: randomBytes,
})
if _, err := conn.Write(randomBytes); err != nil {
return err
}
return nil
}

// HandleTCP takes a net.Conn and peeks at the data send
func HandleTCP(ctx context.Context, conn net.Conn, logger Logger, h Honeypot) error {
server := tcpServer{
events: []parsedTCP{},
}
md, err := h.MetadataByConnection(conn)
if err != nil {
logger.Error("failed to get metadata", zap.Error(err))
}

defer func() {
if err := h.Produce("tcp", conn, md, firstOrEmpty[parsedTCP](server.events).Payload, server.events); err != nil {
logger.Error("failed to produce message", zap.String("protocol", "tcp"), zap.Error(err))
}
if err := conn.Close(); err != nil {
logger.Error("failed to close TCP connection", zap.String("handler", "tcp"), zap.Error(err))
}
}()

host, port, err := net.SplitHostPort(conn.RemoteAddr().String())
if err != nil {
return fmt.Errorf("faild to split remote address: %w", err)
}
md, err := h.MetadataByConnection(conn)
if err != nil {
return fmt.Errorf("failed to get metadata: %w", err)
}

msgLength := 0
data := []byte{}
Expand Down Expand Up @@ -90,21 +124,18 @@ func HandleTCP(ctx context.Context, conn net.Conn, logger Logger, h Honeypot) er
zap.String("handler", "tcp"),
zap.String("payload_hash", payloadHash),
)
if err := h.Produce("tcp", conn, md, data, struct {
PayloadHash string `json:"payload_hash,omitempty"`
}{PayloadHash: payloadHash}); err != nil {
logger.Error("failed to produce message", zap.String("protocol", "tcp"), zap.Error(err))
}
logger.Info(fmt.Sprintf("TCP payload:\n%s", hex.Dump(data[:msgLength%1024])))

server.events = append(server.events, parsedTCP{
Direction: "read",
PayloadHash: payloadHash,
Payload: data[:msgLength%1024],
})
}

// sending some random data
randomBytes := make([]byte, 12+rand.Intn(500))
if _, err = rand.Read(randomBytes); err != nil {
return err
}
if _, err = conn.Write(randomBytes); err != nil {
return err
if err := server.sendRandom(conn); err != nil {
logger.Error("write error", zap.String("handler", "tcp"), zap.Error(err))
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion protocols/telnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func HandleTelnet(ctx context.Context, conn net.Conn, logger Logger, h Honeypot)
if err != nil {
logger.Error("failed to get metadata", zap.Error(err))
}
if err := h.Produce("telnet", conn, md, []byte{}, s.events); err != nil {
if err := h.Produce("telnet", conn, md, []byte(firstOrEmpty[parsedTelnet](s.events).Message), s.events); err != nil {
logger.Error("failed to produce message", zap.Error(err))
}
if err := conn.Close(); err != nil {
Expand Down

0 comments on commit b87d8f2

Please sign in to comment.