Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills

Complete skill folder anatomy across all cybersecurity skills:
- scripts/agent.py: 80-150 line Python agents using real libraries (impacket,
  boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.)
- references/api-reference.md: real API documentation with method signatures
- LICENSE: MIT license for all skill folders
This commit is contained in:
mukul975
2026-03-10 21:02:12 +01:00
parent c74d52fa30
commit 27c6414ca5
1390 changed files with 106806 additions and 0 deletions
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Anthropic Agent Skills Contributors
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,34 @@
---
name: implementing-network-traffic-analysis-with-arkime
description: >-
Deploy and query Arkime (formerly Moloch) for full packet capture network
traffic analysis. Uses the Arkime API v3 to search sessions, download PCAPs,
analyze connection patterns, detect beaconing behavior, and identify suspicious
network flows. Monitors DNS queries, HTTP traffic, and TLS certificate anomalies
across captured traffic.
---
## Instructions
1. Install dependencies: `pip install requests`
2. Configure Arkime viewer URL and credentials.
3. Run the agent to query Arkime sessions and analyze traffic:
- Search sessions by IP, port, protocol, or expression
- Download PCAP data for forensic analysis
- Detect C2 beaconing via connection interval analysis
- Identify DNS tunneling through query length statistics
- Flag connections to known-bad TLS certificate issuers
```bash
python scripts/agent.py --arkime-url https://arkime.local:8005 --user admin --password secret --output arkime_report.json
```
## Examples
### Beaconing Detection
```
Source: 10.1.2.50 -> 185.220.101.34:443
Sessions: 288 over 24 hours
Avg interval: 300s, Jitter: 4.2%
Verdict: HIGH confidence C2 beaconing (jitter < 5%)
```
@@ -0,0 +1,75 @@
# API Reference: Arkime Network Traffic Analysis
## Authentication
```
HTTPDigestAuth(username, password)
```
All API requests require Digest authentication.
## Session Search
```
GET /api/sessions
```
| Parameter | Type | Description |
|-----------|------|-------------|
| `date` | int | Time range in hours (1=last hour) |
| `expression` | string | Arkime search expression |
| `length` | int | Max results to return |
| `order` | string | Sort field:direction (e.g. `lastPacket:desc`) |
| `fields` | string | Comma-separated field list |
## PCAP Download
```
GET /api/sessions/pcap
GET /api/sessions/pcapng
```
| Parameter | Description |
|-----------|-------------|
| `date` | Time range in hours |
| `expression` | Filter expression |
Returns raw PCAP/PCAPNG binary data.
## Connection Graph
```
GET /api/connections
```
Returns `nodes` (IPs) and `links` (connections) for network graph visualization.
## SPI View (Field Statistics)
```
GET /api/spiview
```
| Parameter | Description |
|-----------|-------------|
| `spi` | Comma-separated fields (e.g. `srcIp,dstIp,dstPort`) |
Returns top values and counts for each field.
## Session Fields
| Field | Description |
|-------|-------------|
| `srcIp` | Source IP address |
| `dstIp` | Destination IP address |
| `srcPort` | Source port |
| `dstPort` | Destination port |
| `srcBytes` | Bytes sent by source |
| `dstBytes` | Bytes sent by destination |
| `lastPacket` | Timestamp of last packet (ms) |
| `srcJa3` | JA3 fingerprint of client TLS |
| `tls.issuerCN` | TLS certificate issuer CN |
| `tls.subjectCN` | TLS certificate subject CN |
| `tls.notAfter` | Certificate expiry (ms epoch) |
## Search Expressions
```
ip.src == 10.0.0.0/8
port.dst == 443
protocols == tls
country.src == CN
bytes > 1000000
```
## Beaconing Detection Logic
- Collect connection timestamps per (src, dst, port) tuple
- Calculate intervals between consecutive connections
- Compute jitter ratio: `std_dev / avg_interval`
- Jitter < 0.05 = high confidence C2, < 0.15 = medium
@@ -0,0 +1,213 @@
#!/usr/bin/env python3
"""Arkime Network Traffic Analysis Agent - Queries Arkime API for session analysis and anomaly detection."""
import json
import logging
import argparse
from datetime import datetime
from collections import defaultdict
import requests
from requests.auth import HTTPDigestAuth
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
def arkime_request(base_url, endpoint, auth, params=None):
"""Make an authenticated request to Arkime API v3."""
url = f"{base_url}{endpoint}"
try:
resp = requests.get(url, auth=HTTPDigestAuth(*auth), params=params, verify=False, timeout=30)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
logger.error("Arkime API error %s: %s", endpoint, e)
return None
def search_sessions(base_url, auth, expression, date_range=1, length=500):
"""Search Arkime sessions with an expression filter."""
params = {
"date": date_range,
"expression": expression,
"length": length,
"order": "lastPacket:desc",
}
data = arkime_request(base_url, "/api/sessions", auth, params)
if data and "data" in data:
logger.info("Found %d sessions for expression: %s", len(data["data"]), expression)
return data["data"]
return []
def get_connections(base_url, auth, expression, date_range=1):
"""Get connection graph data from Arkime."""
params = {"date": date_range, "expression": expression}
data = arkime_request(base_url, "/api/connections", auth, params)
if data:
nodes = data.get("nodes", [])
links = data.get("links", [])
logger.info("Connection graph: %d nodes, %d links", len(nodes), len(links))
return {"nodes": nodes, "links": links}
return {"nodes": [], "links": []}
def get_spi_view(base_url, auth, expression, date_range=1):
"""Get SPI view field statistics from Arkime."""
params = {"date": date_range, "expression": expression, "spi": "srcIp,dstIp,dstPort"}
data = arkime_request(base_url, "/api/spiview", auth, params)
return data if data else {}
def detect_beaconing(sessions, interval_threshold=0.15):
"""Detect C2 beaconing by analyzing connection intervals."""
connections = defaultdict(list)
for s in sessions:
key = (s.get("srcIp", ""), s.get("dstIp", ""), s.get("dstPort", 0))
connections[key].append(s.get("lastPacket", 0))
beacons = []
for (src, dst, port), timestamps in connections.items():
if len(timestamps) < 10:
continue
timestamps.sort()
intervals = [timestamps[i + 1] - timestamps[i] for i in range(len(timestamps) - 1)]
if not intervals:
continue
avg_interval = sum(intervals) / len(intervals)
if avg_interval == 0:
continue
std_dev = (sum((i - avg_interval) ** 2 for i in intervals) / len(intervals)) ** 0.5
jitter_ratio = std_dev / avg_interval
if jitter_ratio < interval_threshold:
beacons.append({
"src_ip": src,
"dst_ip": dst,
"dst_port": port,
"session_count": len(timestamps),
"avg_interval_sec": round(avg_interval / 1000, 1),
"jitter_ratio": round(jitter_ratio, 4),
"confidence": "high" if jitter_ratio < 0.05 else "medium",
"severity": "critical",
})
logger.warning("Beaconing: %s -> %s:%d (jitter: %.4f)", src, dst, port, jitter_ratio)
return beacons
def detect_dns_tunneling(sessions, query_len_threshold=50):
"""Detect DNS tunneling via abnormally long DNS queries."""
dns_sessions = [s for s in sessions if s.get("dstPort") == 53]
suspicious = []
src_stats = defaultdict(lambda: {"count": 0, "total_bytes": 0})
for s in dns_sessions:
src = s.get("srcIp", "")
src_stats[src]["count"] += 1
src_stats[src]["total_bytes"] += s.get("srcBytes", 0) + s.get("dstBytes", 0)
for src, stats in src_stats.items():
avg_bytes = stats["total_bytes"] / max(stats["count"], 1)
if stats["count"] > 100 and avg_bytes > query_len_threshold:
suspicious.append({
"src_ip": src,
"dns_query_count": stats["count"],
"avg_bytes_per_query": round(avg_bytes, 1),
"total_bytes": stats["total_bytes"],
"severity": "high",
"indicator": "DNS tunneling - high volume with large payloads",
})
return suspicious
def detect_large_transfers(sessions, threshold_mb=100):
"""Detect unusually large data transfers."""
threshold_bytes = threshold_mb * 1024 * 1024
large = []
for s in sessions:
total = s.get("srcBytes", 0) + s.get("dstBytes", 0)
if total > threshold_bytes:
large.append({
"src_ip": s.get("srcIp", ""),
"dst_ip": s.get("dstIp", ""),
"dst_port": s.get("dstPort", 0),
"total_bytes": total,
"total_mb": round(total / (1024 * 1024), 2),
"severity": "high",
})
return large
def detect_tls_anomalies(sessions):
"""Detect TLS certificate anomalies (self-signed, expired, unusual issuers)."""
anomalies = []
for s in sessions:
tls = s.get("tls", {})
if not tls:
continue
ja3 = s.get("srcJa3", "")
issuer_cn = tls.get("issuerCN", "")
not_after = tls.get("notAfter", 0)
if issuer_cn and issuer_cn == tls.get("subjectCN", ""):
anomalies.append({
"src_ip": s.get("srcIp", ""),
"dst_ip": s.get("dstIp", ""),
"issue": "self-signed certificate",
"issuer": issuer_cn,
"severity": "medium",
})
if not_after and not_after < int(datetime.utcnow().timestamp() * 1000):
anomalies.append({
"src_ip": s.get("srcIp", ""),
"dst_ip": s.get("dstIp", ""),
"issue": "expired certificate",
"issuer": issuer_cn,
"severity": "medium",
})
return anomalies
def generate_report(beacons, dns_tunneling, large_transfers, tls_anomalies, session_count):
"""Generate network traffic analysis report."""
all_findings = beacons + dns_tunneling + large_transfers + tls_anomalies
critical = [f for f in all_findings if f.get("severity") == "critical"]
report = {
"timestamp": datetime.utcnow().isoformat(),
"sessions_analyzed": session_count,
"findings_total": len(all_findings),
"critical_count": len(critical),
"beaconing_detected": beacons,
"dns_tunneling": dns_tunneling,
"large_transfers": large_transfers,
"tls_anomalies": tls_anomalies,
}
print(f"ARKIME REPORT: {len(all_findings)} findings ({len(critical)} critical) from {session_count} sessions")
return report
def main():
parser = argparse.ArgumentParser(description="Arkime Network Traffic Analysis Agent")
parser.add_argument("--arkime-url", required=True, help="Arkime viewer URL")
parser.add_argument("--user", required=True)
parser.add_argument("--password", required=True)
parser.add_argument("--expression", default="*", help="Arkime search expression")
parser.add_argument("--date-range", type=int, default=1, help="Date range in hours")
parser.add_argument("--output", default="arkime_report.json")
args = parser.parse_args()
auth = (args.user, args.password)
sessions = search_sessions(args.arkime_url, auth, args.expression, args.date_range)
beacons = detect_beaconing(sessions)
dns_tunnel = detect_dns_tunneling(sessions)
large = detect_large_transfers(sessions)
tls = detect_tls_anomalies(sessions)
report = generate_report(beacons, dns_tunnel, large, tls, len(sessions))
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
logger.info("Report saved to %s", args.output)
if __name__ == "__main__":
main()