mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-29 15:40:58 +03:00
Add 55 new skills across 3 new domains + 6 undercovered areas (762 -> 817)
Demand-driven expansion targeting the fastest-growing 2025-2026 threat and
skills categories (ISC2/WEF/CrowdStrike/Mandiant signals):
- AI Security (NEW domain, 12 skills): LLM red-teaming with garak/PyRIT,
prompt injection (direct/indirect/RAG), MCP tool-poisoning, agentic tool
invocation, guardrails, model/data poisoning, system-prompt leakage,
embedding/vector weaknesses, model extraction, continuous red-teaming
- Supply Chain Security (NEW domain, 5 skills): SBOMs, dependency confusion,
malicious-npm triage, typosquatting, SLSA/Sigstore provenance
- Hardware & Firmware Security (NEW domain, 4 skills): CHIPSEC/UEFI audit,
Secure Boot bypass, TPM measured-boot attestation, ESP bootkit hunting
- Identity (10): Entra ID/ROADtools, GraphRunner, AADInternals, ADCS/Certipy,
shadow credentials, coercion, BloodHound CE, device-code phishing, SSO abuse
- Cloud-native (8): Stratus, Pacu, CloudFox, container escape, K8s RBAC,
Falco, Trivy, kube-bench
- Offensive C2 (6): Sliver, Havoc, NetExec, DPAPI, NTLM relay ESC8, redirectors
- DFIR (6): Hayabusa, Chainsaw, KAPE, Velociraptor, EZ Tools, Plaso
- Backfill (4): OpenCTI, MISP, honeytokens, post-quantum crypto migration
Each skill follows the repo taxonomy (SKILL.md + references/{standards,api-reference}.md
+ scripts/agent.py + LICENSE), with researched real tool commands (no placeholders),
complete frontmatter, and ATT&CK/ATLAS + NIST CSF mappings. Updates README domain
table, skill count, and index.json.
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. Please do not remove or change
|
||||
the license header comment from a contributed file except when
|
||||
necessary.
|
||||
|
||||
Copyright 2026 mukul975
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,204 @@
|
||||
---
|
||||
name: detecting-model-extraction-attacks
|
||||
description: Detect model stealing, model inversion, and membership inference performed through inference-API abuse by monitoring query patterns, applying output perturbation, and red-teaming your own model's extractability.
|
||||
domain: cybersecurity
|
||||
subdomain: ai-security
|
||||
tags:
|
||||
- ai-security
|
||||
- model-extraction
|
||||
- membership-inference
|
||||
- model-inversion
|
||||
- inference-api
|
||||
- mitre-atlas
|
||||
- query-monitoring
|
||||
- mlsecops
|
||||
version: '1.0'
|
||||
author: mahipal
|
||||
license: Apache-2.0
|
||||
nist_csf:
|
||||
- MEASURE-2.6
|
||||
mitre_attack:
|
||||
- AML.T0024
|
||||
---
|
||||
# Detecting Model Extraction Attacks
|
||||
|
||||
> **Authorized Use Only:** The extraction, inversion, and membership-inference techniques described here are intended for defenders testing their own models and for red teams operating under written authorization. Querying a third-party model to clone it, reconstruct its training data, or infer membership without permission may violate terms of service, copyright, and privacy law.
|
||||
|
||||
## Overview
|
||||
|
||||
Model extraction is the family of attacks in which an adversary abuses a model's **inference API** to steal value that the model owner intended to keep private. MITRE ATLAS catalogs these under **AML.T0024 — Exfiltration via AI Inference API**, in the *Exfiltration* tactic, with three sub-techniques:
|
||||
|
||||
- **AML.T0024.000 — Infer Training Data Membership** (membership inference): the adversary determines whether a specific record was part of the training set, a privacy violation that can expose, for example, whether a patient's record trained a medical model.
|
||||
- **AML.T0024.001 — Invert AI Model** (model inversion): the adversary reconstructs representative training inputs (e.g., faces, text) by exploiting confidence scores returned by the API.
|
||||
- **AML.T0024.002 — Extract ML Model** (model stealing): the adversary repeatedly queries the victim model, collects (input, prediction) pairs, and trains a *surrogate* model offline that mimics the victim's decision boundary — avoiding the per-query cost of a Machine-Learning-as-a-Service offering and stealing the owner's intellectual property.
|
||||
|
||||
All three share a common signal: an attacker must send **many queries**, often crafted to probe the decision boundary (high-entropy, near-boundary, synthetic, or systematically grid-sampled inputs), and frequently requests **full confidence vectors / logits** rather than just the top label. Detection therefore centers on per-principal query monitoring, input-distribution analysis, and confidence-exposure controls, while defense centers on rate limiting, output perturbation, and reducing the information returned per query. This skill follows the MITRE ATLAS technique definition for AML.T0024 (https://atlas.mitre.org/techniques/AML.T0024) and the NIST AI RMF MEASURE function (MEASURE-2.6, security and resilience of the AI system).
|
||||
|
||||
## When to Use
|
||||
|
||||
- When you operate a model behind a public or partner inference API and need to detect cloning, inversion, or membership inference.
|
||||
- When performing a pre-deployment AI red-team exercise to measure how many queries are needed to extract your own model.
|
||||
- When validating that rate limiting, output perturbation, and confidence-suppression controls actually reduce extractability.
|
||||
- When investigating anomalous billing/usage spikes that may indicate surrogate-model harvesting.
|
||||
- When responding to a privacy incident where membership inference against a model is suspected.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.9+ environment.
|
||||
- Access to inference-API access logs (per-API-key/per-principal query counts, timestamps, input features or hashes, returned confidence vectors).
|
||||
- For self-assessment red-teaming, install the Adversarial Robustness Toolbox (ART), the reference framework for extraction/inference attacks and defenses:
|
||||
```bash
|
||||
pip install adversarial-robustness-toolbox scikit-learn numpy
|
||||
```
|
||||
- Optional: access to the target model object (white/grey-box) or only its API (black-box).
|
||||
- Authorization to test the target model.
|
||||
|
||||
## Objectives
|
||||
|
||||
- Instrument the inference API to record per-principal query volume, input diversity, and confidence-exposure.
|
||||
- Build a detector that scores principals for extraction-like behavior (volume, near-boundary sampling, full-vector requests).
|
||||
- Run an ART-based extraction attack against your own model to measure fidelity vs. query budget.
|
||||
- Run a membership-inference attack to quantify training-data leakage.
|
||||
- Apply and validate defenses: rate limiting, label-only responses, confidence rounding/perturbation, and prediction poisoning.
|
||||
|
||||
## MITRE ATT&CK Mapping
|
||||
|
||||
| ID | Name (MITRE ATLAS) | Tactic |
|
||||
|----|--------------------|--------|
|
||||
| AML.T0024 | Exfiltration via AI Inference API | Exfiltration |
|
||||
| AML.T0024.000 | Infer Training Data Membership | Exfiltration |
|
||||
| AML.T0024.001 | Invert AI Model | Exfiltration |
|
||||
| AML.T0024.002 | Extract ML Model | Exfiltration |
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Instrument the inference API for detection signals
|
||||
Capture the fields a detector needs. Per request, log the principal (API key / IP / account), timestamp, an input fingerprint, and whether the caller requested probabilities/logits.
|
||||
|
||||
```python
|
||||
import hashlib, json, time
|
||||
|
||||
def log_inference(principal, features, returned_probs):
|
||||
record = {
|
||||
"ts": time.time(),
|
||||
"principal": principal,
|
||||
# hash inputs so logs don't store raw sensitive data
|
||||
"input_hash": hashlib.sha256(json.dumps(features, sort_keys=True).encode()).hexdigest(),
|
||||
"wants_probs": returned_probs,
|
||||
"n_features": len(features),
|
||||
}
|
||||
with open("inference_audit.jsonl", "a") as f:
|
||||
f.write(json.dumps(record) + "\n")
|
||||
```
|
||||
|
||||
### 2. Detect extraction-like query patterns
|
||||
Score each principal on the three signals that distinguish extraction from normal use: high query volume in a window, high *unique-input* ratio (attackers rarely repeat), and a high rate of full-probability requests.
|
||||
|
||||
```python
|
||||
import collections, json
|
||||
|
||||
def score_principals(audit_path="inference_audit.jsonl", window_qps_threshold=100):
|
||||
by_principal = collections.defaultdict(lambda: {"q": 0, "uniq": set(), "probs": 0})
|
||||
for line in open(audit_path):
|
||||
r = json.loads(line)
|
||||
p = by_principal[r["principal"]]
|
||||
p["q"] += 1
|
||||
p["uniq"].add(r["input_hash"])
|
||||
p["probs"] += int(r["wants_probs"])
|
||||
findings = []
|
||||
for principal, p in by_principal.items():
|
||||
uniq_ratio = len(p["uniq"]) / max(p["q"], 1)
|
||||
prob_ratio = p["probs"] / max(p["q"], 1)
|
||||
suspicious = p["q"] > window_qps_threshold and uniq_ratio > 0.9 and prob_ratio > 0.8
|
||||
findings.append({"principal": principal, "queries": p["q"],
|
||||
"unique_ratio": round(uniq_ratio, 3),
|
||||
"prob_request_ratio": round(prob_ratio, 3),
|
||||
"suspected_extraction": suspicious})
|
||||
return sorted(findings, key=lambda x: -x["queries"])
|
||||
```
|
||||
|
||||
### 3. Measure your model's extractability with ART (self red-team)
|
||||
Use ART's `CopycatCNN` (or `KnockoffNets`) to train a surrogate from black-box queries and report fidelity at a given query budget. Low query budget + high agreement = high risk.
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
from art.estimators.classification import SklearnClassifier
|
||||
from art.attacks.extraction import KnockoffNets
|
||||
from sklearn.ensemble import RandomForestClassifier
|
||||
|
||||
# victim is your already-trained model wrapped for ART
|
||||
victim = SklearnClassifier(model=trained_model) # your production model
|
||||
thief_model = RandomForestClassifier(n_estimators=100)
|
||||
thief = SklearnClassifier(model=thief_model)
|
||||
|
||||
attack = KnockoffNets(classifier=victim, batch_size_fit=64,
|
||||
batch_size_query=64, nb_epochs=10, nb_stolen=2000)
|
||||
stolen = attack.extract(x=x_pool, thief_classifier=thief) # 2000-query budget
|
||||
|
||||
agreement = np.mean(stolen.predict(x_test).argmax(1) == victim.predict(x_test).argmax(1))
|
||||
print(f"Surrogate fidelity (agreement with victim): {agreement:.2%} at 2000 queries")
|
||||
```
|
||||
|
||||
### 4. Quantify training-data leakage with membership inference
|
||||
Run ART's black-box membership-inference attack. An accuracy meaningfully above 50% indicates the model leaks membership (AML.T0024.000).
|
||||
|
||||
```python
|
||||
from art.attacks.inference.membership_inference import MembershipInferenceBlackBox
|
||||
|
||||
mia = MembershipInferenceBlackBox(victim, attack_model_type="rf")
|
||||
# fit the attack on a labeled split of known members / non-members
|
||||
mia.fit(x_train[:500], y_train[:500], x_test[:500], y_test[:500])
|
||||
member_pred = mia.infer(x_train[500:1000], y_train[500:1000])
|
||||
nonmember_pred = mia.infer(x_test[500:1000], y_test[500:1000])
|
||||
acc = (member_pred.mean() + (1 - nonmember_pred.mean())) / 2
|
||||
print(f"Membership-inference accuracy: {acc:.2%} (0.50 = no leakage)")
|
||||
```
|
||||
|
||||
### 5. Apply and validate defenses
|
||||
Reduce the information returned and the query economics. Re-run steps 3 and 4 after each control to confirm extractability drops.
|
||||
|
||||
```python
|
||||
# (a) Label-only responses: never return full probability vectors to untrusted callers.
|
||||
def respond(probs, trusted):
|
||||
return int(probs.argmax()) if not trusted else probs.tolist()
|
||||
|
||||
# (b) Confidence rounding / output perturbation (raises queries needed for inversion):
|
||||
def perturb(probs, decimals=2, noise=0.01):
|
||||
p = np.round(probs, decimals) + np.random.normal(0, noise, probs.shape)
|
||||
p = np.clip(p, 0, None)
|
||||
return p / p.sum()
|
||||
```
|
||||
Defense in depth combines these with strict **per-principal rate limiting**, anomaly alerting from step 2, ART's `ReverseSigmoid` / prediction-poisoning postprocessor, and watermarking so an extracted surrogate remains attributable.
|
||||
|
||||
### 6. Alert and respond
|
||||
Wire step-2 findings into your SIEM. On a confirmed extraction pattern: throttle or revoke the API key, switch the principal to label-only responses, preserve the audit log as evidence, and assess membership-inference exposure for any sensitive training data.
|
||||
|
||||
## Tools and Resources
|
||||
|
||||
| Resource | Link |
|
||||
|----------|------|
|
||||
| MITRE ATLAS AML.T0024 — Exfiltration via AI Inference API | https://atlas.mitre.org/techniques/AML.T0024 |
|
||||
| Adversarial Robustness Toolbox (ART) | https://github.com/Trusted-AI/adversarial-robustness-toolbox |
|
||||
| ART extraction attacks (CopycatCNN, KnockoffNets) | https://adversarial-robustness-toolbox.readthedocs.io/ |
|
||||
| MITRE ATLAS Matrix | https://atlas.mitre.org/matrices/ATLAS |
|
||||
| NIST AI RMF (MEASURE function) | https://www.nist.gov/itl/ai-risk-management-framework |
|
||||
|
||||
## Detection Signal Reference
|
||||
|
||||
| Signal | Normal use | Extraction behavior |
|
||||
|--------|-----------|---------------------|
|
||||
| Query volume per principal | Bounded, bursty | Very high, sustained |
|
||||
| Unique-input ratio | Repeats common inputs | Near-1.0 (rarely repeats) |
|
||||
| Confidence-vector requests | Mostly top label | Demands full probs/logits |
|
||||
| Input distribution | In-distribution | Near-boundary / synthetic / grid |
|
||||
| Inter-query timing | Human-paced | Automated, regular |
|
||||
|
||||
## Validation Criteria
|
||||
|
||||
- [ ] Inference API logs per-principal query volume, input fingerprint, and confidence-exposure.
|
||||
- [ ] Detector scores principals and flags high-volume, high-unique-ratio, full-vector callers.
|
||||
- [ ] ART extraction attack run against own model; surrogate fidelity vs. query budget reported.
|
||||
- [ ] Membership-inference accuracy measured and compared against the 50% baseline.
|
||||
- [ ] Label-only / confidence-perturbation defenses applied and re-tested.
|
||||
- [ ] Per-principal rate limiting enforced and validated.
|
||||
- [ ] Alerts routed to SIEM with response playbook (throttle, revoke, preserve evidence).
|
||||
@@ -0,0 +1,52 @@
|
||||
# Model Extraction Detection — API / Library Reference
|
||||
|
||||
## Libraries
|
||||
|
||||
| Library | Install | Purpose |
|
||||
|---------|---------|---------|
|
||||
| adversarial-robustness-toolbox | `pip install adversarial-robustness-toolbox` | Extraction, inversion, and membership-inference attacks + defenses |
|
||||
| scikit-learn | `pip install scikit-learn` | Surrogate / attack model training |
|
||||
| numpy | `pip install numpy` | Confidence-vector math, perturbation |
|
||||
|
||||
## ART Extraction Attacks (`art.attacks.extraction`)
|
||||
|
||||
| Class | Key params | Purpose |
|
||||
|-------|-----------|---------|
|
||||
| `KnockoffNets` | `nb_stolen`, `batch_size_query`, `nb_epochs`, `sampling_strategy` | Train surrogate from black-box queries (Knockoff Nets) |
|
||||
| `CopycatCNN` | `nb_stolen`, `batch_size_fit`, `batch_size_query` | Copycat surrogate extraction for neural nets |
|
||||
| `attack.extract(x, thief_classifier=...)` | — | Run extraction; returns trained surrogate classifier |
|
||||
|
||||
## ART Inference Attacks (`art.attacks.inference.membership_inference`)
|
||||
|
||||
| Class | Key methods | Purpose |
|
||||
|-------|-------------|---------|
|
||||
| `MembershipInferenceBlackBox` | `.fit(...)`, `.infer(x, y)` | Black-box membership inference (AML.T0024.000) |
|
||||
| `MembershipInferenceBlackBoxRuleBased` | `.infer(x, y)` | Rule-based MIA baseline (no shadow training) |
|
||||
|
||||
## ART Defenses (postprocessors)
|
||||
|
||||
| Class | Purpose |
|
||||
|-------|---------|
|
||||
| `art.defences.postprocessor.ReverseSigmoid` | Perturb output probabilities to hinder extraction |
|
||||
| `art.defences.postprocessor.Rounded` | Round confidence values to reduce leaked precision |
|
||||
| `art.defences.postprocessor.HighConfidence` | Suppress low-confidence outputs |
|
||||
|
||||
## Estimator Wrappers
|
||||
|
||||
| Class | Purpose |
|
||||
|-------|---------|
|
||||
| `art.estimators.classification.SklearnClassifier` | Wrap a scikit-learn model as an ART victim |
|
||||
| `art.estimators.classification.KerasClassifier` / `PyTorchClassifier` | Wrap DL models |
|
||||
|
||||
## Detection Signals (custom)
|
||||
|
||||
| Signal | Heuristic |
|
||||
|--------|-----------|
|
||||
| Query volume | Queries/principal/window above baseline |
|
||||
| Unique-input ratio | `unique(input_hash)/queries` → ~1.0 |
|
||||
| Confidence-request ratio | Fraction of calls demanding full probability vectors |
|
||||
|
||||
## External References
|
||||
|
||||
- ART docs: https://adversarial-robustness-toolbox.readthedocs.io/
|
||||
- MITRE ATLAS AML.T0024: https://atlas.mitre.org/techniques/AML.T0024
|
||||
@@ -0,0 +1,29 @@
|
||||
# Standards and References — Detecting Model Extraction Attacks
|
||||
|
||||
## MITRE ATLAS Techniques
|
||||
|
||||
| ID | Name | Tactic | Rationale |
|
||||
|----|------|--------|-----------|
|
||||
| AML.T0024 | Exfiltration via AI Inference API | Exfiltration | Parent technique: abusing the inference API to steal model value or training data. |
|
||||
| AML.T0024.000 | Infer Training Data Membership | Exfiltration | Membership inference — determine if a record was in the training set (privacy leak). |
|
||||
| AML.T0024.001 | Invert AI Model | Exfiltration | Model inversion — reconstruct training inputs from confidence scores. |
|
||||
| AML.T0024.002 | Extract ML Model | Exfiltration | Model stealing — train a surrogate from query/response pairs to clone the model. |
|
||||
|
||||
## NIST AI RMF
|
||||
|
||||
| ID | Function | Rationale |
|
||||
|----|----------|-----------|
|
||||
| MEASURE-2.6 | AI system security and resilience are evaluated and documented | Extraction/inference testing measures and documents the model's resilience to inference-API abuse. |
|
||||
|
||||
## Official Resources
|
||||
|
||||
- MITRE ATLAS AML.T0024: https://atlas.mitre.org/techniques/AML.T0024
|
||||
- MITRE ATLAS Matrix: https://atlas.mitre.org/matrices/ATLAS
|
||||
- Adversarial Robustness Toolbox (Trusted-AI): https://github.com/Trusted-AI/adversarial-robustness-toolbox
|
||||
- NIST AI Risk Management Framework: https://www.nist.gov/itl/ai-risk-management-framework
|
||||
|
||||
## Key Research
|
||||
|
||||
- Tramèr et al., "Stealing Machine Learning Models via Prediction APIs" (USENIX Security 2016)
|
||||
- Shokri et al., "Membership Inference Attacks Against Machine Learning Models" (IEEE S&P 2017)
|
||||
- Orekondy et al., "Knockoff Nets: Stealing Functionality of Black-Box Models" (CVPR 2019)
|
||||
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
# For authorized AI red-teaming and defense of models you own or are permitted to test.
|
||||
# Cloning a third-party model or inferring its training data without consent may
|
||||
# violate terms of service, copyright, and privacy law.
|
||||
"""Model-extraction detection helper.
|
||||
|
||||
Two modes:
|
||||
detect - Parse an inference-API audit log (JSONL) and flag principals whose
|
||||
query behaviour matches MITRE ATLAS AML.T0024 (model extraction /
|
||||
inference). Pure stdlib, no external model needed.
|
||||
extract - Self red-team: train an ART surrogate against your own scikit-learn
|
||||
model and report fidelity vs. query budget (requires ART).
|
||||
|
||||
Audit log format (one JSON object per line):
|
||||
{"ts": 1700000000.0, "principal": "key-123", "input_hash": "ab..",
|
||||
"wants_probs": true, "n_features": 12}
|
||||
"""
|
||||
import argparse
|
||||
import collections
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
def load_audit(path):
|
||||
records = []
|
||||
with open(path, "r", encoding="utf-8") as fh:
|
||||
for ln, line in enumerate(fh, 1):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
records.append(json.loads(line))
|
||||
except json.JSONDecodeError as exc:
|
||||
print(f"[!] skip malformed line {ln}: {exc}", file=sys.stderr)
|
||||
return records
|
||||
|
||||
|
||||
def score_principals(records, q_threshold, uniq_threshold, prob_threshold):
|
||||
agg = collections.defaultdict(lambda: {"q": 0, "uniq": set(), "probs": 0})
|
||||
for r in records:
|
||||
principal = r.get("principal", "unknown")
|
||||
a = agg[principal]
|
||||
a["q"] += 1
|
||||
a["uniq"].add(r.get("input_hash", id(r)))
|
||||
a["probs"] += int(bool(r.get("wants_probs", False)))
|
||||
|
||||
findings = []
|
||||
for principal, a in agg.items():
|
||||
q = a["q"]
|
||||
uniq_ratio = len(a["uniq"]) / q if q else 0.0
|
||||
prob_ratio = a["probs"] / q if q else 0.0
|
||||
suspected = (q >= q_threshold and uniq_ratio >= uniq_threshold
|
||||
and prob_ratio >= prob_threshold)
|
||||
findings.append({
|
||||
"principal": principal,
|
||||
"queries": q,
|
||||
"unique_ratio": round(uniq_ratio, 3),
|
||||
"prob_request_ratio": round(prob_ratio, 3),
|
||||
"suspected_extraction": suspected,
|
||||
})
|
||||
return sorted(findings, key=lambda x: (-x["suspected_extraction"], -x["queries"]))
|
||||
|
||||
|
||||
def cmd_detect(args):
|
||||
records = load_audit(args.audit)
|
||||
if not records:
|
||||
print("[!] no usable records in audit log", file=sys.stderr)
|
||||
return 1
|
||||
findings = score_principals(records, args.min_queries,
|
||||
args.min_unique_ratio, args.min_prob_ratio)
|
||||
flagged = [f for f in findings if f["suspected_extraction"]]
|
||||
print(f"[+] analysed {len(records)} requests across {len(findings)} principals")
|
||||
print(f"[+] {len(flagged)} principal(s) match AML.T0024 extraction pattern\n")
|
||||
for f in findings:
|
||||
mark = "[ALERT]" if f["suspected_extraction"] else " "
|
||||
print(f"{mark} {f['principal']:<24} q={f['queries']:<7} "
|
||||
f"uniq={f['unique_ratio']:<6} probs={f['prob_request_ratio']}")
|
||||
if args.output:
|
||||
with open(args.output, "w", encoding="utf-8") as fh:
|
||||
json.dump(findings, fh, indent=2)
|
||||
print(f"\n[+] findings written to {args.output}")
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_extract(args):
|
||||
try:
|
||||
import numpy as np
|
||||
from sklearn.datasets import load_iris
|
||||
from sklearn.ensemble import RandomForestClassifier
|
||||
from sklearn.model_selection import train_test_split
|
||||
from art.estimators.classification import SklearnClassifier
|
||||
from art.attacks.extraction import KnockoffNets
|
||||
except ImportError:
|
||||
print("[!] install: pip install adversarial-robustness-toolbox scikit-learn numpy",
|
||||
file=sys.stderr)
|
||||
return 1
|
||||
|
||||
# demo victim trained on a public dataset (replace with your production model)
|
||||
data = load_iris()
|
||||
x_tr, x_te, y_tr, y_te = train_test_split(data.data, data.target,
|
||||
test_size=0.4, random_state=42)
|
||||
victim_model = RandomForestClassifier(n_estimators=100, random_state=0).fit(x_tr, y_tr)
|
||||
victim = SklearnClassifier(model=victim_model)
|
||||
|
||||
thief = SklearnClassifier(model=RandomForestClassifier(n_estimators=100))
|
||||
attack = KnockoffNets(classifier=victim, batch_size_fit=16, batch_size_query=16,
|
||||
nb_epochs=5, nb_stolen=args.budget, sampling_strategy="random")
|
||||
stolen = attack.extract(x=x_te, thief_classifier=thief)
|
||||
|
||||
agreement = float(np.mean(stolen.predict(x_te).argmax(1) ==
|
||||
victim.predict(x_te).argmax(1)))
|
||||
print(f"[+] query budget : {args.budget}")
|
||||
print(f"[+] surrogate fidelity : {agreement:.2%} agreement with victim")
|
||||
risk = "HIGH" if agreement > 0.9 else "MEDIUM" if agreement > 0.7 else "LOW"
|
||||
print(f"[+] extractability risk : {risk}")
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description="Model-extraction detection / self red-team")
|
||||
sub = p.add_subparsers(dest="cmd", required=True)
|
||||
|
||||
d = sub.add_parser("detect", help="flag extraction-like principals in an audit log")
|
||||
d.add_argument("--audit", required=True, help="path to JSONL inference audit log")
|
||||
d.add_argument("--min-queries", type=int, default=100)
|
||||
d.add_argument("--min-unique-ratio", type=float, default=0.9)
|
||||
d.add_argument("--min-prob-ratio", type=float, default=0.8)
|
||||
d.add_argument("--output", help="write findings JSON")
|
||||
d.set_defaults(func=cmd_detect)
|
||||
|
||||
e = sub.add_parser("extract", help="ART self red-team on a demo model")
|
||||
e.add_argument("--budget", type=int, default=2000, help="query budget for surrogate")
|
||||
e.set_defaults(func=cmd_extract)
|
||||
|
||||
args = p.parse_args()
|
||||
sys.exit(args.func(args))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user