Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Contributing to Glutton

Thanks for considering a contribution. Glutton is a security tool, so small source-verified changes are easier to review than broad rewrites.

See [Getting started](docs/setup.md) for the toolchain, Spicy/HILTI, and Glutton build steps.

## Guidelines

- **Pick an issue** from the [tracker](https://github.com/mushorg/glutton/issues). Useful labels: `good first issue`, `help wanted`, `protocol`, `enhancement`. Reproduce older issues against `main` before starting. For protocol work, read [Extension system](docs/extension-system.md), [Adding a protocol](docs/protocols/adding-a-protocol.md), and [Spicy cheatsheet](docs/protocols/spicy-cheatsheet.md) first to gauge effort.
- **Comment before you start** so a maintainer can confirm scope or redirect.
- **Keep PRs small and source-verified.** Split large work into a thin first slice.
- **Add tests** beside the package you change.
- **Update docs in the same PR** when behavior changes:
- Build/CI/Docker or Go version → [Getting started](docs/setup.md)
- Config defaults or rules behavior → [Configuration](docs/configuration.md)
- Handler registration or protocol behavior → [Architecture](docs/architecture.md), [Extension system](docs/extension-system.md), [FAQ](docs/faq.md)
- Producer event fields → [Logging and producers](docs/logging.md)
- Spicy parser coverage → [Spicy cheatsheet](docs/protocols/spicy-cheatsheet.md)

## Code style and PRs

- **Format** Mirror the structure of existing handlers in `protocols/tcp/` and `protocols/udp/`.
- **Respect the boundary:** parsing belongs in `.spicy` files, protocol logic in Go. Never commit generated parser artifacts — they're git-ignored.
- **Test before pushing:** run `go test ./protocols/... ./rules/...` while iterating, and the full `CC=clang CXX=clang++ go test ./...` (Spicy must be installed) before opening a PR. If you changed any `.spicy` file, run `make spicy` first so tests pick up the regenerated parser.
- **Write a focused PR:** describe what changed, how you tested it, and which docs moved with it. Keep unrelated cleanup in its own PR.
137 changes: 128 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,133 @@
# Glutton
![Tests](https://github.com/mushorg/glutton/actions/workflows/workflow.yml/badge.svg)
[![GoDoc](https://godoc.org/github.com/mushorg/glutton?status.svg)](https://godoc.org/github.com/mushorg/glutton)

Glutton is a protocol-agnostic, low-interaction honeypot that intercepts network traffic and logs interactions to help analyze malicious activities. It's built using Golang and leverages iptables and TPROXY to redirect all traffic to specific protocol handlers.
[![Tests](https://github.com/mushorg/glutton/actions/workflows/workflow.yml/badge.svg)](https://github.com/mushorg/glutton/actions/workflows/workflow.yml)
[![Go Reference](https://pkg.go.dev/badge/github.com/mushorg/glutton.svg)](https://pkg.go.dev/github.com/mushorg/glutton)
[![Go Version](https://img.shields.io/github/go-mod/go-version/mushorg/glutton)](go.mod)
[![License](https://img.shields.io/github/license/mushorg/glutton)](LICENSE)
[![Discord](https://img.shields.io/badge/discord-Honeynet-5865F2?logo=discord&logoColor=white)](https://discord.gg/xzESEhgPtk)

> A highly sensitive, protocol-agnostic, low-interaction TCP/UDP honeypot in Go.

Modern attackers increasingly rely on stealthy techniques like low-volume scans, partial protocol handshakes, and subtle behavioral anomalies to evade detection by conventional honeypots. These systems often fail to capture such activities due to rigid protocol emulation, incomplete logging, or reliance on predefined attack signatures.

Glutton is built to bridge this gap with its catch-all TCP/UDP approach. It captures traffic across all TCP and UDP ports and protocols without requiring a specific protocol implementation for each service. Its dynamic rule engine then either redirects traffic to a protocol-specific handler, forwards it to an upstream target through the built-in TCP proxy, or captures it generically so the payload is preserved even when the protocol is unknown. Together, this gives security teams visibility into reconnaissance activities that might otherwise go undetected.

Glutton's core is designed for:

- **Protocol-agnosticism:** Instead of fully emulating each protocol, Glutton uses configurable rules and generic handlers to process any TCP/UDP-based interaction on all ports.
- **Detailed logging:** Glutton records all connections, including metadata and payloads, to preserve even partial interactions for further analysis.
- **Extensibility:** Its flexible mapping of protocol handlers and configurable rules allows it to quickly adapt to support new protocols without the need for extensive architectural changes.

Beyond Go handlers, Glutton also includes an emerging Spicy parser path. Spicy is the parser-definition language from the Zeek project; it lets contributors describe byte-level protocol grammars in a small DSL instead of writing the parser in Go. Currently Glutton uses Spicy for HTTP parsing and TCP-payload protocol detection only.

Out of the box, Glutton ships handlers that capture exploit probes targeting Citrix ADC (CVE-2019-19781), VMware vCenter (`hyper/send`), and Ethereum JSON-RPC wallets, alongside protocol-interaction handlers for SMTP, RDP, SMB, and many more, plus generic TCP/UDP fallbacks and TCP proxy forwarding for everything else. See [What Glutton captures](#what-glutton-captures) below for the full list.

## Quick start

Glutton requires Linux, root privileges for iptables, and a build toolchain compatible with the [CI workflow](.github/workflows/workflow.yml) — currently Go 1.23+, Spicy 1.13.1, clang 17, libpcap, iptables, and zlib1g.

```bash
git clone https://github.com/mushorg/glutton.git
cd glutton

# Install Spicy/HILTI under /opt/spicy (see docs/setup.md), then:
export PATH=/opt/spicy/bin:$PATH
make spicy
make build

sudo bin/server -i eth0 -c config/ -l /var/log/glutton.log
```

> **SSH safety:** Glutton's iptables rule excludes one TCP port from TPROXY redirection so your SSH session survives. Both `ports.ssh` (`config/config.yaml`) and the CLI flag `-s/--ssh` (`app/server.go`) default to `2222`. If your sshd listens on a different port (the typical `22`, for example), set `ports.ssh` in your config or pass `-s <port>` explicitly to the port your sshd actually listens on before exposing the sensor, or you will lock yourself out.

Edit `config/config.yaml` before deployment. Set `addresses` to your host's public IPs and review `ports.`*, `producers.`*, `capture_traffic.enabled`, `dial_timeout`, and the rules in `config/rules.yaml`. Full reference in [docs/configuration.md](docs/configuration.md).

For full build, install, and runtime details — including Spicy setup, privileges, and operational hazards — see [docs/setup.md](docs/setup.md).

## Docker

The repository ships a `Dockerfile`. For real traffic capture the container needs the host network namespace and `NET_ADMIN`, since TPROXY operates on a real interface:

```bash
docker build -t glutton .
docker run --rm --network host --cap-add=NET_ADMIN -it glutton
```

This requires the host kernel to support iptables `mangle` and the `xt_TPROXY` module. Without `--network host` the container will install rules inside the container network namespace and never see external traffic.

For full Docker, privileges, and host-placement guidance, see [docs/setup.md](docs/setup.md).

## What Glutton captures


| Name | What it captures |
| --------------------------- | ---------------------------------------- |
| Citrix ADC (CVE-2019-19781) | `GET /vpn/*` RCE probes |
| VMware "hyper/send" | `* hyper/send` request-body exploit |
| Ethereum JSON-RPC | `POST` body containing `eth_blockNumber` |
| Wallet probes | URIs containing `wallet` |
| SMTP | mail submission probes |
| RDP | Remote Desktop handshake |
| SMB | Windows file-sharing probes |
| FTP | file transfer commands |
| SIP | VoIP signaling traffic |
| RFB/VNC | remote framebuffer auth |
| Telnet | interactive login attempts |
| MQTT | IoT pub/sub messages |
| iSCSI | block-storage target probes |
| BitTorrent | peer handshake traffic |
| Memcache | key-value cache commands |
| Jabber/XMPP | instant messaging stream |
| ADB | Android Debug Bridge probes |
| MongoDB | wire protocol queries |
| Hadoop YARN | `POST */cluster/apps/new-application` |
| Docker Engine API | `GET /v1.16/version` |
| HTTP | generic web requests |
| generic TCP | unrecognized TCP payloads |
| generic UDP | unrecognized UDP payloads |


Example producer event shape:

```json
{
"timestamp": "2026-05-15T12:00:00Z",
"transport": "tcp",
"srcHost": "203.0.113.10",
"srcPort": "54321",
"dstPort": 80,
"sensorID": "00000000-0000-0000-0000-000000000000",
"rule": "Rule: tcp",
"handler": "http",
"payload": "R0VUIC8gSFRUUC8xLjENCg0K",
"scanner": "",
"decoded": { "protocol": "http", "fields": {} }
}
```

## Where it fits

Glutton is a breadth-oriented sensor: it trades the deep per-protocol emulation of specialized honeypots for coverage across the TCP/UDP port space. It is not a SIEM, not a high-interaction honeynet, and not a Cowrie replacement for SSH-only deployments. Compared to tools such as Cowrie (SSH/Telnet, high-interaction shell), Dionaea (malware capture), and T-Pot (bundled distribution), Glutton's distinctive surface is broad protocol coverage in one Go binary, a dynamic rule engine, `proxy_tcp` forwarding, and a parser-extension path that can grow with new protocols.

## Documentation
For more details, please read the [documentation](https://go-glutton.readthedocs.io/en/latest/), which provides the following sections:

* [Introduction](https://go-glutton.readthedocs.io/en/latest/)
* [Setup](https://go-glutton.readthedocs.io/en/latest/setup/)
* [Configuration](https://go-glutton.readthedocs.io/en/latest/configuration/)
* [Extension](https://go-glutton.readthedocs.io/en/latest/extension/)
* [FAQs](https://go-glutton.readthedocs.io/en/latest/faq/)
- [Getting started](docs/setup.md)
- [Configuration](docs/configuration.md)
- [Architecture](docs/architecture.md)
- [Logging and producers](docs/logging.md)
- [Extension system](docs/extension-system.md) · [Adding a protocol](docs/protocols/adding-a-protocol.md) · [Spicy cheatsheet](docs/protocols/spicy-cheatsheet.md)
- [FAQ](docs/faq.md)

## Community and contributing

Glutton was built by [Lukas Rist](https://github.com/glaslos), [Muhammad Bilal Arif](https://github.com/furusiyya), and [the community](https://github.com/mushorg/glutton/graphs/contributors?all=1).

For contributing see:

- Contributor guide: [CONTRIBUTING.md](CONTRIBUTING.md)
- Issues and PRs: [github.com/mushorg/glutton](https://github.com/mushorg/glutton)
- Chat: [Honeynet Project Discord](https://discord.gg/xzESEhgPtk)

## License

Glutton is released under the [MIT License](LICENSE).
76 changes: 76 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Architecture

Glutton is built around four moving parts: transparent redirection, rule-based dispatch, protocol handlers, and optional producer output. It does not bind every public service port directly — it installs iptables TPROXY rules that redirect matching TCP and UDP traffic to local listener ports, then reconstructs enough metadata to pick a handler.

```mermaid
flowchart TD
Net[Incoming TCP/UDP traffic] --> IPT[iptables mangle PREROUTING TPROXY]
IPT --> Listen[127.0.0.1 TCP/UDP listeners]
Listen --> Rules[Rule matching]
Rules --> Meta[connection.Metadata]
Meta --> Dispatch[Protocol handler registry]
Dispatch --> GoHandler[Go protocol handler]
Dispatch --> Proxy[proxy_tcp forwarder]
Dispatch --> Spicy[Optional Spicy detection/parsing]
Spicy --> GoHandler
Proxy --> Upstream[Upstream TCP service]
GoHandler --> ProcessLog[slog JSON process logs]
Proxy --> ProcessLog
GoHandler --> Producer[Optional HTTP / hpfeeds producer events]
Proxy --> Producer
```

## Components

| Component | Source | Role |
| --- | --- | --- |
| CLI + runtime | `app/server.go`, `glutton.go` | Flags, init, listeners, rule load, dispatch, signal handling. |
| Listener | `server.go` | Local TCP/UDP TPROXY listeners on `127.0.0.1`. |
| iptables integration | `iptables.go` | Append/remove mangle PREROUTING TPROXY rules. |
| Rules engine | `rules/rules.go` | Compiles BPF expressions, returns the first matching rule. |
| Handler registry | `protocols/protocols.go` | Maps rule targets (`smtp`, `http`, `proxy_tcp`, `tcp`, …) to handler funcs. |
| TCP/UDP handlers | `protocols/tcp/`, `protocols/udp/` | Protocol interaction, logging, producer calls, fake responses. |
| Spicy bridge | `protocols/spicy/` | Initializes Spicy/HILTI runtime; parses selected payloads. |
| Logging | `producer/logger.go` | JSON `slog` to stdout + rotating file. |
| Producers | `producer/producer.go` | Optional structured events to HTTP / hpfeeds. |

## Startup

1. `app/server.go` parses flags and binds them into Viper.
2. `glutton.New(...)` builds the connection table, reads or writes the sensor ID under `--var-dir`, creates the logger, loads config and rules.
3. `glutton.Init()` resolves public addresses for `interface`, starts the local TCP/UDP listeners, initializes optional producers, builds the handler maps, and initializes Spicy if `spicy.enabled` is true.
4. `glutton.Start()` installs the iptables TPROXY rules and starts the listener loops.

The sensor ID is stored as binary UUID data in `<var-dir>/glutton.id`. Default `--var-dir` is `/var/lib/glutton`.

## TCP dispatch

1. Connection is redirected to the local TCP listener; Glutton accepts it.
2. `applyRulesOnConn(...)` runs the rule set against the connection's remote and local addresses.
3. If no rule matches, a fallback rule with target `default` is synthesized.
4. The connection is registered in the table and the connection timeout is applied.
5. If the rule type is `proxy_tcp`, the proxy handler runs. Otherwise the handler for the matched target runs in a goroutine.

## UDP dispatch

1. A UDP packet is read from the local UDP listener with original source/destination addresses preserved.
2. The rules engine runs with network type `udp`.
3. If no rule matches, target `udp` is used.
4. The packet is registered and the handler runs in a goroutine.

Today the UDP handler map only contains the generic `udp` handler.

## Spicy boundary

Spicy is optional, gated by `spicy.enabled`. When on, the Spicy/HILTI runtime is initialized and compiled parser modules are registered. Current usage:

- `TCP::Protocol` inspects raw TCP payload bytes in the generic `tcp` handler path; detected HTTP, RDP, or MongoDB payloads route to more specific handling.
- `HTTP::Request` parses HTTP request bytes for the Spicy HTTP handler path.

Spicy does not replace Go protocol handlers. The parser extracts fields from bytes; Go still owns reads, writes, fake responses, logging, producer calls, timeouts, and fallback behavior.

One routing wrinkle: a rule with target `http` calls the Go HTTP handler directly. The Spicy HTTP handler is reached *only* from the generic `tcp` catch-all path when Spicy detection classifies the payload as HTTP.

## Output

Process logs always go through `slog` JSON to stdout and the configured `--logpath` file (rotated via lumberjack). Producer events are separate and only emitted when `producers.enabled` and a sink (`producers.http.enabled` or `producers.hpfeeds.enabled`) are on. See [Logging and producers](logging.md).
Loading
Loading