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,60 @@
# API Reference: Active Directory Attack Simulation Agent
## Dependencies
| Library | Version | Purpose |
|---------|---------|---------|
| impacket | >=0.11.0 | Kerberos attacks, SMB interaction, DCSync |
| ldap3 | >=2.9 | LDAP enumeration of users, groups, SPNs |
## CLI Usage
```bash
python scripts/agent.py \
--dc-ip 10.10.10.1 \
--domain corp.local \
--username testuser \
--password 'P@ssw0rd' \
--output ad_report.json
```
## Functions
### `ldap_enum_users(dc_ip, domain, username, password) -> list`
Enumerates all domain user objects via LDAP. Returns list of dicts with `samaccountname`, `spns`, `no_preauth`, `admin_count`.
### `find_kerberoastable(users) -> list`
Filters user list for accounts with `servicePrincipalName` set (targets for Kerberoasting via `impacket-GetUserSPNs`).
### `find_asrep_roastable(users) -> list`
Filters for accounts with UAC flag `DONT_REQUIRE_PREAUTH` (0x400000) set.
### `enum_groups(dc_ip, domain, username, password) -> dict`
Queries LDAP for membership of Domain Admins, Enterprise Admins, Schema Admins, Backup Operators, Account Operators.
### `check_smb_signing(target_ip) -> bool`
Connects to SMB on port 445 and checks whether signing is required. Returns `False` when relay attacks are possible.
### `generate_report(users, groups, dc_ip) -> dict`
Aggregates findings into a JSON report with risk summary.
## Output Schema
```json
{
"assessment_date": "ISO-8601",
"total_users": 500,
"kerberoastable_accounts": ["svc-sql", "svc-web"],
"asrep_roastable_accounts": ["old-account"],
"high_value_groups": {"Domain Admins": 5},
"dc_smb_signing_required": true,
"risk_summary": ["CRITICAL: 2 accounts are Kerberoastable"]
}
```
## Key Impacket Modules
- `impacket.krb5.kerberosv5`: TGT/TGS request functions
- `impacket.smbconnection.SMBConnection`: SMB negotiation and signing check
- `impacket.dcerpc.v5.samr`: SAM Remote Protocol for user/group enumeration
- `ldap3.Connection.search()`: LDAP search with filter and attribute list
@@ -0,0 +1,167 @@
#!/usr/bin/env python3
# For authorized testing in lab/CTF environments only
"""Active Directory attack simulation agent using Impacket and ldap3."""
import argparse
import sys
import json
import logging
from datetime import datetime
try:
from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
from impacket.krb5 import constants as krb5_constants
from impacket.krb5.types import Principal, KerberosTime
from impacket.smbconnection import SMBConnection
from impacket import version as impacket_version
from impacket.dcerpc.v5 import samr, transport
from impacket.examples.GetUserSPNs import GetUserSPNs
from impacket.examples.GetNPUsers import GetNPUsers
except ImportError:
sys.exit("impacket is required: pip install impacket")
try:
import ldap3
from ldap3 import Server, Connection, ALL, SUBTREE
except ImportError:
sys.exit("ldap3 is required: pip install ldap3")
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
def ldap_enum_users(dc_ip: str, domain: str, username: str, password: str) -> list:
"""Enumerate domain users via LDAP, returning accounts with SPNs and no preauth."""
base_dn = ",".join(f"DC={part}" for part in domain.split("."))
server = Server(dc_ip, get_info=ALL, use_ssl=False)
conn = Connection(server, user=f"{domain}\\{username}", password=password, auto_bind=True)
conn.search(
base_dn,
"(objectClass=user)",
search_scope=SUBTREE,
attributes=[
"sAMAccountName", "servicePrincipalName", "userAccountControl",
"memberOf", "adminCount", "pwdLastSet", "lastLogon",
],
)
users = []
for entry in conn.entries:
uac = int(str(entry.userAccountControl)) if entry.userAccountControl else 0
spn_list = list(entry.servicePrincipalName) if entry.servicePrincipalName else []
no_preauth = bool(uac & 0x400000)
users.append({
"samaccountname": str(entry.sAMAccountName),
"spns": spn_list,
"no_preauth": no_preauth,
"admin_count": str(entry.adminCount) if entry.adminCount else "0",
})
conn.unbind()
logger.info("Enumerated %d domain users via LDAP", len(users))
return users
def find_kerberoastable(users: list) -> list:
"""Filter users with service principal names set (Kerberoastable)."""
targets = [u for u in users if u["spns"]]
logger.info("Found %d Kerberoastable accounts", len(targets))
return targets
def find_asrep_roastable(users: list) -> list:
"""Filter users with Kerberos pre-authentication disabled."""
targets = [u for u in users if u["no_preauth"]]
logger.info("Found %d AS-REP roastable accounts", len(targets))
return targets
def enum_groups(dc_ip: str, domain: str, username: str, password: str) -> dict:
"""Enumerate high-value group memberships via LDAP."""
base_dn = ",".join(f"DC={part}" for part in domain.split("."))
server = Server(dc_ip, get_info=ALL)
conn = Connection(server, user=f"{domain}\\{username}", password=password, auto_bind=True)
high_value_groups = [
"Domain Admins", "Enterprise Admins", "Schema Admins",
"Backup Operators", "Account Operators",
]
results = {}
for group_name in high_value_groups:
conn.search(
base_dn,
f"(&(objectClass=group)(cn={group_name}))",
attributes=["member"],
)
members = []
if conn.entries:
members = list(conn.entries[0].member) if conn.entries[0].member else []
results[group_name] = members
logger.info("Group '%s' has %d members", group_name, len(members))
conn.unbind()
return results
def check_smb_signing(target_ip: str) -> bool:
"""Check if SMB signing is required on the target host."""
try:
smb = SMBConnection(target_ip, target_ip, sess_port=445, timeout=5)
smb.negotiateSession()
signing = smb.isSigningRequired()
smb.close()
return signing
except Exception as exc:
logger.warning("SMB connect failed on %s: %s", target_ip, exc)
return True
def generate_report(users: list, groups: dict, dc_ip: str) -> dict:
"""Compile AD assessment findings into a structured report."""
kerberoastable = find_kerberoastable(users)
asrep = find_asrep_roastable(users)
smb_signing = check_smb_signing(dc_ip)
report = {
"assessment_date": datetime.utcnow().isoformat(),
"total_users": len(users),
"kerberoastable_accounts": [u["samaccountname"] for u in kerberoastable],
"asrep_roastable_accounts": [u["samaccountname"] for u in asrep],
"high_value_groups": {g: len(m) for g, m in groups.items()},
"dc_smb_signing_required": smb_signing,
"risk_summary": [],
}
if kerberoastable:
report["risk_summary"].append(
f"CRITICAL: {len(kerberoastable)} accounts are Kerberoastable"
)
if asrep:
report["risk_summary"].append(
f"HIGH: {len(asrep)} accounts lack Kerberos pre-authentication"
)
if not smb_signing:
report["risk_summary"].append("HIGH: SMB signing not required on DC - relay attacks possible")
return report
def main():
parser = argparse.ArgumentParser(description="AD Attack Simulation Agent")
parser.add_argument("--dc-ip", required=True, help="Domain Controller IP")
parser.add_argument("--domain", required=True, help="Domain FQDN (e.g., corp.local)")
parser.add_argument("--username", required=True, help="Low-privilege domain username")
parser.add_argument("--password", required=True, help="Domain user password")
parser.add_argument("--output", default="ad_assessment.json", help="Output JSON report path")
args = parser.parse_args()
logger.info("Starting AD attack simulation against %s", args.domain)
users = ldap_enum_users(args.dc_ip, args.domain, args.username, args.password)
groups = enum_groups(args.dc_ip, args.domain, args.username, args.password)
report = generate_report(users, groups, args.dc_ip)
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
logger.info("Report saved to %s", args.output)
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()