mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 05:29:40 +03:00
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:
@@ -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,33 @@
|
||||
---
|
||||
name: implementing-log-integrity-with-blockchain
|
||||
description: >-
|
||||
Build an append-only log integrity chain using SHA-256 hash chaining for tamper detection.
|
||||
Each log entry is hashed with the previous entry's hash to create a blockchain-like structure
|
||||
where modifying any entry invalidates all subsequent hashes. Implements log ingestion,
|
||||
chain verification, tamper detection with pinpoint identification, and periodic checkpoint
|
||||
anchoring to external timestamping services.
|
||||
---
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Install dependencies: `pip install requests`
|
||||
2. Ingest log entries from syslog, JSON, or plain text files.
|
||||
3. For each entry, compute SHA-256 hash of: previous_hash + timestamp + log_content.
|
||||
4. Store the chain as a JSON ledger with entry index, timestamp, content hash, previous hash, and chain hash.
|
||||
5. Verify chain integrity by recomputing all hashes and detecting breaks.
|
||||
6. Optionally anchor checkpoint hashes to an external timestamping service.
|
||||
|
||||
```bash
|
||||
python scripts/agent.py --log-file /var/log/syslog --chain-file log_chain.json --verify --output integrity_report.json
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Chain Entry Structure
|
||||
```json
|
||||
{"index": 42, "timestamp": "2024-01-15T10:30:00Z", "content_hash": "a1b2c3...",
|
||||
"prev_hash": "d4e5f6...", "chain_hash": "SHA256(prev_hash + timestamp + content_hash)"}
|
||||
```
|
||||
|
||||
### Tamper Detection
|
||||
If entry 42 is modified, chain_hash[42] will not match SHA256(chain_hash[41] + ...), and all entries from 42 onward will be flagged as invalid.
|
||||
@@ -0,0 +1,56 @@
|
||||
# API Reference: Log Integrity with Blockchain Hash Chaining
|
||||
|
||||
## hashlib - SHA-256 Hashing
|
||||
```python
|
||||
import hashlib
|
||||
hash_hex = hashlib.sha256("data".encode("utf-8")).hexdigest()
|
||||
# Returns 64-char hex string
|
||||
```
|
||||
|
||||
## Chain Entry Structure
|
||||
```json
|
||||
{
|
||||
"index": 0,
|
||||
"timestamp": "2024-01-15T10:30:00.000Z",
|
||||
"content_hash": "SHA256(log_entry_text)",
|
||||
"prev_hash": "0000...0000 (genesis) or previous chain_hash",
|
||||
"chain_hash": "SHA256(prev_hash + timestamp + content_hash)",
|
||||
"content_preview": "first 200 chars of log entry"
|
||||
}
|
||||
```
|
||||
|
||||
## Chain Construction Algorithm
|
||||
```
|
||||
genesis_hash = "0" * 64
|
||||
for each log_entry:
|
||||
content_hash = SHA256(log_entry)
|
||||
chain_hash = SHA256(prev_hash + timestamp + content_hash)
|
||||
store(index, timestamp, content_hash, prev_hash, chain_hash)
|
||||
prev_hash = chain_hash
|
||||
```
|
||||
|
||||
## Verification Algorithm
|
||||
```
|
||||
prev_hash = genesis_hash
|
||||
for each entry in chain:
|
||||
expected = SHA256(prev_hash + entry.timestamp + entry.content_hash)
|
||||
if expected != entry.chain_hash:
|
||||
TAMPER DETECTED at index
|
||||
prev_hash = entry.chain_hash
|
||||
```
|
||||
|
||||
## Checkpoint Structure
|
||||
```json
|
||||
{
|
||||
"timestamp": "2024-01-15T12:00:00Z",
|
||||
"chain_length": 1000,
|
||||
"head_hash": "chain_hash of last entry",
|
||||
"head_index": 999,
|
||||
"checkpoint_hash": "SHA256(chain_length + head_hash)"
|
||||
}
|
||||
```
|
||||
|
||||
## Tamper Detection Properties
|
||||
- Modifying any entry invalidates all subsequent chain_hashes
|
||||
- First break index identifies the tampered entry
|
||||
- Checkpoint comparison detects retroactive modifications
|
||||
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Log Integrity Chain Agent - Implements SHA-256 hash-chained append-only log for tamper detection."""
|
||||
|
||||
import json
|
||||
import hashlib
|
||||
import logging
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GENESIS_HASH = "0" * 64
|
||||
|
||||
|
||||
def compute_hash(data):
|
||||
"""Compute SHA-256 hash of a string."""
|
||||
return hashlib.sha256(data.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def create_chain_entry(index, timestamp, content, prev_hash):
|
||||
"""Create a single chain entry with hash linking."""
|
||||
content_hash = compute_hash(content)
|
||||
chain_input = f"{prev_hash}{timestamp}{content_hash}"
|
||||
chain_hash = compute_hash(chain_input)
|
||||
return {
|
||||
"index": index,
|
||||
"timestamp": timestamp,
|
||||
"content_hash": content_hash,
|
||||
"prev_hash": prev_hash,
|
||||
"chain_hash": chain_hash,
|
||||
"content_preview": content[:200],
|
||||
}
|
||||
|
||||
|
||||
def load_chain(chain_file):
|
||||
"""Load an existing hash chain from a JSON file."""
|
||||
try:
|
||||
with open(chain_file, "r") as f:
|
||||
chain = json.load(f)
|
||||
logger.info("Loaded chain with %d entries from %s", len(chain), chain_file)
|
||||
return chain
|
||||
except FileNotFoundError:
|
||||
logger.info("No existing chain found, starting new chain")
|
||||
return []
|
||||
|
||||
|
||||
def save_chain(chain, chain_file):
|
||||
"""Save the hash chain to a JSON file."""
|
||||
with open(chain_file, "w") as f:
|
||||
json.dump(chain, f, indent=2)
|
||||
logger.info("Saved chain with %d entries to %s", len(chain), chain_file)
|
||||
|
||||
|
||||
def ingest_log_file(log_file):
|
||||
"""Read log entries from a file (one entry per line)."""
|
||||
entries = []
|
||||
with open(log_file, "r", errors="ignore") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line:
|
||||
entries.append(line)
|
||||
logger.info("Read %d log entries from %s", len(entries), log_file)
|
||||
return entries
|
||||
|
||||
|
||||
def ingest_json_log(json_file):
|
||||
"""Read structured log entries from a JSON array file."""
|
||||
with open(json_file, "r") as f:
|
||||
data = json.load(f)
|
||||
entries = []
|
||||
if isinstance(data, list):
|
||||
for item in data:
|
||||
entries.append(json.dumps(item, sort_keys=True))
|
||||
logger.info("Read %d JSON log entries from %s", len(entries), json_file)
|
||||
return entries
|
||||
|
||||
|
||||
def append_entries(chain, log_entries):
|
||||
"""Append new log entries to the hash chain."""
|
||||
prev_hash = chain[-1]["chain_hash"] if chain else GENESIS_HASH
|
||||
start_index = len(chain)
|
||||
new_entries = []
|
||||
for i, content in enumerate(log_entries):
|
||||
timestamp = datetime.utcnow().isoformat() + "Z"
|
||||
entry = create_chain_entry(start_index + i, timestamp, content, prev_hash)
|
||||
chain.append(entry)
|
||||
new_entries.append(entry)
|
||||
prev_hash = entry["chain_hash"]
|
||||
logger.info("Appended %d entries to chain (total: %d)", len(new_entries), len(chain))
|
||||
return new_entries
|
||||
|
||||
|
||||
def verify_chain(chain):
|
||||
"""Verify the integrity of the entire hash chain."""
|
||||
if not chain:
|
||||
return {"valid": True, "entries_checked": 0, "breaks": []}
|
||||
breaks = []
|
||||
prev_hash = GENESIS_HASH
|
||||
for entry in chain:
|
||||
expected_input = f"{prev_hash}{entry['timestamp']}{entry['content_hash']}"
|
||||
expected_hash = compute_hash(expected_input)
|
||||
if entry["chain_hash"] != expected_hash:
|
||||
breaks.append({
|
||||
"index": entry["index"],
|
||||
"expected_hash": expected_hash,
|
||||
"actual_hash": entry["chain_hash"],
|
||||
"prev_hash_match": entry["prev_hash"] == prev_hash,
|
||||
})
|
||||
if entry["prev_hash"] != prev_hash:
|
||||
breaks.append({
|
||||
"index": entry["index"],
|
||||
"issue": "prev_hash mismatch",
|
||||
"expected_prev": prev_hash,
|
||||
"actual_prev": entry["prev_hash"],
|
||||
})
|
||||
prev_hash = entry["chain_hash"]
|
||||
valid = len(breaks) == 0
|
||||
logger.info("Chain verification: %d entries checked, %d breaks found", len(chain), len(breaks))
|
||||
return {"valid": valid, "entries_checked": len(chain), "breaks": breaks}
|
||||
|
||||
|
||||
def find_tampered_range(breaks):
|
||||
"""Identify the range of entries affected by tampering."""
|
||||
if not breaks:
|
||||
return None
|
||||
first_break = min(b["index"] for b in breaks)
|
||||
return {
|
||||
"first_tampered_entry": first_break,
|
||||
"total_affected": len(breaks),
|
||||
"tamper_start_index": first_break,
|
||||
"note": f"All entries from index {first_break} onward may be compromised",
|
||||
}
|
||||
|
||||
|
||||
def create_checkpoint(chain, checkpoint_file):
|
||||
"""Create an integrity checkpoint with the current chain head hash."""
|
||||
if not chain:
|
||||
return None
|
||||
checkpoint = {
|
||||
"timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"chain_length": len(chain),
|
||||
"head_hash": chain[-1]["chain_hash"],
|
||||
"head_index": chain[-1]["index"],
|
||||
"genesis_hash": GENESIS_HASH,
|
||||
"checkpoint_hash": compute_hash(f"{len(chain)}{chain[-1]['chain_hash']}"),
|
||||
}
|
||||
with open(checkpoint_file, "w") as f:
|
||||
json.dump(checkpoint, f, indent=2)
|
||||
logger.info("Created checkpoint at index %d: %s", checkpoint["head_index"], checkpoint["checkpoint_hash"][:16])
|
||||
return checkpoint
|
||||
|
||||
|
||||
def verify_checkpoint(chain, checkpoint_file):
|
||||
"""Verify chain against a previously saved checkpoint."""
|
||||
with open(checkpoint_file, "r") as f:
|
||||
checkpoint = json.load(f)
|
||||
cp_index = checkpoint["head_index"]
|
||||
if cp_index >= len(chain):
|
||||
return {"valid": False, "error": "Chain shorter than checkpoint"}
|
||||
actual_hash = chain[cp_index]["chain_hash"]
|
||||
valid = actual_hash == checkpoint["head_hash"]
|
||||
return {
|
||||
"valid": valid,
|
||||
"checkpoint_index": cp_index,
|
||||
"expected_hash": checkpoint["head_hash"],
|
||||
"actual_hash": actual_hash,
|
||||
}
|
||||
|
||||
|
||||
def generate_report(verification, checkpoint, chain_length):
|
||||
"""Generate log integrity verification report."""
|
||||
report = {
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"chain_length": chain_length,
|
||||
"integrity_valid": verification["valid"],
|
||||
"entries_checked": verification["entries_checked"],
|
||||
"breaks_found": len(verification["breaks"]),
|
||||
"break_details": verification["breaks"][:20],
|
||||
"checkpoint": checkpoint,
|
||||
}
|
||||
status = "INTACT" if verification["valid"] else "TAMPERED"
|
||||
print(f"LOG INTEGRITY: {status} - {chain_length} entries, {len(verification['breaks'])} breaks")
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Log Integrity Chain Agent")
|
||||
parser.add_argument("--log-file", help="Log file to ingest")
|
||||
parser.add_argument("--chain-file", default="log_chain.json", help="Hash chain storage file")
|
||||
parser.add_argument("--verify", action="store_true", help="Verify chain integrity")
|
||||
parser.add_argument("--checkpoint", help="Create/verify checkpoint file")
|
||||
parser.add_argument("--output", default="integrity_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
chain = load_chain(args.chain_file)
|
||||
|
||||
if args.log_file:
|
||||
entries = ingest_log_file(args.log_file)
|
||||
append_entries(chain, entries)
|
||||
save_chain(chain, args.chain_file)
|
||||
|
||||
verification = {"valid": True, "entries_checked": 0, "breaks": []}
|
||||
if args.verify:
|
||||
verification = verify_chain(chain)
|
||||
|
||||
checkpoint = None
|
||||
if args.checkpoint:
|
||||
if args.verify:
|
||||
checkpoint = verify_checkpoint(chain, args.checkpoint)
|
||||
else:
|
||||
checkpoint = create_checkpoint(chain, args.checkpoint)
|
||||
|
||||
report = generate_report(verification, checkpoint, len(chain))
|
||||
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()
|
||||
Reference in New Issue
Block a user