Skip to content

False positive: php_webshell_known fires on the German word "behindert" and on "WSO " in prose #487

Description

@kleinwerkstatt

Summary

The YARA rule php_webshell_known in src/skillspector/yara_rules/webshells.yar uses short, unanchored nocase strings. Two of them match ordinary prose, producing a CRITICAL finding at confidence 0.9 with the remediation "Remove the webshell code immediately" on skills that contain no code at all:

  • $behinder = "behinder" nocase — matches the common German words behindert, behindern, Behinderung, behindertengerecht ("to impede", "disability"). Any German-language skill that discusses accessibility will trigger it.
  • $wso2 = "WSO " nocase — matches any occurrence of the letters WSO followed by a space in ordinary prose.

Because condition: any of them, a single substring hit is enough.

Reproduction (v2.11.0, --no-llm)

de-skill/SKILL.md:

---
name: de-skill
description: Ein harmloser deutschsprachiger Skill ueber Barrierefreiheit.
---

# Barrierefreiheit

Zu kleine Schrift behindert das Lesen. Menschen mit Behinderung brauchen
ausreichende Kontraste. Ein Layout, das die Bedienung per Tastatur behindert,
ist nicht barrierefrei.
skillspector scan ./de-skill --no-llm --format json

Result:

score 45, severity MEDIUM, max_issue_severity CRITICAL
YR2  CRITICAL  conf 0.9
  pattern:  YARA rule 'php_webshell_known': Known PHP webshell families (c99, r57, b374k, WSO, etc.)
  finding:  'behinder; Behinder; behinder'
  remediation: Remove the webshell code immediately. Webshells provide unauthorized
               remote command execution. Audit the skill for additional backdoors ...

A second, English-language fixture reproduces the WSO variant:

We deploy the API on WSO 2 Micro Integrator.
YR2  CRITICAL  conf 0.9   finding: 'WSO '

Why this matters

This is not a cosmetic mismatch. The finding is the highest severity the scanner emits, at 0.9 confidence, and the accompanying text asserts a webshell is present and tells the reader to audit for further backdoors. For any non-English-speaking user, the false positive is not obviously false — the report claims a concrete, named malware family.

It also affects real corpora: I hit this while scanning an unrelated German-language skill whose only offence was the word behindert inside a plain Markdown reference file.

Suggested fix

  1. Replace the two prose-colliding strings with markers that are actually specific to the shells:
    • Behinder (冰蝎) is better identified by its hardcoded AES key material or by BehinderShell / Behinder in combination with a PHP/JSP context, rather than the bare substring.
    • WSO is better identified by its banner text (e.g. Web Shell by oRb, already present as $wso) than by "WSO ".
  2. More generally, consider requiring a code context (PHP/JSP/ASPX tags, eval, $_POST, …) before php_webshell_known can fire, or raising the threshold above any of them for the shortest strings. Rule webshells.yar already contains stronger, structural patterns ($preg_replace_e, $create_func) that do not have this problem.

The same class of short, unanchored nocase string appears in the other rule files as well, so a broader audit may be worthwhile.

Environment

  • SkillSpector v2.11.0 (commit 7805bb9), installed from source
  • Python 3.12.13, macOS (arm64)
  • --no-llm static pass only

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions