Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
gpu-instance-fingerprint — Fingerprinte die exakte GPU, auf der du läufst, selbst unter identischen GPUs, anhand der Reihenfolge, in der ihre Atomic Adds eintreffen. 99,1 % Genauigkeit, übersteht Neustarts, lässt sich nicht fälschen, und ein standardmäßiger torch.index_add_-Aufruf gibt sie preis. | Kitploit
Tools/GitHubGitHub/divagr18/gpu-instance-fingerprint
PrivatsphäreHardware-SicherheitPapers & Forschung
GitHubdivagr18/gpu-instance-fingerprint

gpu-instance-fingerprint

Fingerprinte die exakte GPU, auf der du läufst, selbst unter identischen GPUs, anhand der Reihenfolge, in der ihre Atomic Adds eintreffen. 99,1 % Genauigkeit, übersteht Neustarts, lässt sich nicht fälschen, und ein standardmäßiger torch.index_add_-Aufruf gibt sie preis.

Repository anzeigen

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Webseite
27527vor 4 TagenNoch nicht geprüft

Identische GPUs voneinander unterscheiden

Blogbeitrag: Telling identical GPUs apart from their numerical output

Zwei GPUs desselben Modells berechnen dieselbe Summe in einer leicht unterschiedlichen Reihenfolge, und dieser Unterschied reicht aus, um sie voneinander zu unterscheiden. Ein kleiner CUDA-Kernel identifiziert, auf welcher von 19 identischen NVIDIA A40s er gelaufen ist, mit 99,1 % Genauigkeit – allein anhand der Zahlen, die er berechnet. Er liest keine Seriennummer und verwendet keine Timer.

  • Er übersteht Neustarts. Nach einem Container-Neustart stimmten alle 12 Messungen mit dem richtigen Chip überein.
  • Er ließ sich nicht fälschen. Ein Angreifer auf einem Chip, der jede von ihm kontrollierbare Starteinstellung abstimmte, erreichte bestenfalls eine Korrelation von 0,616 mit dem Fingerabdruck eines anderen Chips. Echte Chips stimmen im Durchschnitt mit 0,946 mit ihrem eigenen überein, und nie unter 0,916.
  • Auch ein standardmäßiger torch.index_add_-Aufruf verrät ihn. Wenn man nichts außer der gewöhnlichen Ausgabe dieses Ops liest, lässt sich der Chip unter GPUs mit demselben Treiber mit 100 % Genauigkeit identifizieren und über gemischte Treiber hinweg mit 78 %.
  • Es funktioniert modellübergreifend: A40, RTX 3090, RTX 4090 und L40S.

Warum es funktioniert: Wenn Tausende von Thread-Blöcken darum wetteifern, einen Zähler zu aktualisieren, entscheidet die Hardware, wer zuerst ankommt. Winzige fertigungsbedingte Unterschiede zwischen den Kernen eines Chips verzerren diese Reihenfolge jedes Mal auf dieselbe Weise.

Der deterministische Modus von PyTorch beseitigt das Leck über index_add_. Das Repository enthält die Probes, jede Messung hinter den untenstehenden Zahlen und Skripte, die jedes Ergebnis auf einer Laptop-CPU reproduzieren.

Ergebnisse

ErgebnisZahlReproduzieren
Aktive Probe, 19 identische A40s, P3-Kanal (nur numerische Ausgabe, kein %smid)99,1 % LOO (111/112), Zufall 5,3 %, Separation 4,28xanalysis/pooled_analyze.py
Aktive Probe, 8 A40sP3 100 % LOO, Separation 4,09x, Permutation p = 0,0005analysis/analyze_puf.py
Treiber-Störfaktor: 4 A40s auf dem identischen Treiber (580.159.04)P3 100 % (6,10x), P2 100 % (5,43x)analysis/analyze_puf.py
Neustart: Container-Neustart, gleicher Die per UUID verifiziert (4 A40s)100 % Re-Identifikation (12/12), beide Kanäleanalysis/temporal_analyze.py
RTX 3090, 7 Chips über 4 TreiberversionenP3 100 % LOO (4,55x), P2 100 % (8,12x), p = 0,0005analysis/cross_model_analyze.py
RTX 4090, 2 Chips auf demselben Host und TreiberP3 6/6 (12,5x), P2 6/6 (17,8x)analysis/cross_model_analyze.py
L40S, 2 ChipsP3 4/4 (17,2x), P2 4/4 (13,8x)analysis/cross_model_analyze.py
Passiv torch.index_add_, K=65536, 6 A40s100 % gleicher Treiber (9/9), 78 % treiberübergreifendanalysis/passive_analyze.py
Kapazität der passiven Signatur, K=65536~217 unabhängige Bits (A40), ~239 (RTX 4090)analysis/roc_capacity.py
Fälschung: Angreifer durchläuft jeden von ihm kontrollierbaren Startparameterbeste Fälschung 0,616 Korrelation vs. 0,92 echte Untergrenzeanalysis/forge_analyze.py
Grenze: Vanilla-Transformer fwd/bwd, dichtes GEMM, TF32-Matmulbitidentisch über Chips hinweg, kein Leckanalysis/leak_analyze.py, analysis/channel_analyze.py
Verteidigung: torch.use_deterministic_algorithms(True)passiver Kanal eliminiert; 2,5-3,6x Backward-Kosten; aktive Probe unbeeinflusstanalysis/defense_analyze.py

LOO = Leave-one-out-Nearest-Centroid-Klassifikation einzelner Messungen gegen die Zentroide pro Chip. Separation = Abstand zwischen Chips / Abstand innerhalb eines Chips.

Wie es funktioniert

Die Probe (probes/probe_puf.py) ist ein kleiner cupy-Kernel. Er startet 4096 Blöcke mit 128 Threads. Jeder Thread führt dieselbe feste Kette von FMAs aus, dann zieht Thread 0 jedes Blocks mit atomicAdd(counter, 1) ein Ticket von einem globalen Zähler. Das Ticket ist der Ankunftsplatz dieses Blocks. Am Input unterscheidet sich zwischen den Chips nichts; das Einzige, was variiert, ist, welche Blöcke zuerst ankommen.

Diese Reihenfolge ist nicht zufällig. Der Work-Distributor bildet Blockindizes in einem nahezu festen Muster auf SMs ab, und jede SM auf einem gegebenen Die läuft aufgrund von Fertigungsschwankungen etwas schneller oder langsamer als ihre Geschwister. Gemittelt über 3000 Starts pendelt sich jeder Blockindex auf einen mittleren Ankunftsrang ein, der die Geschwindigkeit der SM widerspiegelt, auf der er landet.

fixed kernel, fixed input
        |
        v
blocks race to atomicAdd  -->  arrival slot per block (hardware-decided)
        |
        v  average over 3000 launches
mean arrival rank per block index (P3)  /  per physical SM via %smid (P2)
        |
        v  subtract the cross-chip mean (removes the architecture)
per-chip residual  -->  nearest-centroid match against enrolled chips

Drei Kanäle gehen aus einem Lauf hervor:

  • P3, Rang pro Block. Mittlerer Ankunfts-Slot pro Blockindex. Er wird allein aus der numerischen Ausgabe des Kernels gelesen: kein %smid, keine Timer, keine privilegierten Zähler. Dies ist der Hauptkanal.
  • P2, Rang pro SM. Dieselben Slots, gruppiert nach physischer SM über das %smid-Register. Die Gruppierung nach physischer SM mittelt thermisches Rauschen heraus, sodass P2 unter Last standhält: 100 % Re-Identifikation (18/18) nach 60 s Volllast-Stresstest.
  • P1, Randsumme. Ein Histogramm des float32-Ergebnisses einer festen Reduktion. Er ist schwach (1,20-fache Trennung auf 8 A40s), weil das Summieren den größten Teil der Ordnungsinformation zerstört.

Das Subtrahieren des Mittelwerts über alle Chips entfernt alles, was die Chips gemeinsam haben (Architektur, Treiber, Compiler), und hinterlässt das Residuum pro Die. Zwei Messungen desselben Chips liegen nahe beieinander; Messungen verschiedener Chips nicht.

Schnellstart

git clone https://github.com/divagr18/gpu-instance-fingerprint.git
cd gpu-instance-fingerprint
pip install -r requirements.txt        # numpy + scipy, enough for every analysis

Führen Sie die Analyse mit den enthaltenen Daten durch (CPU, keine GPU erforderlich):

python analysis/pooled_analyze.py      # 19 A40s: 111/112 = 99.1%
python analysis/analyze_puf.py "a40_8chip/*.json"   # 8 A40s: P3 100%

Die Probe auf einer GPU ausführen:

pip install numpy cupy-cuda12x
python probes/probe_puf.py 3 0 > gpu_a_r0.json   # 3 epochs, replicate 0 (about 2 s per epoch)
python probes/probe_puf.py 3 1 > gpu_a_r1.json

Sammeln Sie einige Replikate von jeder von zwei oder mehr GPUs desselben Modells und führen Sie dann Folgendes aus:

python analysis/analyze_puf.py "path/to/*.json"

Jeder JSON-Datensatz zeichnet die GPU-UUID, den Treiber, die cupy-Version sowie die Taktfrequenz und Temperatur pro Epoche neben den Messwerten auf. Die Analyse gruppiert nach Modellnamen und kennzeichnet Chips anhand der UUID.

Um auf entfernten Maschinen über SSH auszuführen, überträgt scripts/run_remote.sh eine Probe, führt sie parallel auf mehreren Hosts aus und sammelt das JSON ein:

OUT_DIR=data/my_run REPS=4 scripts/run_remote.sh probe gpu1=root@HOST1:PORT gpu2=root@HOST2:PORT

docker/Dockerfile baut ein Image mit CUDA 12.8, cupy und der vorinstallierten Probe (docker build -f docker/Dockerfile -t gpu-instance-fingerprint .).

Reproduzieren der einzelnen Ergebnisse

Alle Befehle werden vom Repo-Stammverzeichnis aus auf einer CPU ausgeführt. Die Skripte finden ihre Daten selbstständig in data/.

Tool herunterladen