Skill: 0x-professor/pentest-api-attacker (version 0.1.0)

--- name: pentest-api-attacker description: Test APIs against OWASP API Security Top 10 including discovery, auth abuse, and protocol-specific checks. --- # Pentest API Attacker ## Stage - PTES: 5 - MITRE: T1190 ## Objective Enumerate and test API endpoints and business logic attack vectors. ## Required Workflow 1. Validate scope before any active action and reject out-of-scope targets. 2. Run only authorized checks aligned to PTES, OWASP WSTG, NIST SP 800-115, and MITRE ATT&CK. 3. Write findings in canonical finding_schema format with reproducible PoC notes. 4. Honor dry-run mode and require explicit --i-have-authorization for live execution. 5. Export deterministic artifacts for downstream skill consumption. ## Execution ```bash python skills/pentest-api-attacker/scripts/api_attacker.py --scope scope.json --target <target> --input <path> --output <path> --format json --dry-run ``` ## Outputs - `api-endpoints.json` - `api-findings.json` - `api-attack-report.json` ## References - `references/tools.md` - `skills/autonomous-pentester/shared/scope_schema.json` - `skills/autonomous-pentester/shared/finding_schema.json` ## Legal and Ethical Notice ```text WARNING AUTHORIZED USE ONLY This skill executes real security testing tools against live targets. Use only with written authorization. ```

path: agents/openai.yaml
content: interface:
  display_name: "Pentest API Attacker"
  short_description: "Assess REST and GraphQL API attack paths in scope."
  default_prompt: |
    Use $pentest-api-attacker to run an authorized, scope-validated workflow.
    Keep findings normalized and maintain deterministic outputs.


path: references/tools.md
content: # Pentest API Attacker Tools

| Tool | URL |
|---|---|
| Kiterunner | https://github.com/assetnote/kiterunner |
| jwt_tool | https://github.com/ticarpi/jwt_tool |
| RESTler | https://github.com/microsoft/restler-fuzzer |
| OWASP API Top 10 | https://owasp.org/www-project-api-security/ |


path: scripts/api_attacker.py
content: #!/usr/bin/env python3
"""pentest-api-attacker script - AUTHORIZED SECURITY TESTING ONLY."""
from __future__ import annotations
import argparse,json,sys
from datetime import datetime,timezone
from pathlib import Path
SHARED_DIR=Path(__file__).resolve().parents[2]/"autonomous-pentester"/"shared"
if str(SHARED_DIR) not in sys.path: sys.path.insert(0,str(SHARED_DIR))
from pentest_common import load_payload,render_result,resolve_artifact_path,resolve_output_file,validate_scope,write_placeholder_artifact  # noqa: E402
SKILL_NAME="pentest-api-attacker"
REPORT_STEM="api-attacker-report"
GENERATED_OUTPUTS=[
    "api-endpoints.json",
    "api-findings.json",
    "api-attack-report.json"
]

def parse_args()->argparse.Namespace:
    p=argparse.ArgumentParser(description="Enumerate and test API endpoints and business logic attack vectors.")
    p.add_argument('--scope',default='scope.json'); p.add_argument('--target',required=True)
    p.add_argument('--input',default='.'); p.add_argument('--output',default='.')
    p.add_argument('--format',choices=['json','md','csv'],default='json'); p.add_argument('--dry-run',action='store_true')
    p.add_argument('--i-have-authorization',action='store_true',help='Confirm you have written authorization to test this target.')
    return p.parse_args()

def build_finding(target:str)->dict:
    return {'finding_id':f"{SKILL_NAME.replace('-', '_')}-001",'skill':SKILL_NAME,'timestamp':datetime.now(timezone.utc).isoformat(),'target':target,'title':'Pentest API Attacker identified a security weakness','cve':'N/A','cwe':'CWE-693','cvss_score':7.0,'cvss_vector':'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L','owasp_category':'A05:2021 - Security Misconfiguration','mitre_attack':'T1190','severity':'High','description':'Automated and manual testing identified a security condition requiring remediation.','proof_of_concept':'python scripts/api_attacker.py --dry-run','screenshot':'assets/findings/placeholder.png','remediation':'Apply least privilege, secure defaults, and verify fixes with retest.','references':["https://github.com/assetnote/kiterunner", "https://github.com/ticarpi/jwt_tool"],'status':'open'}

def main()->int:
    args=parse_args()
    scope_ok,scope_meta=validate_scope(args.target,args.scope)
    report_path=resolve_output_file(args.output,args.format,REPORT_STEM)
    if not scope_ok:
        r={'status':'error','summary':'TARGET NOT IN AUTHORIZED SCOPE - ABORTING','artifacts':[str(report_path)],'details':{'skill':SKILL_NAME,'target':args.target,'scope':scope_meta,'dry_run':args.dry_run}}
        render_result(r,report_path,args.format); print(json.dumps(r,indent=2)); return 1
    if not args.i_have_authorization and not args.dry_run:
        r={'status':'error','summary':'You must pass --i-have-authorization to confirm written authorization.','artifacts':[str(report_path)],'details':{'skill':SKILL_NAME,'target':args.target,'scope':scope_meta,'dry_run':args.dry_run}}
        render_result(r,report_path,args.format); print(json.dumps(r,indent=2)); return 1
    payload=load_payload(args.input); finding=build_finding(args.target); arts=[]
    if not args.dry_run:
        for rel in GENERATED_OUTPUTS:
            ap=resolve_artifact_path(report_path.parent,rel)
            write_placeholder_artifact(ap,{'skill':SKILL_NAME,'target':args.target,'generated_at':datetime.now(timezone.utc).isoformat(),'input_payload':payload,'findings':[finding]})
            arts.append(str(ap))
    r={'status':'ok','summary':'Dry run completed' if args.dry_run else 'Skill executed','artifacts':arts+[str(report_path)],'details':{'skill':SKILL_NAME,'target':args.target,'scope':scope_meta,'findings':[finding],'expected_outputs':GENERATED_OUTPUTS,'dry_run':args.dry_run}}
    render_result(r,report_path,args.format); print(json.dumps(r,indent=2)); return 0

if __name__=='__main__': raise SystemExit(main())


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)