mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-26 19:29:41 +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,67 @@
|
||||
# API Reference: Analyzing Windows Event Logs in Splunk
|
||||
|
||||
## splunk-sdk Connection
|
||||
|
||||
```python
|
||||
import splunklib.client as client
|
||||
service = client.connect(host="splunk", port=8089, username="admin", password="pass")
|
||||
```
|
||||
|
||||
## Key Windows Security Event IDs
|
||||
|
||||
| EventCode | Description | ATT&CK Technique |
|
||||
|-----------|-------------|-------------------|
|
||||
| 4624 | Successful logon | T1078 |
|
||||
| 4625 | Failed logon | T1110 |
|
||||
| 4648 | Explicit credential logon | T1078 |
|
||||
| 4672 | Special privileges assigned | T1134 |
|
||||
| 4688 | New process created | T1059 |
|
||||
| 4698 | Scheduled task created | T1053.005 |
|
||||
| 4720 | User account created | T1136.001 |
|
||||
| 4732 | Member added to security group | T1098 |
|
||||
| 4768 | Kerberos TGT requested | T1558 |
|
||||
| 4769 | Kerberos service ticket | T1558.003 |
|
||||
|
||||
## Key Sysmon Event IDs
|
||||
|
||||
| EventCode | Description |
|
||||
|-----------|-------------|
|
||||
| 1 | Process creation (full command line, hashes) |
|
||||
| 3 | Network connection |
|
||||
| 7 | Image loaded (DLL) |
|
||||
| 10 | Process access (LSASS credential dumping) |
|
||||
| 11 | File creation |
|
||||
| 13 | Registry value set |
|
||||
| 22 | DNS query |
|
||||
|
||||
## Logon Types
|
||||
|
||||
| Type | Description | Context |
|
||||
|------|-------------|---------|
|
||||
| 2 | Interactive | Local console logon |
|
||||
| 3 | Network | SMB, WMI, PowerShell Remoting |
|
||||
| 7 | Unlock | Workstation unlock |
|
||||
| 9 | NewCredentials | runas /netonly |
|
||||
| 10 | RemoteInteractive | RDP logon |
|
||||
|
||||
## SPL Detection Patterns
|
||||
|
||||
```spl
|
||||
# Brute force detection
|
||||
index=wineventlog EventCode=4625 | stats count by src_ip | where count > 20
|
||||
|
||||
# Kerberoasting (T1558.003)
|
||||
index=wineventlog EventCode=4769 Ticket_Encryption_Type=0x17
|
||||
| where ServiceName != "krbtgt"
|
||||
|
||||
# DCSync detection (T1003.006)
|
||||
index=wineventlog EventCode=4662
|
||||
| where ObjectType="*domainDNS*"
|
||||
| search Properties="*Replicating Directory Changes*"
|
||||
```
|
||||
|
||||
### References
|
||||
|
||||
- splunk-sdk: https://pypi.org/project/splunk-sdk/
|
||||
- Splunk CIM: https://docs.splunk.com/Documentation/CIM/latest/User/Overview
|
||||
- Windows Security Log Encyclopedia: https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/
|
||||
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for analyzing Windows event logs in Splunk for SOC operations."""
|
||||
|
||||
import os
|
||||
import json
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
import splunklib.client as client
|
||||
import splunklib.results as results
|
||||
|
||||
|
||||
def connect(host, port, username, password):
|
||||
"""Connect to Splunk Enterprise."""
|
||||
return client.connect(
|
||||
host=host, port=port, username=username, password=password, autologin=True
|
||||
)
|
||||
|
||||
|
||||
def search(service, query, earliest="-24h", latest="now"):
|
||||
"""Run a blocking Splunk search and return results."""
|
||||
job = service.jobs.create(
|
||||
f"search {query}",
|
||||
**{"earliest_time": earliest, "latest_time": latest, "exec_mode": "blocking"}
|
||||
)
|
||||
reader = results.JSONResultsReader(job.results(output_mode="json"))
|
||||
rows = [r for r in reader if isinstance(r, dict)]
|
||||
job.cancel()
|
||||
return rows
|
||||
|
||||
|
||||
def detect_brute_force(service, earliest="-24h", threshold=20):
|
||||
"""Detect brute force via EventCode 4625 with logon type classification."""
|
||||
query = (
|
||||
'index=wineventlog sourcetype="WinEventLog:Security" EventCode=4625 '
|
||||
"| stats count, dc(TargetUserName) as unique_users, "
|
||||
"values(TargetUserName) as targeted_users by src_ip, Logon_Type, Status "
|
||||
f"| where count > {threshold} "
|
||||
'| eval attack_type=case(Logon_Type=3,"Network",Logon_Type=10,"RDP",'
|
||||
'Logon_Type=2,"Interactive",1=1,"Other") '
|
||||
"| sort -count"
|
||||
)
|
||||
return search(service, query, earliest)
|
||||
|
||||
|
||||
def detect_password_spray(service, earliest="-24h"):
|
||||
"""Detect password spray attacks targeting many accounts from one source."""
|
||||
query = (
|
||||
'index=wineventlog sourcetype="WinEventLog:Security" EventCode=4625 Logon_Type=3 '
|
||||
"| bin _time span=10m "
|
||||
"| stats dc(TargetUserName) as unique_users, count as total by src_ip, _time "
|
||||
"| where unique_users > 10 AND total < unique_users * 3 "
|
||||
'| eval confidence=if(unique_users > 25, "HIGH", "MEDIUM")'
|
||||
)
|
||||
return search(service, query, earliest)
|
||||
|
||||
|
||||
def detect_new_admin_accounts(service, earliest="-7d"):
|
||||
"""Detect new accounts added to the Administrators group (T1136.001)."""
|
||||
query = (
|
||||
'index=wineventlog sourcetype="WinEventLog:Security" EventCode=4720 '
|
||||
'| join TargetUserName type=left [search index=wineventlog EventCode=4732 '
|
||||
'TargetUserName="Administrators" | rename MemberName as TargetUserName] '
|
||||
"| table _time, SubjectUserName, TargetUserName, ComputerName"
|
||||
)
|
||||
return search(service, query, earliest)
|
||||
|
||||
|
||||
def detect_lsass_access(service, earliest="-24h"):
|
||||
"""Detect LSASS credential dumping via Sysmon Event 10 (T1003.001)."""
|
||||
query = (
|
||||
'index=sysmon EventCode=10 TargetImage="*\\\\lsass.exe" '
|
||||
'GrantedAccess IN ("0x1010","0x1038","0x1fffff","0x40") '
|
||||
"| stats count by SourceImage, SourceUser, Computer, GrantedAccess "
|
||||
'| where NOT match(SourceImage, "(svchost|csrss|wininit|MsMpEng)") '
|
||||
"| sort -count"
|
||||
)
|
||||
return search(service, query, earliest)
|
||||
|
||||
|
||||
def detect_lateral_movement_smb(service, earliest="-24h"):
|
||||
"""Detect SMB lateral movement via Type 3 logons to many hosts (T1021.002)."""
|
||||
query = (
|
||||
'index=wineventlog sourcetype="WinEventLog:Security" EventCode=4624 Logon_Type=3 '
|
||||
"| stats dc(ComputerName) as targets, values(ComputerName) as dest_hosts "
|
||||
"by src_ip, TargetUserName "
|
||||
"| where targets > 3 | sort -targets"
|
||||
)
|
||||
return search(service, query, earliest)
|
||||
|
||||
|
||||
def detect_psexec(service, earliest="-24h"):
|
||||
"""Detect PsExec execution via Sysmon process creation (T1021.002)."""
|
||||
query = (
|
||||
"index=sysmon EventCode=1 "
|
||||
'(Image="*\\\\psexec.exe" OR Image="*\\\\psexesvc.exe" '
|
||||
'OR ParentImage="*\\\\psexesvc.exe") '
|
||||
"| table _time, Computer, User, ParentImage, Image, CommandLine"
|
||||
)
|
||||
return search(service, query, earliest)
|
||||
|
||||
|
||||
def build_forensic_timeline(service, hostname, earliest, latest="now"):
|
||||
"""Build a comprehensive forensic timeline for a host."""
|
||||
query = (
|
||||
f'(index=wineventlog OR index=sysmon) Computer="{hostname}" '
|
||||
"| eval desc=case("
|
||||
' EventCode=4624, "Logon: ".TargetUserName." (Type ".Logon_Type.")",'
|
||||
' EventCode=4625, "Failed Logon: ".TargetUserName,'
|
||||
' EventCode=1, "Process: ".Image," CMD: ".CommandLine,'
|
||||
' EventCode=3, "Network: ".DestinationIp.":".DestinationPort,'
|
||||
' EventCode=11, "File Created: ".TargetFilename,'
|
||||
' EventCode=13, "Registry: ".TargetObject,'
|
||||
' 1=1, "Event ".EventCode) '
|
||||
"| sort _time | table _time, EventCode, desc, User, src_ip"
|
||||
)
|
||||
return search(service, query, earliest, latest)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Windows Event Log Splunk Analysis Agent")
|
||||
parser.add_argument("--host", default=os.getenv("SPLUNK_HOST", "localhost"))
|
||||
parser.add_argument("--port", type=int, default=int(os.getenv("SPLUNK_PORT", "8089")))
|
||||
parser.add_argument("--username", default=os.getenv("SPLUNK_USERNAME", "admin"))
|
||||
parser.add_argument("--password", default=os.getenv("SPLUNK_PASSWORD", ""))
|
||||
parser.add_argument("--earliest", default="-24h")
|
||||
parser.add_argument("--hostname", help="Target hostname for timeline")
|
||||
parser.add_argument("--action", choices=[
|
||||
"brute_force", "password_spray", "new_admin", "lsass_access",
|
||||
"lateral_smb", "psexec", "timeline", "full_hunt"
|
||||
], default="full_hunt")
|
||||
args = parser.parse_args()
|
||||
|
||||
svc = connect(args.host, args.port, args.username, args.password)
|
||||
findings = {}
|
||||
|
||||
if args.action in ("brute_force", "full_hunt"):
|
||||
findings["brute_force"] = detect_brute_force(svc, args.earliest)
|
||||
print(f"[+] Brute force sources: {len(findings['brute_force'])}")
|
||||
|
||||
if args.action in ("password_spray", "full_hunt"):
|
||||
findings["password_spray"] = detect_password_spray(svc, args.earliest)
|
||||
print(f"[+] Password spray events: {len(findings['password_spray'])}")
|
||||
|
||||
if args.action in ("new_admin", "full_hunt"):
|
||||
findings["new_admin"] = detect_new_admin_accounts(svc)
|
||||
print(f"[+] New admin accounts: {len(findings['new_admin'])}")
|
||||
|
||||
if args.action in ("lsass_access", "full_hunt"):
|
||||
findings["lsass_access"] = detect_lsass_access(svc, args.earliest)
|
||||
print(f"[+] LSASS access events: {len(findings['lsass_access'])}")
|
||||
|
||||
if args.action in ("lateral_smb", "full_hunt"):
|
||||
findings["lateral_smb"] = detect_lateral_movement_smb(svc, args.earliest)
|
||||
print(f"[+] Lateral movement paths: {len(findings['lateral_smb'])}")
|
||||
|
||||
if args.action == "timeline" and args.hostname:
|
||||
findings["timeline"] = build_forensic_timeline(svc, args.hostname, args.earliest)
|
||||
print(f"[+] Timeline events: {len(findings['timeline'])}")
|
||||
|
||||
print(json.dumps({"generated_at": datetime.utcnow().isoformat(), "findings": findings}, indent=2, default=str))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user