mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-16 16:03:17 +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,58 @@
|
||||
# API Reference: Implementing Google Workspace Admin Security
|
||||
|
||||
## Libraries
|
||||
|
||||
### google-api-python-client + google-auth
|
||||
- **Install**: `pip install google-api-python-client google-auth`
|
||||
- **Docs**: https://developers.google.com/admin-sdk/directory/reference/rest
|
||||
|
||||
## Admin SDK Directory API
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `users().list(domain, projection="full")` | List users with full profile |
|
||||
| `users().get(userKey)` | Get specific user details |
|
||||
| `users().update(userKey, body)` | Update user settings |
|
||||
| `users().list(query="isAdmin=true")` | List admin users |
|
||||
| `orgunits().list(customerId)` | List organizational units |
|
||||
| `roles().list(customer)` | List admin roles |
|
||||
| `roleAssignments().list(customer)` | List role assignments |
|
||||
|
||||
## Reports API (Audit Logs)
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `activities().list(userKey, applicationName)` | Get audit events |
|
||||
| Application names: `login`, `admin`, `drive`, `token`, `mobile` |
|
||||
|
||||
## Key User Fields for Security
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `isEnrolledIn2Sv` | User enrolled in 2-Step Verification |
|
||||
| `isEnforcedIn2Sv` | 2SV enforcement applied |
|
||||
| `isAdmin` | Super admin status |
|
||||
| `isDelegatedAdmin` | Delegated admin status |
|
||||
| `lastLoginTime` | Last login timestamp |
|
||||
| `recoveryEmail` | Recovery email (risk if external) |
|
||||
| `recoveryPhone` | Recovery phone number |
|
||||
| `isSuspended` | Account suspended |
|
||||
|
||||
## OAuth Scopes Required
|
||||
- `admin.directory.user` -- User management
|
||||
- `admin.directory.domain` -- Domain settings
|
||||
- `admin.reports.audit.readonly` -- Audit log access
|
||||
- `admin.directory.orgunit` -- Org unit management
|
||||
|
||||
## Login Event Names
|
||||
- `login_success` -- Successful login
|
||||
- `login_failure` -- Failed login attempt
|
||||
- `login_challenge` -- 2FA challenge issued
|
||||
- `suspicious_login` -- Flagged by Google
|
||||
- `account_disabled_password_leak` -- Compromised password
|
||||
|
||||
## External References
|
||||
- Admin SDK: https://developers.google.com/admin-sdk
|
||||
- Workspace Security Best Practices: https://support.google.com/a/answer/7587183
|
||||
- CIS Google Workspace Benchmark: https://www.cisecurity.org/benchmark/google_workspace
|
||||
- Reports API: https://developers.google.com/admin-sdk/reports/reference/rest
|
||||
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Google Workspace admin security hardening agent using Admin SDK."""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from google.oauth2 import service_account
|
||||
from googleapiclient.discovery import build
|
||||
from googleapiclient.errors import HttpError
|
||||
except ImportError:
|
||||
print("Install: pip install google-api-python-client google-auth")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
SCOPES = [
|
||||
"https://www.googleapis.com/auth/admin.directory.user",
|
||||
"https://www.googleapis.com/auth/admin.directory.domain",
|
||||
"https://www.googleapis.com/auth/admin.reports.audit.readonly",
|
||||
"https://www.googleapis.com/auth/admin.directory.orgunit",
|
||||
]
|
||||
|
||||
|
||||
def get_admin_service(credentials_file, admin_email, api="admin", version="directory_v1"):
|
||||
"""Build Google Admin SDK service with domain-wide delegation."""
|
||||
creds = service_account.Credentials.from_service_account_file(
|
||||
credentials_file, scopes=SCOPES, subject=admin_email)
|
||||
return build(api, version, credentials=creds)
|
||||
|
||||
|
||||
def get_reports_service(credentials_file, admin_email):
|
||||
"""Build Reports API service."""
|
||||
creds = service_account.Credentials.from_service_account_file(
|
||||
credentials_file, scopes=SCOPES, subject=admin_email)
|
||||
return build("admin", "reports_v1", credentials=creds)
|
||||
|
||||
|
||||
def list_users_without_2fa(service, domain):
|
||||
"""List users who have not enrolled in 2-Step Verification."""
|
||||
users_without_2fa = []
|
||||
request = service.users().list(domain=domain, maxResults=500,
|
||||
projection="full", orderBy="email")
|
||||
while request:
|
||||
response = request.execute()
|
||||
for user in response.get("users", []):
|
||||
is_enrolled = user.get("isEnrolledIn2Sv", False)
|
||||
is_enforced = user.get("isEnforcedIn2Sv", False)
|
||||
if not is_enrolled:
|
||||
users_without_2fa.append({
|
||||
"email": user["primaryEmail"],
|
||||
"name": user.get("name", {}).get("fullName", ""),
|
||||
"is_admin": user.get("isAdmin", False),
|
||||
"is_2sv_enrolled": is_enrolled,
|
||||
"is_2sv_enforced": is_enforced,
|
||||
"last_login": user.get("lastLoginTime", "never"),
|
||||
})
|
||||
request = service.users().list_next(request, response)
|
||||
return users_without_2fa
|
||||
|
||||
|
||||
def list_admin_users(service, domain):
|
||||
"""List all admin users and their admin roles."""
|
||||
admins = []
|
||||
request = service.users().list(domain=domain, maxResults=500,
|
||||
projection="full", query="isAdmin=true")
|
||||
response = request.execute()
|
||||
for user in response.get("users", []):
|
||||
admins.append({
|
||||
"email": user["primaryEmail"],
|
||||
"name": user.get("name", {}).get("fullName", ""),
|
||||
"is_super_admin": user.get("isAdmin", False),
|
||||
"is_delegated_admin": user.get("isDelegatedAdmin", False),
|
||||
"is_2sv_enrolled": user.get("isEnrolledIn2Sv", False),
|
||||
"last_login": user.get("lastLoginTime", "never"),
|
||||
"creation_time": user.get("creationTime", ""),
|
||||
})
|
||||
return admins
|
||||
|
||||
|
||||
def get_login_audit_events(reports_service, user_email=None, days=7):
|
||||
"""Get login audit events to detect suspicious activity."""
|
||||
events = []
|
||||
try:
|
||||
params = {"userKey": "all", "applicationName": "login", "maxResults": 200}
|
||||
if user_email:
|
||||
params["userKey"] = user_email
|
||||
request = reports_service.activities().list(**params)
|
||||
response = request.execute()
|
||||
for activity in response.get("items", []):
|
||||
for event in activity.get("events", []):
|
||||
event_data = {
|
||||
"user": activity.get("actor", {}).get("email", ""),
|
||||
"event_name": event.get("name", ""),
|
||||
"time": activity.get("id", {}).get("time", ""),
|
||||
"ip_address": activity.get("ipAddress", ""),
|
||||
}
|
||||
for param in event.get("parameters", []):
|
||||
event_data[param["name"]] = param.get("value", param.get("boolValue", ""))
|
||||
events.append(event_data)
|
||||
except HttpError as e:
|
||||
events.append({"error": str(e)})
|
||||
return events
|
||||
|
||||
|
||||
def check_suspended_users(service, domain):
|
||||
"""List suspended users that may still have active sessions."""
|
||||
suspended = []
|
||||
request = service.users().list(domain=domain, maxResults=500,
|
||||
query="isSuspended=true")
|
||||
response = request.execute()
|
||||
for user in response.get("users", []):
|
||||
suspended.append({
|
||||
"email": user["primaryEmail"],
|
||||
"suspension_reason": user.get("suspensionReason", "manual"),
|
||||
"last_login": user.get("lastLoginTime", "never"),
|
||||
})
|
||||
return suspended
|
||||
|
||||
|
||||
def check_recovery_settings(service, domain):
|
||||
"""Audit users with recovery email/phone that could be used for account takeover."""
|
||||
findings = []
|
||||
request = service.users().list(domain=domain, maxResults=500, projection="full")
|
||||
response = request.execute()
|
||||
for user in response.get("users", []):
|
||||
recovery_email = user.get("recoveryEmail", "")
|
||||
recovery_phone = user.get("recoveryPhone", "")
|
||||
if user.get("isAdmin") and (recovery_email or recovery_phone):
|
||||
if recovery_email and not recovery_email.endswith(f"@{domain}"):
|
||||
findings.append({
|
||||
"email": user["primaryEmail"],
|
||||
"issue": "Admin has external recovery email",
|
||||
"recovery_email": recovery_email,
|
||||
"severity": "HIGH",
|
||||
})
|
||||
return findings
|
||||
|
||||
|
||||
def run_workspace_audit(service, reports_service, domain):
|
||||
"""Run comprehensive Google Workspace security audit."""
|
||||
print(f"\n{'='*60}")
|
||||
print(f" GOOGLE WORKSPACE SECURITY AUDIT")
|
||||
print(f" Domain: {domain}")
|
||||
print(f" Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
admins = list_admin_users(service, domain)
|
||||
print(f"--- ADMIN ACCOUNTS ({len(admins)}) ---")
|
||||
for a in admins:
|
||||
mfa_status = "2FA ON" if a["is_2sv_enrolled"] else "2FA OFF"
|
||||
print(f" [{mfa_status}] {a['email']} (Super: {a['is_super_admin']})")
|
||||
|
||||
no_2fa = list_users_without_2fa(service, domain)
|
||||
print(f"\n--- USERS WITHOUT 2FA ({len(no_2fa)}) ---")
|
||||
admin_no_2fa = [u for u in no_2fa if u["is_admin"]]
|
||||
if admin_no_2fa:
|
||||
print(f" CRITICAL: {len(admin_no_2fa)} admin(s) without 2FA!")
|
||||
for u in admin_no_2fa:
|
||||
print(f" {u['email']}")
|
||||
print(f" Total users without 2FA: {len(no_2fa)}")
|
||||
|
||||
recovery = check_recovery_settings(service, domain)
|
||||
print(f"\n--- RECOVERY SETTINGS ISSUES ({len(recovery)}) ---")
|
||||
for r in recovery:
|
||||
print(f" [{r['severity']}] {r['email']}: {r['issue']}")
|
||||
|
||||
suspended = check_suspended_users(service, domain)
|
||||
print(f"\n--- SUSPENDED USERS ({len(suspended)}) ---")
|
||||
for s in suspended[:5]:
|
||||
print(f" {s['email']} (Reason: {s['suspension_reason']})")
|
||||
|
||||
events = get_login_audit_events(reports_service)
|
||||
suspicious = [e for e in events if e.get("event_name") == "login_failure"]
|
||||
print(f"\n--- RECENT LOGIN EVENTS ---")
|
||||
print(f" Total events: {len(events)}")
|
||||
print(f" Failed logins: {len(suspicious)}")
|
||||
|
||||
print(f"\n{'='*60}\n")
|
||||
return {"admins": len(admins), "no_2fa": len(no_2fa),
|
||||
"admin_no_2fa": len(admin_no_2fa), "suspended": len(suspended)}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Google Workspace Admin Security Agent")
|
||||
parser.add_argument("--credentials", required=True, help="Service account JSON key file")
|
||||
parser.add_argument("--admin-email", required=True, help="Admin email for delegation")
|
||||
parser.add_argument("--domain", required=True, help="Google Workspace domain")
|
||||
parser.add_argument("--audit", action="store_true", help="Run full security audit")
|
||||
parser.add_argument("--output", help="Save report to JSON")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.audit:
|
||||
service = get_admin_service(args.credentials, args.admin_email)
|
||||
reports = get_reports_service(args.credentials, args.admin_email)
|
||||
report = run_workspace_audit(service, reports, args.domain)
|
||||
if args.output:
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user