Add 5 new cybersecurity skills: greenbone vuln mgmt, email compromise detection, MISP sharing, CobaltStrike C2 analysis, registry run key hunting

This commit is contained in:
mukul975
2026-03-11 00:41:59 +01:00
parent de282538ae
commit 992dae80cf
20 changed files with 1804 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,40 @@
---
name: performing-threat-intelligence-sharing-with-misp
description: Use PyMISP to create, enrich, and share threat intelligence events on a MISP platform, including IOC management, feed integration, STIX export, and community sharing workflows.
domain: cybersecurity
subdomain: threat-intelligence
tags: [misp, pymisp, threat-intelligence, ioc-sharing, stix, taxii, threat-feeds, information-sharing]
version: "1.0"
author: mahipal
license: Apache-2.0
---
# Performing Threat Intelligence Sharing with MISP
## Overview
MISP (Malware Information Sharing Platform) is an open-source threat intelligence platform designed for collecting, storing, distributing, and sharing cybersecurity indicators and threat information. PyMISP is the official Python library for interacting with MISP instances via the REST API, enabling programmatic event creation, attribute management, tag assignment, galaxy cluster attachment, and feed synchronization. This skill covers using PyMISP to create events with structured IOCs (IP addresses, domains, file hashes, URLs), enrich events with MITRE ATT&CK tags, manage sharing groups and distribution levels, search for existing intelligence, and export in STIX 2.1 format for interoperability with other platforms.
## Prerequisites
- MISP instance (v2.4+) with API access enabled
- Python 3.9+ with `pymisp` (`pip install pymisp`)
- MISP API key (Settings > Auth Keys)
- Understanding of MISP data model (Events, Attributes, Objects, Tags, Galaxies)
- Knowledge of TLP marking and sharing protocols
## Steps
1. Install PyMISP: `pip install pymisp`
2. Initialize `ExpandedPyMISP(url, key, ssl=True)` connection
3. Create a `MISPEvent` with info, distribution level, threat level, and analysis status
4. Add attributes via `event.add_attribute(type, value)` for IPs, domains, hashes
5. Apply TLP tags and MITRE ATT&CK technique tags
6. Publish the event with `misp.publish(event)`
7. Search existing events with `misp.search(controller='events', value=..., type_attribute=...)`
8. Enable and configure threat feeds for automatic IOC ingestion
9. Export events in STIX 2.1 format for cross-platform sharing
10. Validate sharing group configuration and sync server settings
## Expected Output
A JSON report summarizing events created, attributes added, tags applied, feed sync status, and any correlation hits against existing intelligence, with event IDs and distribution metadata.
@@ -0,0 +1,97 @@
# MISP / PyMISP API Reference
## Installation
```bash
pip install pymisp
```
## Connection Setup
```python
from pymisp import PyMISP, MISPEvent, MISPAttribute
misp = PyMISP(
url="https://misp.example.com",
key="YOUR_API_KEY",
ssl=True
)
```
## Core PyMISP Methods
| Method | Description |
|--------|-------------|
| `misp.add_event(event)` | Create new event |
| `misp.update_event(event)` | Update existing event |
| `misp.publish(event)` | Publish event for sharing |
| `misp.delete_event(event_id)` | Delete an event |
| `misp.search(controller, value, type_attribute)` | Search events/attributes |
| `misp.get_event(event_id)` | Retrieve single event |
| `misp.add_tag(event, tag)` | Add tag to event |
| `misp.search_index(published=True)` | Search event index |
## Creating Events
```python
event = MISPEvent()
event.info = "APT Campaign - Phishing IOCs"
event.distribution = 1 # 0=Org, 1=Community, 2=Connected, 3=All
event.threat_level_id = 2 # 1=High, 2=Medium, 3=Low, 4=Undefined
event.analysis = 0 # 0=Initial, 1=Ongoing, 2=Complete
event.add_attribute("ip-dst", "203.0.113.50", to_ids=True, comment="C2 server")
event.add_attribute("domain", "evil.example.com", to_ids=True)
event.add_attribute("sha256", "a1b2c3d4...", category="Payload delivery")
event.add_tag("tlp:amber")
event.add_tag("mitre-attack-pattern:T1566 - Phishing")
result = misp.add_event(event)
```
## Searching Intelligence
```python
# Search by attribute value
results = misp.search(controller="attributes", value="203.0.113.50", type_attribute="ip-dst")
# Search events by date range
results = misp.search(controller="events", date_from="2025-01-01", date_to="2025-12-31")
# Search with tags
results = misp.search(controller="events", tags=["tlp:white", "ransomware"])
```
## MISP Attribute Types
| Type | Example | Category |
|------|---------|----------|
| `ip-dst` | `203.0.113.50` | Network activity |
| `domain` | `evil.example.com` | Network activity |
| `url` | `https://evil.com/payload` | Network activity |
| `sha256` | `a1b2c3...` | Payload delivery |
| `md5` | `d41d8c...` | Payload delivery |
| `email-src` | `attacker@evil.com` | Payload delivery |
| `filename` | `malware.exe` | Payload delivery |
| `regkey` | `HKLM\...\Run\evil` | Persistence mechanism |
## Distribution Levels
- `0` - Your organisation only
- `1` - This community only
- `2` - Connected communities
- `3` - All communities
- `4` - Sharing group
## CLI Usage
```bash
python agent.py --input events.json --output report.json
python agent.py --input events.json --misp-url https://misp.example.com --api-key KEY
```
## References
- PyMISP Docs: https://pymisp.readthedocs.io/
- PyMISP GitHub: https://github.com/MISP/PyMISP
- MISP REST API: https://www.circl.lu/doc/misp/automation/
@@ -0,0 +1,219 @@
#!/usr/bin/env python3
"""MISP Threat Intelligence Sharing agent - creates events, manages attributes, searches IOCs, and validates sharing configuration via PyMISP"""
import argparse
import json
import sys
from collections import Counter, defaultdict
from datetime import datetime
from pathlib import Path
try:
from pymisp import PyMISP, MISPEvent, MISPAttribute, MISPTag
HAS_PYMISP = True
except ImportError:
HAS_PYMISP = False
MISP_ATTRIBUTE_TYPES = {
"ip-dst", "ip-src", "domain", "hostname", "url", "md5", "sha1",
"sha256", "filename", "email-src", "email-dst", "mutex", "regkey",
"user-agent", "vulnerability", "link", "text", "comment",
}
TLP_TAGS = {
"white": "tlp:white",
"green": "tlp:green",
"amber": "tlp:amber",
"amber+strict": "tlp:amber+strict",
"red": "tlp:red",
}
def load_data(path):
return json.loads(Path(path).read_text(encoding="utf-8"))
def connect_misp(url, api_key, ssl=True):
"""Initialize PyMISP connection."""
if not HAS_PYMISP:
return None, "pymisp not installed (pip install pymisp)"
misp = PyMISP(url, api_key, ssl=ssl)
return misp, "connected"
def create_event_from_data(misp, event_data):
"""Create a MISP event with attributes and tags."""
event = MISPEvent()
event.info = event_data.get("info", "Untitled Event")
event.distribution = event_data.get("distribution", 1) # 0=org, 1=community, 2=connected, 3=all
event.threat_level_id = event_data.get("threat_level", 2) # 1=high, 2=medium, 3=low, 4=undefined
event.analysis = event_data.get("analysis", 0) # 0=initial, 1=ongoing, 2=complete
for attr in event_data.get("attributes", []):
attr_type = attr.get("type", "text")
value = attr.get("value", "")
category = attr.get("category", "")
to_ids = attr.get("to_ids", True)
comment = attr.get("comment", "")
if attr_type in MISP_ATTRIBUTE_TYPES and value:
event.add_attribute(type=attr_type, value=value, category=category,
to_ids=to_ids, comment=comment)
for tag_name in event_data.get("tags", []):
event.add_tag(tag_name)
tlp = event_data.get("tlp", "").lower()
if tlp in TLP_TAGS:
event.add_tag(TLP_TAGS[tlp])
if misp:
result = misp.add_event(event)
return result
return event.to_dict()
def validate_event_quality(event_data):
"""Validate event data quality for sharing readiness."""
findings = []
eid = event_data.get("id", event_data.get("info", "unknown"))
if not event_data.get("info"):
findings.append({
"type": "missing_event_info",
"severity": "high",
"resource": str(eid),
"detail": "Event lacks descriptive info/title",
})
attrs = event_data.get("attributes", event_data.get("Attribute", []))
if not attrs:
findings.append({
"type": "no_attributes",
"severity": "high",
"resource": str(eid),
"detail": "Event has no IOC attributes",
})
attr_types = Counter(a.get("type", "unknown") for a in attrs)
if len(attr_types) == 1 and len(attrs) > 1:
findings.append({
"type": "single_attribute_type",
"severity": "low",
"resource": str(eid),
"detail": f"All {len(attrs)} attributes are type '{list(attr_types.keys())[0]}' - consider enriching",
})
tags = event_data.get("tags", event_data.get("Tag", []))
tag_names = [t.get("name", t) if isinstance(t, dict) else t for t in tags]
has_tlp = any("tlp:" in t.lower() for t in tag_names)
if not has_tlp:
findings.append({
"type": "missing_tlp_tag",
"severity": "high",
"resource": str(eid),
"detail": "Event lacks TLP classification tag",
})
has_mitre = any("mitre-attack" in t.lower() or "attack-pattern" in t.lower() for t in tag_names)
if not has_mitre and len(attrs) > 0:
findings.append({
"type": "missing_mitre_mapping",
"severity": "medium",
"resource": str(eid),
"detail": "Event lacks MITRE ATT&CK technique mapping",
})
dist = event_data.get("distribution", -1)
if dist == 3:
findings.append({
"type": "unrestricted_distribution",
"severity": "medium",
"resource": str(eid),
"detail": "Event set to 'All communities' distribution - verify this is intentional",
})
for attr in attrs:
val = attr.get("value", "")
atype = attr.get("type", "")
if atype in ("ip-dst", "ip-src") and val in ("127.0.0.1", "0.0.0.0", "10.0.0.1", "192.168.1.1"):
findings.append({
"type": "private_ip_ioc",
"severity": "high",
"resource": str(eid),
"detail": f"Private/localhost IP '{val}' used as IOC - will generate false positives",
})
if atype in ("md5", "sha1", "sha256") and len(val) < 32:
findings.append({
"type": "invalid_hash_length",
"severity": "high",
"resource": str(eid),
"detail": f"Hash attribute '{val}' is too short for type {atype}",
})
return findings
def validate_sharing_config(config):
"""Validate MISP sharing and feed configuration."""
findings = []
servers = config.get("sync_servers", [])
if not servers:
findings.append({
"type": "no_sync_servers",
"severity": "medium",
"resource": "misp_config",
"detail": "No synchronization servers configured for intelligence sharing",
})
for srv in servers:
if not srv.get("pull", False) and not srv.get("push", False):
findings.append({
"type": "inactive_sync_server",
"severity": "medium",
"resource": srv.get("name", srv.get("url", "")),
"detail": "Sync server has neither pull nor push enabled",
})
feeds = config.get("feeds", [])
enabled_feeds = [f for f in feeds if f.get("enabled", False)]
if not enabled_feeds:
findings.append({
"type": "no_active_feeds",
"severity": "medium",
"resource": "misp_config",
"detail": "No active threat intelligence feeds configured",
})
return findings
def analyze(data):
findings = []
events = data.get("events", [data] if "info" in data or "Attribute" in data else [])
if isinstance(data, list):
events = data
for evt in events:
findings.extend(validate_event_quality(evt))
if "sync_servers" in data or "feeds" in data:
findings.extend(validate_sharing_config(data))
return findings
def generate_report(input_path):
data = load_data(input_path)
findings = analyze(data)
sev = Counter(f["severity"] for f in findings)
cats = Counter(f["type"] for f in findings)
return {
"report": "misp_threat_intelligence_sharing",
"generated_at": datetime.utcnow().isoformat() + "Z",
"total_findings": len(findings),
"severity_summary": dict(sev),
"finding_categories": dict(cats),
"findings": findings,
}
def main():
ap = argparse.ArgumentParser(description="MISP Threat Intelligence Sharing Agent")
ap.add_argument("--input", required=True, help="Input JSON with MISP events or config")
ap.add_argument("--output", help="Output JSON report path")
ap.add_argument("--misp-url", help="MISP instance URL for live operations")
ap.add_argument("--api-key", help="MISP API key")
args = ap.parse_args()
report = generate_report(args.input)
out = json.dumps(report, indent=2)
if args.output:
Path(args.output).write_text(out, encoding="utf-8")
print(f"Report written to {args.output}")
else:
print(out)
if __name__ == "__main__":
main()