Skip to content

Tags: cowrie/cowrie

Tags

v3.0.2

Toggle v3.0.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
build(deps): bump idna from 3.15 to 3.16 (#40147)

Bumps [idna](https://github.com/kjd/idna) from 3.15 to 3.16.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md)
- [Commits](kjd/idna@v3.15...v3.16)

---
updated-dependencies:
- dependency-name: idna
  dependency-version: '3.16'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

v3.0.1

Toggle v3.0.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Honor txtcmds_path for text commands (#40143)

v3.0.0

Toggle v3.0.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
chore: fix mypy on Python 3.15 stubs; drop unused tftpy dependency (#…

…40141)

* fix: version-gated Traversable import; drop unused type: ignore

src/cowrie/core/resources.py: the previous fix imported Traversable
from importlib.abc, which works for Python 3.10 typeshed but is
"attr-defined" missing on Python 3.15+ stubs (where Traversable lives
exclusively in importlib.resources.abc). Use sys.version_info to
gate the import:

  if sys.version_info >= (3, 11):
      from importlib.resources.abc import Traversable
  else:
      from importlib.abc import Traversable

Verified clean under mypy --python-version=3.10, 3.13, and 3.15.

src/cowrie/commands/base.py: drop two `# type: ignore` comments that
mypy now flags as unused-ignore. codecs.escape_decode is typed in
current typeshed, so the suppression is no longer needed.

* chore: drop tftpy runtime dependency

tftpy 0.8.7 was a listed runtime dependency in pyproject.toml and
requirements.txt but no Python source file imports it. cowrie's TFTP
client (cowrie/commands/tftp.py) is a custom async implementation
on top of twisted.internet.protocol.DatagramProtocol; tftpy was a
legacy dependency from before that refactor.

`grep -rE 'tftpy|import tftpy|from tftpy' src/` returns no matches.

* docs: update CHANGELOG for 3.0.0 and 2.9.1--2.9.20

Add DEPENDENCIES section (tftpy removal) and two INTERNAL entries
(backend_pool bundled-data cascade, CI smoke tests) to the 3.0.0
section. Add a rollup section covering the 20 patch releases between
2.9.0 and 2.9.20 that had no changelog entries.

* docs: put cowrie-env inside the honeypot state directory

The Quick start and Step 3 previously put the virtualenv at
~/cowrie-env (next to the user's $HOME). Move it inside the honeypot
state directory so each honeypot is self-contained — venv, config,
and runtime state all sit under the same root, and the user can move
/ back up / delete the whole thing as a unit.

Also:
- Bump the "requires Cowrie X" line from 2.10 to 3.0.0 (actual target).
- Step 4 now references the directory created in Step 3 rather than
  duplicating the mkdir.
- Step 4 output sample updated to show the var/ skeleton that
  cowrie init now creates.

* security: disable HTTP redirects on output-plugin API calls

treq's default agent wraps with BrowserLikeRedirectAgent, which
forwards request headers (including Authorization, API keys, and
similar secrets) to the redirect target. A malicious or compromised
redirect from an external API endpoint would exfiltrate those
secrets.

Pass allow_redirects=False on every treq.get / treq.post in cowrie
output plugins:

  - abuseipdb.py    (X-Auth-Key, X-API-Key in headers)
  - axiom.py        (Authorization: Bearer)
  - crashreporter.py (no auth, but defensively)
  - dshield.py      (X-ISC-Authorization)
  - greynoise.py    (`key` header)
  - malshare.py     (api_key in URL query string)
  - telegram.py     (bot token in URL path)

cuckoo.py already uses HTTPClient(client.Agent(reactor, ...)) — the
bare twisted Agent without redirect wrapping — so it does not follow
redirects. virustotal.py uses self.agent.request() with the same bare
Agent. misp.py uses the synchronous PyMISP library; redirect behaviour
is outside this PR's scope.

* docs: fix stale Sphinx cross-reference in INSTALL.rst

Step 4's header was renamed from "Initialise a state directory" to
"Initialise the state directory" in an earlier commit on this branch,
but the table of contents at the top of the file still pointed at the
old anchor:

    WARNING: undefined label: 'install:step 4: initialise a state directory'

Update the :ref: target to match the new section title.

v2.9.20

Toggle v2.9.20's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: embed file contents into bundled fs.pickle (#40137)

* feat: embed file contents into bundled fs.pickle

Two paths, one purpose — make the bundled cowrie data filesystem
self-contained instead of relying on a sibling honeyfs/ directory tree.

1. createfs.py grew an EMBED_PATHS constant listing the virtual paths
   whose file bytes are read into A_CONTENTS during the recursive
   walk. The list maps to paths cowrie reads at startup (banner,
   passwd, group) plus the small text files attackers commonly cat to
   fingerprint the OS (/etc/os-release, /proc/cpuinfo, ...). Files not
   listed keep an empty A_CONTENTS to avoid bloating the pickle with
   every regular file in the source tree.

   Future `make build-fs-pickle` runs pick this up automatically; no
   second pass needed. Read errors on listed files are logged via the
   existing logit() and the entry keeps an empty A_CONTENTS, so a
   partial container does not abort the build.

2. fsctl gained `embed <local-dir>`: bulk-load file contents from a
   local directory into matching pickle entries. The counterpart to
   the existing per-file `do_load` for editing an already-built pickle
   without rerunning createfs.

The existing fs.py:file_contents already returns A_CONTENTS bytes
when present, so once the bundled pickle has bytes baked in (next
commit), the runtime serves them for /etc/passwd, /etc/issue.net,
/proc/cpuinfo, etc. without needing the top-level honeyfs/ tree.

* chore: embed honeyfs contents into bundled fs.pickle

Regenerated src/cowrie/data/fs.pickle with file contents from the
top-level honeyfs/ directory baked into A_CONTENTS.

    fsctl src/cowrie/data/fs.pickle "embed honeyfs"

15 files embedded; 4 paths in honeyfs/ have no matching pickle entry
(/proc/mounts, /proc/net/arp, /etc/inittab, /etc/os-release) and are
unchanged from the Debian image the pickle was built from.

With this in place, honeyfs.read_file() returns real bytes for paths
served by the bundled defaults, and the read_honeyfs_bytes cascade
works end-to-end without the top-level honeyfs/ directory present.

Pickle grows from 1.18MB to 1.19MB.

v2.9.19

Toggle v2.9.19's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Port malshare and cuckoo output plugins to treq (#40118)

* refactor(output): port malshare to treq

Use treq for the malshare upload so the request is async/Deferred-based
and shares the reactor's thread instead of going through the
requests/threads.deferToThread roundtrip.

* refactor(output): port cuckoo to treq

Use treq via a per-output HTTPClient that wraps a Twisted Agent with a
no-verify TLS policy, matching the previous verify=False semantics
required by typical self-signed local Cuckoo deployments. HTTPBasicAuth
becomes the (user, password) tuple that treq's auth kwarg expects, and
the dedup-then-upload sequence becomes one inlineCallbacks chain so the
download/upload write paths stay serialised.

* fix(output): only log 'Sending file to Cuckoo' when we actually send

The previous treq port logged the message in both write() branches
before the duplicate check, so file_upload events emitted the line even
when the dup check suppressed the upload. The pre-treq code logged
inside the inner conditional for file_upload (post-dedup) and ahead
of the conditional for file_download. Move the log into
_maybe_postfile so both event types log when an upload actually
happens; aligns the two branches behind a single source of truth.

* fix(output): drain response bodies in cuckoo and malshare

treq returns the underlying connection to the pool only after the body
has been consumed. The treq port was reading the body via
response.json() only on the 2xx branches of cuckoo's dedup/postfile/
posturl and on no branch of malshare's postfile, so non-2xx and the
malshare success path would tie up a pool slot until garbage collection
released it. Add yield response.text() on every untraversed branch to
match the pattern used elsewhere (greynoise.py).

v2.9.18

Toggle v2.9.18's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
LLM Anthropic support + Configurable context prompt (#38602)

* feat(llm): add Anthropic API support and configurable system prompt

- Detect Anthropic API endpoint and use x-api-key + anthropic-version headers
- Extract system context into _build_system_context() helper shared by
  interactive and exec protocol paths
- Add system_prompt config option in [llm] section supporting template
  variables: {hostname}, {username}, {ip}, {ip6}, {client_ip}, {cwd}
- Document new config option in cowrie.cfg.dist
- Add Anthropic Messages API response parser (content[0].text) alongside
  the existing OpenAI choices[0].message.content parser
- Restore distinct default system prompts for interactive vs exec sessions:
  exec uses a tighter prompt instructing ONLY raw output, no commentary
- Make both prompts independently configurable via system_prompt and
  system_prompt_exec in [llm] config section

PyPy 3.11.15 crashes with an AssertionError in duplicate_exits_without_lineno
when compiling annotated assignments (name: type = value) inside generator
function sub-scopes. Remove the annotation from content= inside get_response.

* feat(llm): support HTTP/HTTPS proxy via standard env vars

The LLM backend now respects proxy environment variables
(HTTPS_PROXY, HTTP_PROXY and lowercase variants), using
Twisted's ProxyAgent when a proxy is configured. This allows
Cowrie to reach LLM APIs through corporate or outbound proxies
without any config file changes.

v2.9.17

Toggle v2.9.17's commit message
build(deps-dev): bump ruff from 0.15.8 to 0.15.9

Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.8 to 0.15.9.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.15.8...0.15.9)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.15.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

v2.9.16

Toggle v2.9.16's commit message
remove .swap

v2.9.15

Toggle v2.9.15's commit message
build(deps): bump sigstore/cosign-installer from 4.0.0 to 4.1.0

Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](sigstore/cosign-installer@v4.0.0...v4.1.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

v2.9.14

Toggle v2.9.14's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #2928 from cowrie/dependabot/github_actions/docker…

…/metadata-action-6

build(deps): bump docker/metadata-action from 5 to 6