Add 10 new cybersecurity skills with full folder anatomy

Skills added:
- implementing-privileged-access-workstation (IAM, PAW hardening)
- detecting-suspicious-oauth-application-consent (cloud security, Graph API)
- performing-hardware-security-module-integration (cryptography, PKCS#11)
- analyzing-android-malware-with-apktool (malware analysis, androguard)
- hunting-for-unusual-service-installations (threat hunting, T1543.003)
- detecting-shadow-it-cloud-usage (cloud security, proxy/DNS log analysis)
- performing-active-directory-forest-trust-attack (red team, impacket)
- implementing-deception-based-detection-with-canarytoken (deception, Canary API)
- analyzing-office365-audit-logs-for-compromise (cloud security, BEC detection)
- hunting-for-startup-folder-persistence (threat hunting, T1547.001)

Each skill includes SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
This commit is contained in:
mukul975
2026-03-11 00:47:03 +01:00
parent b6c7ac9d82
commit 4d6d585285
40 changed files with 3578 additions and 0 deletions
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Mahipal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,38 @@
---
name: hunting-for-unusual-service-installations
description: Detect suspicious Windows service installations (MITRE ATT&CK T1543.003) by parsing System event logs for Event ID 7045, analyzing service binary paths, and identifying indicators of persistence mechanisms.
domain: cybersecurity
subdomain: threat-hunting
tags: [threat-hunting, T1543.003, service-installation, persistence, Event-7045, Sysmon, Windows-services]
version: "1.0"
author: mahipal
license: Apache-2.0
---
# Hunting for Unusual Service Installations
## Overview
Attackers frequently install malicious Windows services for persistence and privilege escalation (MITRE ATT&CK T1543.003 — Create or Modify System Process: Windows Service). Event ID 7045 in the System event log records every new service installation. This skill parses .evtx log files to extract service installation events, flags suspicious binary paths (temp directories, PowerShell, cmd.exe, encoded commands), and correlates with known attack patterns.
## Prerequisites
- Python 3.9+ with `python-evtx`, `lxml`
- Windows System event log (.evtx) files
- Access to live System event log (optional, for real-time monitoring)
- Sysmon logs for enhanced process tracking (optional)
## Steps
1. Parse System.evtx for Event ID 7045 (new service installed)
2. Extract service name, binary path, service type, and account
3. Flag services with suspicious binary paths (temp dirs, encoded commands)
4. Detect PowerShell-based service creation patterns
5. Identify services running as LocalSystem with unusual paths
6. Cross-reference with known legitimate service baselines
7. Generate threat hunting report with MITRE ATT&CK T1543.003 mapping
## Expected Output
- JSON report listing all new service installations with risk scores, suspicious indicators, and remediation recommendations
- Timeline of service installation events with binary path analysis
@@ -0,0 +1,73 @@
# API Reference — Hunting for Unusual Service Installations
## Libraries Used
- **python-evtx**: Parse Windows .evtx event log files
- **lxml**: XML parsing of EVTX record XML
- **re**: Regex matching for suspicious binary path patterns
- **collections.Counter**: Statistics aggregation
## CLI Interface
```
python agent.py System.evtx parse
python agent.py System.evtx hunt
python agent.py System.evtx stats
python agent.py System.evtx full
```
## Core Functions
### `parse_evtx_events(evtx_path)` — Extract Event ID 7045 records
Opens .evtx file with `evtx.Evtx()`, iterates records, parses XML with lxml.
Extracts: ServiceName, ImagePath, ServiceType, StartType, AccountName, timestamp.
Namespace: `http://schemas.microsoft.com/win/2004/08/events/event`
### `analyze_service_path(image_path)` — Binary path risk analysis
Matches against 17 suspicious patterns (temp dirs, PowerShell, encoded commands,
LOLBins, download patterns). Checks against 5 legitimate path prefixes.
Scoring: +20 for non-standard path, +15 per suspicious indicator. Max 100.
### `hunt_suspicious_services(evtx_path)` — Main hunting engine
Combines parsing and analysis. Extra +20 risk for LocalSystem account with
non-standard binary path. Results sorted by risk score descending.
### `generate_statistics(results)` — Summary statistics
Counts risk distribution, top indicators, service account usage.
### `full_hunt(evtx_path)` — Comprehensive threat hunt report
## Suspicious Path Patterns
| Pattern | Indicator |
|---------|-----------|
| `\temp\`, `\tmp\` | temp_directory |
| `\appdata\` | appdata_directory |
| `\users\public\` | public_user_directory |
| `powershell.exe` | powershell_execution |
| `cmd.exe /c` | cmd_execution |
| `-enc`, `-encodedcommand` | encoded_command |
| `downloadstring`, `webclient` | download_pattern |
| `invoke-expression`, `iex` | invoke_expression |
| `mshta`, `regsvr32`, `rundll32` | lolbin_execution |
## Legitimate Service Path Prefixes
- `C:\Windows\System32\`
- `C:\Windows\SysWOW64\`
- `C:\Program Files\`
- `C:\Program Files (x86)\`
- `C:\Windows\Microsoft.NET\`
## Event ID 7045 Fields
| Field | Description |
|-------|-------------|
| ServiceName | Display name of installed service |
| ImagePath | Binary path and arguments |
| ServiceType | user mode service, kernel driver, etc. |
| StartType | auto start, demand start, boot start |
| AccountName | Service account (LocalSystem, etc.) |
## MITRE ATT&CK Mapping
- **T1543.003** — Create or Modify System Process: Windows Service
- Tactics: Persistence, Privilege Escalation
## Dependencies
- `python-evtx` >= 0.7.4
- `lxml` >= 4.9.0
@@ -0,0 +1,194 @@
#!/usr/bin/env python3
"""Agent for hunting suspicious Windows service installations (T1543.003) via Event ID 7045."""
import json
import re
import argparse
from datetime import datetime
from collections import Counter
try:
from lxml import etree
except ImportError:
etree = None
try:
import Evtx.Evtx as evtx
import Evtx.Views as evtx_views
except ImportError:
evtx = None
SUSPICIOUS_PATH_PATTERNS = [
(r"\\temp\\", "temp_directory"),
(r"\\tmp\\", "temp_directory"),
(r"\\appdata\\", "appdata_directory"),
(r"\\users\\public\\", "public_user_directory"),
(r"\\programdata\\[^\\]+\.[^\\]+$", "loose_file_in_programdata"),
(r"powershell\.exe", "powershell_execution"),
(r"cmd\.exe\s*/c", "cmd_execution"),
(r"-enc\s+", "encoded_command"),
(r"-encodedcommand", "encoded_command"),
(r"frombase64string", "base64_decode"),
(r"downloadstring|downloadfile|webclient", "download_pattern"),
(r"invoke-expression|iex\s", "invoke_expression"),
(r"\\windows\\temp\\", "windows_temp"),
(r"mshta\.exe|regsvr32\.exe|rundll32\.exe|msiexec\.exe", "lolbin_execution"),
(r"sc\.exe\s+create", "sc_create_chain"),
(r"\\\$recycle\.bin\\", "recycle_bin"),
(r"\\perflog", "perflog_abuse"),
]
LEGITIMATE_SERVICE_PATHS = [
r"^\"?C:\\Windows\\System32\\",
r"^\"?C:\\Windows\\SysWOW64\\",
r"^\"?C:\\Program Files\\",
r"^\"?C:\\Program Files \(x86\)\\",
r"^\"?C:\\Windows\\Microsoft\.NET\\",
]
def parse_evtx_events(evtx_path):
"""Parse System.evtx and extract Event ID 7045 records."""
if not evtx:
raise RuntimeError("python-evtx not installed: pip install python-evtx")
events = []
ns = {"e": "http://schemas.microsoft.com/win/2004/08/events/event"}
with evtx.Evtx(evtx_path) as log:
for record in log.records():
try:
xml = record.xml()
root = etree.fromstring(xml.encode("utf-8") if isinstance(xml, str) else xml)
event_id_el = root.find(".//e:System/e:EventID", ns)
if event_id_el is None or event_id_el.text != "7045":
continue
system = root.find(".//e:System", ns)
event_data = root.find(".//e:EventData", ns)
data_fields = {}
if event_data is not None:
for data in event_data.findall("e:Data", ns):
name = data.get("Name", "")
data_fields[name] = data.text or ""
time_el = system.find("e:TimeCreated", ns)
timestamp = time_el.get("SystemTime", "") if time_el is not None else ""
computer_el = system.find("e:Computer", ns)
computer = computer_el.text if computer_el is not None else ""
events.append({
"timestamp": timestamp,
"event_id": 7045,
"computer": computer,
"service_name": data_fields.get("ServiceName", ""),
"image_path": data_fields.get("ImagePath", ""),
"service_type": data_fields.get("ServiceType", ""),
"start_type": data_fields.get("StartType", ""),
"account_name": data_fields.get("AccountName", ""),
})
except Exception:
continue
return events
def analyze_service_path(image_path):
"""Analyze a service binary path for suspicious indicators."""
findings = []
path_lower = image_path.lower()
for pattern, indicator in SUSPICIOUS_PATH_PATTERNS:
if re.search(pattern, path_lower, re.IGNORECASE):
findings.append(indicator)
is_legitimate = any(re.match(p, image_path, re.IGNORECASE) for p in LEGITIMATE_SERVICE_PATHS)
risk_score = 0
if not is_legitimate:
risk_score += 20
risk_score += len(findings) * 15
risk_score = min(risk_score, 100)
return {
"suspicious_indicators": findings,
"legitimate_path": is_legitimate,
"risk_score": risk_score,
"risk_level": "CRITICAL" if risk_score >= 70 else "HIGH" if risk_score >= 50 else "MEDIUM" if risk_score >= 20 else "LOW",
}
def hunt_suspicious_services(evtx_path):
"""Main hunting function: parse events and analyze each service."""
events = parse_evtx_events(evtx_path)
results = []
for event in events:
analysis = analyze_service_path(event.get("image_path", ""))
entry = {**event, **analysis}
if entry.get("account_name", "").lower() == "localsystem" and not analysis["legitimate_path"]:
entry["risk_score"] = min(entry["risk_score"] + 20, 100)
entry["risk_level"] = "CRITICAL" if entry["risk_score"] >= 70 else entry["risk_level"]
entry["suspicious_indicators"].append("localsystem_nonstandard_path")
results.append(entry)
results.sort(key=lambda x: x.get("risk_score", 0), reverse=True)
return results
def generate_statistics(results):
"""Generate summary statistics from hunting results."""
total = len(results)
risk_counts = Counter(r.get("risk_level", "LOW") for r in results)
indicator_counts = Counter()
account_counts = Counter()
for r in results:
for ind in r.get("suspicious_indicators", []):
indicator_counts[ind] += 1
account_counts[r.get("account_name", "Unknown")] += 1
return {
"total_service_installations": total,
"risk_distribution": dict(risk_counts),
"top_indicators": dict(indicator_counts.most_common(10)),
"service_accounts": dict(account_counts.most_common(10)),
"critical_count": risk_counts.get("CRITICAL", 0),
"high_count": risk_counts.get("HIGH", 0),
}
def full_hunt(evtx_path):
"""Run comprehensive service installation threat hunt."""
results = hunt_suspicious_services(evtx_path)
stats = generate_statistics(results)
suspicious = [r for r in results if r.get("risk_score", 0) >= 20]
return {
"hunt_type": "Unusual Service Installation (T1543.003)",
"timestamp": datetime.utcnow().isoformat(),
"evtx_file": evtx_path,
"statistics": stats,
"suspicious_services": suspicious[:30],
"mitre_technique": {
"id": "T1543.003",
"name": "Create or Modify System Process: Windows Service",
"tactic": "Persistence, Privilege Escalation",
},
"recommendation": "Investigate CRITICAL and HIGH services. Verify binary hashes against known-good baselines." if stats["critical_count"] + stats["high_count"] > 0
else "No high-risk service installations detected.",
}
def main():
parser = argparse.ArgumentParser(description="Service Installation Threat Hunting Agent (T1543.003)")
parser.add_argument("evtx", help="Path to System.evtx file")
sub = parser.add_subparsers(dest="command")
sub.add_parser("parse", help="Parse and list all Event ID 7045 records")
sub.add_parser("hunt", help="Hunt for suspicious service installations")
sub.add_parser("stats", help="Generate hunting statistics")
sub.add_parser("full", help="Full threat hunt report")
args = parser.parse_args()
if args.command == "parse":
result = parse_evtx_events(args.evtx)
elif args.command == "hunt":
result = hunt_suspicious_services(args.evtx)
elif args.command == "stats":
results = hunt_suspicious_services(args.evtx)
result = generate_statistics(results)
elif args.command == "full" or args.command is None:
result = full_hunt(args.evtx)
else:
parser.print_help()
return
print(json.dumps(result, indent=2, default=str))
if __name__ == "__main__":
main()