Skip to content

fix(yara): detect multiline socket reverse shells - #599

Open
efegokdemir wants to merge 2 commits into
NVIDIA:mainfrom
efegokdemir:codex/issue-592-multiline-reverse-shell
Open

efegokdemir wants to merge 2 commits into
NVIDIA:mainfrom
efegokdemir:codex/issue-592-multiline-reverse-shell

Conversation

@efegokdemir

Copy link
Copy Markdown

Summary

Closes #592.

The built-in reverse_shell YARA rule now detects Python and Perl socket reverse shells when their socket creation and connection calls span multiple lines. The previous expressions relied on .* without dotall matching, so those common script-shaped shells were missed.

Changes

  • Bound the multiline gap in the Python and Perl socket signatures to 200 characters.
  • Enable YARA dotall matching for both signatures.
  • Added regression coverage for multiline Python and Perl socket shells.

Testing

  • uv run pytest tests/nodes/analyzers/test_static_yara.py -k 'BuiltInMalwarePackaging' -q — 4 passed.
  • uv run pytest tests/nodes/analyzers/test_static_yara.py -q — 88 passed.
  • uv run pytest -m 'not integration and not provider' tests/ — 6,077 passed, 14 skipped, 4 xfailed.
  • uv run ruff check src/ tests/ — passed.
  • uv run ruff format --check src/ tests/ — passed.
  • git diff --check — passed.

Notes

  • The packaged YARA source remains base64 encoded, matching the repository's existing resource format.
  • The 200-character bounds keep matching local to a socket-shell construct instead of allowing unrelated distant calls to satisfy the signature.
  • This contribution was prepared with AI assistance; I reviewed the implementation and validation results and take responsibility for the submitted change.

Signed-off-by: Efe Gökdemir <efe@rexcode.co.uk>

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SkillSpector Review]

Reviewed exact head ab857e4605fe891de363da3ee0f5d830c3479c7f. Bounding the dot-all spans closes the reported multiline blind spot, but the widened signatures do not establish reverse-shell behavior. The decoded Python expression requires only socket.socket(...SOCK_STREAM...) followed by .connect(, while the Perl expression requires only use Socket; followed by socket(SOCK...). Because the rule condition is any of them, ordinary TCP clients now produce a CRITICAL reverse_shell/YR1 finding; the new fixtures themselves contain no file-descriptor redirection, shell execution, or equivalent reverse-shell action.

Require bounded shell-specific evidence (for example descriptor redirection plus a spawned shell, or an equivalently precise paired condition) before YR1 fires. Add negative regressions for ordinary multiline Python and Perl socket clients, retain positive real reverse-shell regressions, and encode signature-triggering fixtures consistently with this test module's antivirus-safety convention. PRs #593, #594, and #599 alter the same two packaged signatures, so only one corrected implementation should land.

All six hosted checks pass and the head is mergeable/clean, but the new core-detector false positives require changes before approval.

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((\"127.0.0.1\", 4444))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P0] This is an ordinary TCP client: it creates a stream socket and connects, but never redirects I/O or launches a shell. Treating it as the positive reverse_shell fixture demonstrates that the widened rule will emit a CRITICAL YR1 finding for benign networking code. Tighten the packaged signature to require shell-specific behavior, then keep this shape as a negative regression and use an encoded, complete reverse shell for the positive case.

Signed-off-by: Efe Gökdemir <efe@rexcode.co.uk>
@efegokdemir

Copy link
Copy Markdown
Author

Fixed the YR1 false-positive path in 1a4adf2. Python and Perl socket signatures now require paired descriptor-redirection and shell/process-execution evidence; ordinary multiline TCP clients are covered by negative regressions, while positive multiline reverse-shell fixtures remain encoded per the test convention.

Validation: uv run --with pytest pytest -q tests/nodes/analyzers/test_static_yara.py — 90 passed; git diff --check passed. Please re-review the current head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Built-in reverse_shell YARA rule misses multi-line Python/Perl socket reverse shells

2 participants