attacklm 0.5.0__tar.gz → 0.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {attacklm-0.5.0 → attacklm-0.5.2}/ATTRIBUTION.md +25 -26
- {attacklm-0.5.0 → attacklm-0.5.2}/CHANGELOG.md +69 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/PKG-INFO +126 -88
- {attacklm-0.5.0 → attacklm-0.5.2}/QA_BEFORE_RELEASES.md +1 -1
- {attacklm-0.5.0 → attacklm-0.5.2}/README.md +124 -86
- {attacklm-0.5.0 → attacklm-0.5.2}/hf/README.md +56 -56
- {attacklm-0.5.0 → attacklm-0.5.2}/hf/dataset_infos.json +1 -1
- {attacklm-0.5.0 → attacklm-0.5.2}/pyproject.toml +1 -1
- attacklm-0.5.2/src/attacklm/__version__.py +1 -0
- attacklm-0.5.0/src/attacklm/__version__.py +0 -1
- {attacklm-0.5.0 → attacklm-0.5.2}/.github/workflows/release.yml +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/.gitignore +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/CONTRIBUTING.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/EVALUATION.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/LICENSE +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/MANIFEST.in +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/Makefile +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/NOTICE +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/REPLAY_PLAN.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/ATTRIBUTION.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/LEGAL.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/REMOVAL.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/bench/questions.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/bench/speed_context.txt +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/ATTRIBUTION.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/GEMINI_RESEARCH_2026-06-11.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/acquisition_report.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/manifest.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/README.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/_index.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/collection/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/discovery/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/execution/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/exfiltration/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/persistence/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/attacklm-synthetic/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/attacklm-synthetic/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/attacklm-synthetic/orchestrator/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/azure-pyrit/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/azure-pyrit/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/cyberark-fuzzyai/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/cyberark-fuzzyai/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/elastic-rules/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/elastic-rules/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/cloud/attacks/data_llm.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/ics/attacks/data_llm.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/social_engineering/phishing/data_llm.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/wireless/attacks/data_llm.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/collection/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/credential_access/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/defense_evasion/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/discovery/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/execution/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/lateral_movement/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/persistence/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/privilege_escalation/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/tools/metasploit/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-atlas-arsenal/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-atlas-arsenal/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-atlas-arsenal/base/discovery/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/collection/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/discovery/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/execution/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/exfiltration/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/persistence/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mordor/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mordor/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nist-ir/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nist-ir/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nvidia-garak/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nvidia-garak/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nvidia-garak/ai/jailbreaking/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptfoo/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptfoo/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptfoo/ai/prompt-injection/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptmap/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptmap/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptmap/ai/prompt-injection/data.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_code.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_conversation.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_factual.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_reasoning.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/sigma-hq/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/sigma-hq/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/splunk-content/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/splunk-content/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/threathunter-playbook/LICENSE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/threathunter-playbook/SOURCE.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/golden/prompts.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/reference/prompts.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/opsec_aware.txt +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/opsec_unaware.txt +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/succinct.txt +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/verbose.txt +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/experiments/README.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/experiments/synthetic_dataset_mutator_evol_instruct.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hf/.gitattributes +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hf/data/manifest.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hf/scripts/build_hf_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hf/scripts/push_to_hf.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hpo_runs/.gitkeep +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hpo_runs/hpo_state.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/hpo_runs/hpo_trial_dataset.jsonl +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/logs/.gitkeep +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/notes/BLUE_TEAM_DESIGN_v0.5.0.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/notes/EVAL_DESIGN_v0.4.0.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/notes/STEERING_REVIEW_v0.4.0.md +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/presets/blue-team.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/presets/purple-team.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/presets/red-team.json +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/requirements.txt +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/_eval_loader.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_cloud_attack_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_ics_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_phishing_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_red_team_tactics.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_replay_general.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_supply_chain_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_web_attack_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_wireless_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/add_attribution.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/audit_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/augment_attribution.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/balance_buckets.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/bucket_loader.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/build.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/classify_unrouted_modules.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/clone_repos.sh +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/collect_reference.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/compare_scores.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/convert_to_gguf.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/dedupe_and_import_llm.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/demo.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/device_utils.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/domain_bench.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/eval_retention.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_ai_tools_to_jsonl.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_atomic_red_team_to_jsonl.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_by_tactic.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_caldera_plugins_to_jsonl.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_elastic_rules.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_infection_monkey_to_jsonl.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_mordor.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_nist_ir.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_rta_to_jsonl.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_sigma_defensive.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_splunk_content.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_threathunter_playbook.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_dataset_deterministic.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_hybrid_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_metasploit_dataset.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_orchestrator.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_prompt_injection.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_source_layout.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_synthetic_scarce.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/golden_vectors.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/hpo_runner.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/import_gguf.sh +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/import_to_lmstudio.sh +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/infer.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/init_pipeline.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/llm_generate_wrapper.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/merge_adapter.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/migrate_buckets_to_v021.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/migrate_v015_to_v020.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/mitre_tactic_lookup.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/parse_metasploit_to_jsonl.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/rebuild_manifest.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/register_ollama.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/reorganize_buckets.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/replay_mixer.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/run_all_acquisitions.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/score_candidates.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/scrub_bpl_callback.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/setup_buckets.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/speed_bench.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/stamp_and_reorg.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/steering.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/train_all.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/train_template.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/scripts/validate_per_category.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/src/attacklm/__init__.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/src/attacklm/cli.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_balance_buckets.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_collect_reference.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_compare_scores.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_domain_bench.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_eval_loader.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_eval_retention.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_golden_vectors.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_init_pipeline.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_replay_mixer.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_score_candidates.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_speed_bench.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_steering.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_thinking_models.py +0 -0
- {attacklm-0.5.0 → attacklm-0.5.2}/uv.lock +0 -0
|
@@ -16,11 +16,12 @@ artifact* learned from these sources; they are not a verbatim copy.
|
|
|
16
16
|
attribution in this file** per each source's license.
|
|
17
17
|
- If you modify the training data, **document what you changed**.
|
|
18
18
|
- If you re-distribute the trained model commercially, **review the
|
|
19
|
-
|
|
19
|
+
DRL-1.1 and BSD-3-Clause requirements below** — they have attribution
|
|
20
|
+
obligations.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
23
|
-
## Training Data Sources (
|
|
24
|
+
## Training Data Sources (21,865 pairs across 23 buckets)
|
|
24
25
|
|
|
25
26
|
### 1. Atomic Red Team (redcanaryco)
|
|
26
27
|
|
|
@@ -239,26 +240,27 @@ AGPLv3 terms.
|
|
|
239
240
|
|
|
240
241
|
The full per-bucket manifest is at `data/datasets/buckets/manifest.json`.
|
|
241
242
|
It records which pairs come from which upstream source (via the
|
|
242
|
-
`source_file` field). Total: **
|
|
243
|
+
`source_file` field). Total: **21,865 pairs across 23 buckets**.
|
|
243
244
|
|
|
244
245
|
| Bucket | Pairs | Upstream sources |
|
|
245
|
-
|
|
246
|
-
| collection | 634 | atomic,
|
|
247
|
-
| command_and_control | 105 | atomic,
|
|
248
|
-
| credential_access | 589 |
|
|
249
|
-
| defense_evasion | 1,375 |
|
|
250
|
-
| discovery | 1,846 | atomic,
|
|
251
|
-
| execution | 767 | atomic,
|
|
252
|
-
| exfiltration |
|
|
253
|
-
| lateral_movement | 252 |
|
|
254
|
-
| persistence | 1,120 | atomic,
|
|
255
|
-
| privilege_escalation | 537 |
|
|
246
|
+
|---|---|---:|
|
|
247
|
+
| collection | 634 | atomic, metasploit, stockpile |
|
|
248
|
+
| command_and_control | 105 | atomic, metasploit, stockpile |
|
|
249
|
+
| credential_access | 589 | metasploit |
|
|
250
|
+
| defense_evasion | 1,375 | metasploit |
|
|
251
|
+
| discovery | 1,846 | atomic, metasploit, stockpile, atlas-arsenal |
|
|
252
|
+
| execution | 767 | atomic, metasploit, stockpile |
|
|
253
|
+
| exfiltration | 53 | atomic, stockpile |
|
|
254
|
+
| lateral_movement | 252 | metasploit |
|
|
255
|
+
| persistence | 1,120 | atomic, metasploit, stockpile |
|
|
256
|
+
| privilege_escalation | 537 | metasploit |
|
|
256
257
|
| orchestrator | 380 | synthetic |
|
|
257
|
-
| ai/jailbreaking |
|
|
258
|
+
| ai/jailbreaking | 50 | garak |
|
|
258
259
|
| ai/prompt-injection | 687 | promptfoo, promptmap, synthetic |
|
|
259
|
-
| tools/infection_monkey | 36 | guardicore/monkey |
|
|
260
260
|
| tools/metasploit | 8,349 | rapid7/metasploit-framework |
|
|
261
|
-
|
|
|
261
|
+
| defensive/detection_engineering | 5,000 | sigma-hq, elastic-rules, splunk-content |
|
|
262
|
+
| defensive/threat_hunting | 650 | mordor, threathunter-playbook |
|
|
263
|
+
| defensive/incident_response | 200 | nist-ir |
|
|
262
264
|
|
|
263
265
|
---
|
|
264
266
|
|
|
@@ -268,16 +270,13 @@ If you fork AttackLM and re-distribute:
|
|
|
268
270
|
|
|
269
271
|
1. **Keep this `ATTRIBUTION.md` file intact** in any derivative repo.
|
|
270
272
|
2. **Keep all upstream LICENSE files** in `data/<source>/LICENSE*`.
|
|
271
|
-
3. **Do not remove any source's attribution** when removing its data
|
|
272
|
-
|
|
273
|
-
4. **For Apache 2.0 sources (Caldera, MITRE ATT&CK, garak, FuzzyAI):**
|
|
273
|
+
3. **Do not remove any source's attribution** when removing its data.
|
|
274
|
+
4. **For Apache 2.0 sources (Caldera, garak, Mordor, ThreatHunter-Playbook, Splunk):**
|
|
274
275
|
include a `NOTICE` file in your distribution (template below).
|
|
275
|
-
5. **For
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
of upstream code; the GPL may apply to the JSONL files but not
|
|
280
|
-
to model weights learned from them.
|
|
276
|
+
5. **For BSD-3-Clause (Metasploit):** preserve the copyright notice and
|
|
277
|
+
license text in derivative works per BSD §1.
|
|
278
|
+
6. **For DRL-1.1 (Sigma):** preserve attribution to Sigma rule authors
|
|
279
|
+
per the Detection Rule License.
|
|
281
280
|
|
|
282
281
|
### NOTICE template (required by Apache 2.0)
|
|
283
282
|
|
|
@@ -4,6 +4,75 @@ All notable changes to AttackLM are documented in this file. Versions follow [Se
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.5.0] — 2026-06-24 — Blue-team data sources, team presets, defensive extractors
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **6 new blue-team/defensive data sources** (~5,850 pairs):
|
|
12
|
+
- SigmaHQ/sigma: 3,000 detection rules (DRL-1.1)
|
|
13
|
+
- Elastic/detection-rules: 1,200 EQL/KQL rules (Elastic-2.0)
|
|
14
|
+
- Splunk/security_content: 800 SPL detections (Apache-2.0)
|
|
15
|
+
- OTRF/Security-Datasets (Mordor): 500 event log scenarios (Apache-2.0)
|
|
16
|
+
- OTRF/ThreatHunter-Playbook: 150 hunting playbooks (Apache-2.0)
|
|
17
|
+
- NIST SP 800-61r3: 200 IR procedure pairs (Public Domain, template-based)
|
|
18
|
+
- **6 new extractor scripts**: `extract_sigma_defensive.py`, `extract_elastic_rules.py`,
|
|
19
|
+
`extract_splunk_content.py`, `extract_mordor.py`, `extract_threathunter_playbook.py`,
|
|
20
|
+
`extract_nist_ir.py`
|
|
21
|
+
- **3 team presets** (`presets/red-team.json`, `purple-team.json`, `blue-team.json`)
|
|
22
|
+
with pre-configured bucket weights for offensive/defensive mix control
|
|
23
|
+
- **`--preset` and `--system-prompt` flags** on `attacklm-balance`
|
|
24
|
+
- **3 new defensive buckets**: `defensive/detection_engineering` (5,000),
|
|
25
|
+
`defensive/threat_hunting` (650), `defensive/incident_response` (200)
|
|
26
|
+
- **12 attribution files** (SOURCE.md + LICENSE.md per new source)
|
|
27
|
+
- **`notes/BLUE_TEAM_DESIGN_v0.5.0.md`** — full architectural plan (792 lines)
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `scripts/init_pipeline.py` — 5 new local probes, 5 new remote repos, 6 new extractors
|
|
32
|
+
- `src/attacklm/cli.py` — 6 new extractors in extraction sequence
|
|
33
|
+
- `data/datasets/buckets/manifest.json` — 21,865 total pairs, 23 buckets, 17 sources
|
|
34
|
+
- `scripts/balance_buckets.py` — preset loading, weight resolution, `--preset` flag
|
|
35
|
+
- `src/attacklm/__version__.py` — bumped to `0.5.0`
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- `balance_buckets.py` `BASE_DIR` undefined in preset helpers
|
|
40
|
+
- `_caps_for_target_total` fallback for buckets not in any category share
|
|
41
|
+
- Manifest `total_pairs` math consistency (source_totals sum = tier_totals sum = total_pairs)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## [0.4.1] — 2026-06-22 — Evaluation framework, steering vectors, dataset cleanup
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- **7-pattern ds4 evaluation framework** (Patterns 1-7):
|
|
50
|
+
- Pattern 1: Reference-continuation NLL scoring (`collect_reference.py`, `score_candidates.py`, `compare_scores.py`)
|
|
51
|
+
- Pattern 2: Golden-vector regression gates (`golden_vectors.py`, 558 lines)
|
|
52
|
+
- Pattern 3: 100-question domain benchmark (`domain_bench.py`, 563 lines)
|
|
53
|
+
- Pattern 4: Speed profiling / context-frontier (`speed_bench.py`, 463 lines)
|
|
54
|
+
- Pattern 5: QA checklist (documentation)
|
|
55
|
+
- Pattern 6: Steering vectors (`steering.py`, 1,120 lines) — extract, apply, sweep, diagnose
|
|
56
|
+
- Pattern 7: Narrow-bet philosophy doc
|
|
57
|
+
- **Shared model loader** `_eval_loader.py` (149 lines) — extracted from `eval_retention.py`
|
|
58
|
+
- **4 new CLI entry points**: `attacklm-collect-ref`, `attacklm-score`, `attacklm-compare`, `attacklm-golden`
|
|
59
|
+
- **198 hermetic pytest tests** across 8 test files (all pass, 0.62s)
|
|
60
|
+
- **`notes/EVAL_DESIGN_v0.4.0.md`** (1,098 lines), **`notes/STEERING_REVIEW_v0.4.0.md`** (793 lines)
|
|
61
|
+
- **`EVALUATION.md`**, **`QA_BEFORE_RELEASES.md`** documentation
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- `scripts/eval_retention.py` refactored to import from `_eval_loader.py`
|
|
66
|
+
- `scripts/domain_bench.py` — integrated steering vector flags
|
|
67
|
+
- `pyproject.toml` — 4 new eval entry points, `eval` optional-dependency group
|
|
68
|
+
|
|
69
|
+
### Removed
|
|
70
|
+
|
|
71
|
+
- **8,649 template-generated synthetic records** deleted — dataset reduced from 25,601 → 16,015 pairs
|
|
72
|
+
(only 380 orchestrator records kept from synthetic sources)
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
7
76
|
## [0.4.0] — 2026-06-22 — MoE-safe training, retention eval, and experience replay
|
|
8
77
|
|
|
9
78
|
### Added
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: attacklm
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
Summary: QLoRA-fine-tuned Qwen2.5-Coder for offensive security and AI red-teaming
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: QLoRA-fine-tuned Qwen2.5-Coder for offensive/defensive security and AI red-teaming
|
|
5
5
|
Project-URL: Homepage, https://github.com/Veedubin/AttackLM
|
|
6
6
|
Project-URL: Repository, https://github.com/Veedubin/AttackLM
|
|
7
7
|
Project-URL: Issues, https://github.com/Veedubin/AttackLM/issues
|
|
@@ -207,10 +207,11 @@ Description-Content-Type: text/markdown
|
|
|
207
207
|
|
|
208
208
|
# AttackLM
|
|
209
209
|
|
|
210
|
-
> A QLoRA fine-tuning pipeline for a MITRE ATT&CK-grounded red-team AI assistant.
|
|
211
|
-
>
|
|
210
|
+
> A QLoRA fine-tuning pipeline for a MITRE ATT&CK-grounded red/blue-team AI assistant.
|
|
211
|
+
> 21,865 training pairs · 3B–70B Qwen base · 16GB–128GB VRAM.
|
|
212
212
|
|
|
213
213
|
[](LICENSE)
|
|
214
|
+
[](https://pypi.org/project/attacklm/)
|
|
214
215
|
[](ATTRIBUTION.md)
|
|
215
216
|
[](requirements.txt)
|
|
216
217
|
[](https://huggingface.co/unsloth/Qwen2.5-Coder-3B-Instruct-bnb-4bit)
|
|
@@ -220,14 +221,17 @@ Description-Content-Type: text/markdown
|
|
|
220
221
|
## What is this?
|
|
221
222
|
|
|
222
223
|
AttackLM is a complete pipeline for fine-tuning a small language model to be
|
|
223
|
-
a competent red-team / AI-security assistant. The training data is
|
|
224
|
-
**MITRE ATT&CK** techniques, sourced from openly licensed
|
|
225
|
-
(Atomic Red Team, MITRE Caldera, Metasploit, Sigma,
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
224
|
+
a competent red-team / blue-team / AI-security assistant. The training data is
|
|
225
|
+
grounded in **MITRE ATT&CK** techniques, sourced from openly licensed
|
|
226
|
+
open-source projects (Atomic Red Team, MITRE Caldera, Metasploit, Sigma,
|
|
227
|
+
Elastic, Splunk, Mordor, ThreatHunter-Playbook, NIST IR, plus prompt-injection
|
|
228
|
+
and jailbreak corpora for AI-security coverage).
|
|
229
|
+
|
|
230
|
+
The pipeline ingests 10 MITRE tactic buckets, 3 defensive buckets, 3 tool
|
|
231
|
+
buckets, 2 AI-security buckets, 1 orchestrator bucket, and 4 extended-category
|
|
232
|
+
buckets (23 total) and produces a QLoRA LoRA adapter you can drop on top of
|
|
233
|
+
`Qwen2.5-Coder-3B-Instruct`. Team presets (red/purple/blue) let you control
|
|
234
|
+
the offensive/defensive mix.
|
|
231
235
|
|
|
232
236
|
What makes it different:
|
|
233
237
|
- **No LLM in the data pipeline.** Every training pair is deterministically
|
|
@@ -251,73 +255,68 @@ its contribution to AttackLM's training mix is documented in
|
|
|
251
255
|
The full per-source map:
|
|
252
256
|
|
|
253
257
|
| Source | Pairs | License | Repository |
|
|
254
|
-
|
|
255
|
-
|
|
|
256
|
-
|
|
|
257
|
-
|
|
|
258
|
-
|
|
|
259
|
-
|
|
|
260
|
-
|
|
|
261
|
-
|
|
|
262
|
-
|
|
|
263
|
-
|
|
|
264
|
-
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
network-distribution implications for derivative works. The public
|
|
268
|
-
repository satisfies the source-availability requirement. If you need an
|
|
269
|
-
AGPL-clean deployment, retrain after removing the `tools/rta` bucket.
|
|
270
|
-
See [ATTRIBUTION.md §8](ATTRIBUTION.md) for the full analysis.
|
|
258
|
+
|---|---|---|---|
|
|
259
|
+
| Metasploit Framework | 13,997 | BSD-3-Clause | [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) |
|
|
260
|
+
| Sigma rules | 3,000 | DRL-1.1 | [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) |
|
|
261
|
+
| Elastic detection rules | 1,200 | Elastic-2.0 | [elastic/detection-rules](https://github.com/elastic/detection-rules) |
|
|
262
|
+
| Splunk security content | 800 | Apache-2.0 | [splunk/security_content](https://github.com/splunk/security_content) |
|
|
263
|
+
| Mordor (OTRF) | 500 | Apache-2.0 | [OTRF/Security-Datasets](https://github.com/OTRF/Security-Datasets) |
|
|
264
|
+
| Atomic Red Team | 1,115 | MIT | [redcanaryco/atomic-red-team](https://github.com/redcanaryco/atomic-red-team) |
|
|
265
|
+
| MITRE Caldera / Stockpile | 390 | Apache-2.0 | [mitre/stockpile](https://github.com/mitre/stockpile) |
|
|
266
|
+
| ThreatHunter-Playbook | 150 | Apache-2.0 | [OTRF/ThreatHunter-Playbook](https://github.com/OTRF/ThreatHunter-Playbook) |
|
|
267
|
+
| NIST SP 800-61r3 | 200 | Public Domain | NIST (template-based extractor) |
|
|
268
|
+
| AI-security tools (garak, promptfoo, promptmap) | 113 | mixed MIT/Apache-2.0 | various (see [ATTRIBUTION.md](ATTRIBUTION.md)) |
|
|
269
|
+
| Synthetic (orchestrator + extended categories) | 380 | MIT | this repo |
|
|
270
|
+
| **Total** | **21,865** | | |
|
|
271
271
|
|
|
272
272
|
---
|
|
273
273
|
|
|
274
|
-
## Quickstart
|
|
274
|
+
## Quickstart
|
|
275
|
+
|
|
276
|
+
### Option A: Install from PyPI (fastest — 30 seconds)
|
|
275
277
|
|
|
276
278
|
```bash
|
|
277
279
|
# 1. Install uv (Python package manager, ~10MB)
|
|
278
280
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
279
281
|
|
|
280
|
-
# 2.
|
|
282
|
+
# 2. Install AttackLM from PyPI with the full CUDA training stack
|
|
283
|
+
uv pip install "attacklm[all]"
|
|
284
|
+
|
|
285
|
+
# 3. Clone the repo for the training data (the PyPI package is code-only)
|
|
281
286
|
git clone https://github.com/Veedubin/AttackLM.git
|
|
282
287
|
cd AttackLM
|
|
283
288
|
|
|
284
|
-
#
|
|
285
|
-
|
|
286
|
-
uv pip install -e ".[all]"
|
|
289
|
+
# 4. Initialize the dataset (probes local `data/` first; falls back to git clone)
|
|
290
|
+
attacklm-init --yes
|
|
287
291
|
|
|
288
|
-
#
|
|
289
|
-
|
|
292
|
+
# 5. Train
|
|
293
|
+
attacklm-train-all --single-model \
|
|
294
|
+
--dataset base/ \
|
|
295
|
+
--base-model huihui-ai/Qwen2.5-Coder-3B-Instruct-abliterated \
|
|
296
|
+
--epochs 5 --max-length 2048
|
|
297
|
+
```
|
|
290
298
|
|
|
291
|
-
|
|
292
|
-
# uv sync
|
|
299
|
+
### Option B: Install from source (if you want to modify the code)
|
|
293
300
|
|
|
294
|
-
|
|
301
|
+
```bash
|
|
302
|
+
# 1. Install uv
|
|
303
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
304
|
+
|
|
305
|
+
# 2. Clone this repo
|
|
306
|
+
git clone https://github.com/Veedubin/AttackLM.git
|
|
307
|
+
cd AttackLM
|
|
308
|
+
|
|
309
|
+
# 3. Install as an editable Python package (gets you all `attacklm-*` commands)
|
|
310
|
+
uv pip install -e ".[all]"
|
|
311
|
+
|
|
312
|
+
# 4. Initialize the dataset
|
|
295
313
|
attacklm-init --yes
|
|
296
314
|
|
|
297
|
-
#
|
|
298
|
-
# run each step individually, the four commands are still available:
|
|
299
|
-
#
|
|
300
|
-
# 4. Clone upstream data sources (~1.5GB total, optional — data is in the repo)
|
|
301
|
-
# attacklm-clone
|
|
302
|
-
#
|
|
303
|
-
# 5. Extract training data from each source
|
|
304
|
-
# attacklm-extract
|
|
305
|
-
#
|
|
306
|
-
# 6. Augment each JSONL with per-pair source/license attribution
|
|
307
|
-
# attacklm-attribute
|
|
308
|
-
#
|
|
309
|
-
# 7. Organize into 16 MITRE/AI/tools buckets
|
|
310
|
-
# attacklm-buckets
|
|
311
|
-
|
|
312
|
-
# 8. Pick a base model — use an uncensored/abliterated one (see "Pick a base model" below)
|
|
313
|
-
# Example: Qwen2.5-Coder-3B-Instruct with refusal direction removed
|
|
314
|
-
# v0.2.0+ uses --dataset (multi-positional) instead of --include-tools etc.
|
|
315
|
+
# 5. Train
|
|
315
316
|
attacklm-train-all --single-model \
|
|
316
317
|
--dataset base/ \
|
|
317
318
|
--base-model huihui-ai/Qwen2.5-Coder-3B-Instruct-abliterated \
|
|
318
319
|
--epochs 5 --max-length 2048
|
|
319
|
-
|
|
320
|
-
# Optional: add --hpo for automatic lora_r / lora_dropout sweep
|
|
321
320
|
```
|
|
322
321
|
|
|
323
322
|
The trained LoRA adapter lands in `models/attacklm-single_<TIMESTAMP>/`
|
|
@@ -338,6 +337,17 @@ The project ships as a **proper Python package** (`pyproject.toml`,
|
|
|
338
337
|
`src/attacklm/` layout, hatchling build backend) so users don't have to
|
|
339
338
|
build anything by hand.
|
|
340
339
|
|
|
340
|
+
**Install from PyPI (recommended):**
|
|
341
|
+
```bash
|
|
342
|
+
uv pip install "attacklm[all]" # CUDA training stack
|
|
343
|
+
uv pip install "attacklm[all-rocm]" # ROCm training stack
|
|
344
|
+
uv pip install "attacklm[infer]" # CPU / Apple Silicon (inference only)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Then clone the repo for the training data: `git clone https://github.com/Veedubin/AttackLM.git`
|
|
348
|
+
|
|
349
|
+
**Install from source** (editable, for development):
|
|
350
|
+
|
|
341
351
|
There are **two GPU stacks** — pick the one for your hardware.
|
|
342
352
|
|
|
343
353
|
---
|
|
@@ -437,7 +447,7 @@ prompts. Pick `[all-cuda]` or `[all-rocm]` for actual training.
|
|
|
437
447
|
|
|
438
448
|
---
|
|
439
449
|
|
|
440
|
-
###
|
|
450
|
+
### 21 console-script entry points
|
|
441
451
|
|
|
442
452
|
All install paths give you these:
|
|
443
453
|
|
|
@@ -452,11 +462,18 @@ All install paths give you these:
|
|
|
452
462
|
| `attacklm-build` | `scripts/build.py` | merge → GGUF → install (one shot) |
|
|
453
463
|
| `attacklm-demo` | `scripts/demo.py` | Multi-agent orchestrator demo |
|
|
454
464
|
| `attacklm-extract` | all 6 extractors | Extract data from cloned repos |
|
|
455
|
-
| `attacklm-buckets` | `setup_buckets.py` + `reorganize_buckets.py` | Organize data into
|
|
465
|
+
| `attacklm-buckets` | `setup_buckets.py` + `reorganize_buckets.py` | Organize data into 23 buckets |
|
|
456
466
|
| `attacklm-attribute` | `scripts/augment_attribution.py` | Add source/license to each JSONL row |
|
|
457
467
|
| `attacklm-clone` | `scripts/clone_repos.sh` | Clone upstream data repos |
|
|
458
468
|
| `attacklm-init` | `scripts/init_pipeline.py` | **One-shot init: clone→extract→attribute→buckets** (probes local first) |
|
|
459
469
|
| `attacklm-balance` | `scripts/balance_buckets.py` | Build a balanced subset of the buckets |
|
|
470
|
+
| `attacklm-build` | `scripts/build.py` | merge → GGUF → install (one shot) |
|
|
471
|
+
| `attacklm-train-lora` | `scripts/train_template.py` | Direct LoRA training (single dataset) |
|
|
472
|
+
| `attacklm-eval` | `scripts/eval_retention.py` | Retention evaluation suite |
|
|
473
|
+
| `attacklm-collect-ref` | `scripts/collect_reference.py` | Collect reference model outputs |
|
|
474
|
+
| `attacklm-score` | `scripts/score_candidates.py` | Score candidate models vs reference |
|
|
475
|
+
| `attacklm-compare` | `scripts/compare_scores.py` | Compare multiple candidate models |
|
|
476
|
+
| `attacklm-golden` | `scripts/golden_vectors.py` | Golden vector regression gates |
|
|
460
477
|
|
|
461
478
|
The CLI dispatchers are thin wrappers — they use `runpy.run_path()` to
|
|
462
479
|
invoke the canonical script in `scripts/`. So `scripts/` stays the
|
|
@@ -499,7 +516,7 @@ thin dispatcher layer.
|
|
|
499
516
|
|
|
500
517
|
## Architecture
|
|
501
518
|
|
|
502
|
-
The training data is organized into **
|
|
519
|
+
The training data is organized into **23 buckets**:
|
|
503
520
|
|
|
504
521
|
- **10 MITRE tactic buckets** — under `base/`: `base/collection`,
|
|
505
522
|
`base/command_and_control`, `base/credential_access`, `base/defense_evasion`,
|
|
@@ -510,9 +527,13 @@ The training data is organized into **16 buckets**:
|
|
|
510
527
|
- **1 orchestrator bucket** — routing decisions across 6 sub-agents
|
|
511
528
|
- **2 AI-model attack buckets** — under `ai/`: `ai/prompt-injection` and
|
|
512
529
|
`ai/jailbreaking` (TA0040 — Adversarial ML)
|
|
513
|
-
- **3 security-tool buckets** — under `tools/`: `tools/
|
|
514
|
-
|
|
515
|
-
|
|
530
|
+
- **3 security-tool buckets** — under `tools/`: `tools/metasploit`
|
|
531
|
+
- **3 defensive buckets** — under `defensive/`: `defensive/detection_engineering`
|
|
532
|
+
(Sigma, Elastic, Splunk — 5,000 pairs), `defensive/threat_hunting`
|
|
533
|
+
(Mordor, ThreatHunter-Playbook — 650 pairs), `defensive/incident_response`
|
|
534
|
+
(NIST SP 800-61r3 — 200 pairs)
|
|
535
|
+
- **4 extended-category buckets** — `attack_tactics/`, `web_app/`, `cloud/`,
|
|
536
|
+
`ics/`, `wireless/`, `supply_chain/`, `social_engineering/`
|
|
516
537
|
|
|
517
538
|
> **v0.2.1 layout change:** the 10 tactic buckets moved from top-level
|
|
518
539
|
> into a new `base/` parent directory, and `ai-models/` was renamed to
|
|
@@ -666,13 +687,15 @@ The new dataset spec is dir-shaped and hierarchical:
|
|
|
666
687
|
| Spec | Resolves to | Pair count |
|
|
667
688
|
|-------------------------------|------------------------------------------------------|-----------:|
|
|
668
689
|
| `base/` | All 10 MITRE tactic buckets | 7,398 |
|
|
669
|
-
| `tools/` | All
|
|
670
|
-
| `tools/metasploit/` | Just metasploit |
|
|
671
|
-
| `tools/infection_monkey/` | Just infection_monkey | 36 |
|
|
672
|
-
| `tools/rta/` | Just RTA | 76 |
|
|
690
|
+
| `tools/` | All tool buckets (metasploit) | 13,997 |
|
|
691
|
+
| `tools/metasploit/` | Just metasploit | 13,997 |
|
|
673
692
|
| `ai/` | Both AI buckets (jailbreaking, prompt-injection) | 743 |
|
|
693
|
+
| `defensive/` | All 3 defensive buckets | 5,850 |
|
|
694
|
+
| `defensive/detection_engineering/` | Sigma + Elastic + Splunk | 5,000 |
|
|
695
|
+
| `defensive/threat_hunting/` | Mordor + ThreatHunter-Playbook | 650 |
|
|
696
|
+
| `defensive/incident_response/` | NIST SP 800-61r3 | 200 |
|
|
674
697
|
| `orchestrator` | The orchestrator bucket | 380 |
|
|
675
|
-
| `all` | Everything (alias for `base + tools + ai + orchestrator`) |
|
|
698
|
+
| `all` | Everything (alias for `base + tools + ai + defensive + orchestrator`) | 21,865 |
|
|
676
699
|
| `tactics` | Alias for `base/` | 7,398 |
|
|
677
700
|
|
|
678
701
|
Multiple specs combine: `--dataset base/ tools/metasploit/` = 10 tactics + just metasploit = 15,747 pairs.
|
|
@@ -682,15 +705,17 @@ and translate internally to `--dataset` specs. The new flag wins if both are pas
|
|
|
682
705
|
|
|
683
706
|
### Balanced sampling (`attacklm-balance`)
|
|
684
707
|
|
|
685
|
-
The
|
|
686
|
-
pairs (
|
|
708
|
+
The 23 buckets are heavily skewed: `tools/metasploit` alone has 13,997
|
|
709
|
+
pairs (64% of the 21,865 total). Training on raw `--dataset all`
|
|
687
710
|
makes the model see ~2 Metasploit examples for every 1 non-Metasploit
|
|
688
711
|
example, which overfits it to msfconsole syntax at the expense of
|
|
689
712
|
broader tactical coverage.
|
|
690
713
|
|
|
691
714
|
`attacklm-balance` builds a balanced subset of the buckets. It applies
|
|
692
715
|
a per-bucket cap (one cap applied uniformly to all buckets) and
|
|
693
|
-
selects examples from each bucket with a chosen strategy
|
|
716
|
+
selects examples from each bucket with a chosen strategy. Team presets
|
|
717
|
+
(`--preset red-team|purple-team|blue-team`) control the offensive/defensive
|
|
718
|
+
mix with pre-configured bucket weights.
|
|
694
719
|
|
|
695
720
|
```bash
|
|
696
721
|
# Dry-run: see the per-bucket caps + total without writing
|
|
@@ -715,7 +740,7 @@ attacklm-train --dataset data/datasets/balanced/balanced_7b-128gb.jsonl \
|
|
|
715
740
|
| `7b-128gb` | 1,500 | ~9,800 | 7B QLoRA on 128 GB rig |
|
|
716
741
|
| `14b-128gb`| 1,500 | ~9,800 | 14B QLoRA on 128 GB rig |
|
|
717
742
|
| `31b-128gb`| 2,000 | ~10,600 | 31B QLoRA on 128 GB rig |
|
|
718
|
-
| `full` | unlimited |
|
|
743
|
+
| `full` | unlimited | 21,865 | All data, no cap |
|
|
719
744
|
| `custom` | (you set)| (you set)| `--per-bucket-cap` or `--target-total` |
|
|
720
745
|
|
|
721
746
|
**Strategies** (within a bucket, after the cap is applied):
|
|
@@ -860,20 +885,21 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
|
|
860
885
|
## Data Sources (upstream)
|
|
861
886
|
|
|
862
887
|
| Project | License | Use |
|
|
863
|
-
|
|
864
|
-
| [
|
|
865
|
-
| [
|
|
866
|
-
| [
|
|
867
|
-
| [
|
|
868
|
-
| [
|
|
869
|
-
| [
|
|
870
|
-
| [
|
|
888
|
+
|---|---|---|---|
|
|
889
|
+
| [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) | BSD-3-Clause | 13,997 module description triples |
|
|
890
|
+
| [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) | DRL-1.1 | 3,000 detection rules |
|
|
891
|
+
| [elastic/detection-rules](https://github.com/elastic/detection-rules) | Elastic-2.0 | 1,200 EQL/KQL detection rules |
|
|
892
|
+
| [splunk/security_content](https://github.com/splunk/security_content) | Apache-2.0 | 800 SPL detections |
|
|
893
|
+
| [redcanaryco/atomic-red-team](https://github.com/redcanaryco/atomic-red-team) | MIT | 1,115 atomic test triples |
|
|
894
|
+
| [OTRF/Security-Datasets](https://github.com/OTRF/Security-Datasets) | Apache-2.0 | 500 Mordor event log scenarios |
|
|
895
|
+
| [mitre/stockpile](https://github.com/mitre/stockpile) | Apache-2.0 | 390 adversary-emulation abilities |
|
|
896
|
+
| [OTRF/ThreatHunter-Playbook](https://github.com/OTRF/ThreatHunter-Playbook) | Apache-2.0 | 150 hunting playbooks |
|
|
897
|
+
| NIST SP 800-61r3 | Public Domain | 200 IR procedure pairs (template-based) |
|
|
871
898
|
| [promptfoo/promptfoo](https://github.com/promptfoo/promptfoo) | MIT | Prompt injection probes |
|
|
872
899
|
| [NVIDIA/garak](https://github.com/NVIDIA/garak) | Apache-2.0 | DAN/probe resources |
|
|
873
900
|
| [utkusen/promptmap](https://github.com/utkusen/promptmap) | MIT | Prompt injection rules |
|
|
874
|
-
| [Azure/PyRIT](https://github.com/Azure/PyRIT) | MIT | Jailbreak templates |
|
|
875
|
-
| [cyberark/FuzzyAI](https://github.com/cyberark/FuzzyAI) | Apache-2.0 | Adversarial prompt resources |
|
|
876
|
-
| [Resident-Falker/TheBigPromptLibrary](https://github.com/Resident-Falker/TheBigPromptLibrary) | mixed MIT/MPL | Jailbreak + system prompt library |
|
|
901
|
+
| [Azure/PyRIT](https://github.com/Azure/PyRIT) | MIT | Jailbreak templates (reserved) |
|
|
902
|
+
| [cyberark/FuzzyAI](https://github.com/cyberark/FuzzyAI) | Apache-2.0 | Adversarial prompt resources (reserved) |
|
|
877
903
|
|
|
878
904
|
Full attribution, per-pair source mapping, and re-distribution guidance in
|
|
879
905
|
[**`/ATTRIBUTION.md`**](ATTRIBUTION.md).
|
|
@@ -883,8 +909,10 @@ Full attribution, per-pair source mapping, and re-distribution guidance in
|
|
|
883
909
|
## License
|
|
884
910
|
|
|
885
911
|
- **Code in this repository** — [MIT License](LICENSE)
|
|
886
|
-
- **Training data** —
|
|
887
|
-
|
|
912
|
+
- **Training data** — mixed licenses per source. The most restrictive
|
|
913
|
+
licenses in the dataset are DRL-1.1 (Sigma rules) and BSD-3-Clause
|
|
914
|
+
(Metasploit Framework). See [ATTRIBUTION.md](ATTRIBUTION.md) for the
|
|
915
|
+
full per-source license table.
|
|
888
916
|
- **Trained model weights** — MIT License as a new statistical artifact
|
|
889
917
|
learned from openly licensed material. Whether model weights are a
|
|
890
918
|
"derivative work" in the copyright sense is an unsettled question; no
|
|
@@ -908,6 +936,16 @@ submitting PRs, and extending the bucket/extractor system.
|
|
|
908
936
|
See [CHANGELOG.md](CHANGELOG.md) for the full version history. Notable
|
|
909
937
|
recent releases:
|
|
910
938
|
|
|
939
|
+
- **v0.5.0** (2026-06-24) — Blue-team data sources (6 new extractors,
|
|
940
|
+
5,850 pairs), team presets (red/purple/blue), 3 defensive buckets,
|
|
941
|
+
21,865 total pairs, 23 buckets.
|
|
942
|
+
- **v0.4.1** (2026-06-22) — 7-pattern ds4 evaluation framework,
|
|
943
|
+
steering vectors, 198 hermetic tests, dataset cleanup (8,649
|
|
944
|
+
synthetic records removed).
|
|
945
|
+
- **v0.4.0** (2026-06-22) — MoE-safe training, retention eval,
|
|
946
|
+
experience replay, DoRA/LoftQ support.
|
|
947
|
+
- **v0.3.0** (2026-06-11) — Dataset license audit, per-source layout,
|
|
948
|
+
RTA/Infection Monkey/BPL removed, 100% per-record attribution.
|
|
911
949
|
- **v0.2.2** (2026-06-10) — `attacklm-balance` (balanced bucket sampler),
|
|
912
950
|
`attacklm-build` (one-shot merge+GGUF+install), auto-timestamped
|
|
913
951
|
run dirs in `attacklm-train`, accurate epoch counter, GGUF
|
|
@@ -927,6 +965,6 @@ recent releases:
|
|
|
927
965
|
## Acknowledgments
|
|
928
966
|
|
|
929
967
|
Thanks to the open-source security community — Red Canary, MITRE, Rapid7,
|
|
930
|
-
|
|
968
|
+
Elastic, Splunk, OTRF, NIST, the SigmaHQ maintainers, the promptfoo,
|
|
931
969
|
garak, PyRIT, and FuzzyAI teams, and everyone who contributes to the
|
|
932
970
|
projects we depend on. AttackLM stands on their shoulders.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
**Threshold**: 0 errors, 0 warnings
|
|
13
13
|
|
|
14
14
|
**Checks**:
|
|
15
|
-
- All
|
|
15
|
+
- All 21,865 records present across 23 buckets
|
|
16
16
|
- No duplicate records
|
|
17
17
|
- All required fields present (messages, source, license, attribution)
|
|
18
18
|
- License attribution complete for all records
|