Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
silifuzz — Esegue fuzzing sulle implementazioni di CPU generando input di test da proxy software, quindi li esegue su hardware reale per rilevare difetti di microarchitettura ed errata. | Kitploit
Strumenti/GitHubGitHub/google/silifuzz
Analisi delle VulnerabilitàFuzzingSicurezza HardwareAnalisi di Binari
GitHubgoogle/silifuzz

silifuzz

Esegue fuzzing sulle implementazioni di CPU generando input di test da proxy software, quindi li esegue su hardware reale per rilevare difetti di microarchitettura ed errata.

Vedi Repository
41638225 giorni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
# SiliFuzz - Fuzzing di CPU tramite proxy

## Cos'è SiliFuzz

SiliFuzz è un sistema che trova difetti nelle CPU fuzzando proxy software, come simulatori o disassemblatori di CPU, ed esegue poi gli input di test accumulati (noti come *corpus*) su CPU reali su larga scala. SiliFuzz è un lavoro in corso; per i dettagli, fare riferimento all'[articolo](https://github.com/google/silifuzz/blob/master/paper/silifuzz.pdf).

## Terminologia

##### Fuzzing software e copertura

Il fuzzing è una tecnica per testare un target (un'applicazione o un'API) con un gran numero di input di test generati al volo. L'obiettivo è rendere questi input il più interessanti e diversificati possibile per innescare casi limite. In altre parole, il fuzzing mira a massimizzare la copertura complessiva del codice.
La *copertura del codice* può avere significati diversi, ad esempio quali blocchi di base vengono eseguiti o quali percorsi vengono seguiti nel programma.

##### Proxy

Ai fini di SiliFuzz, un *proxy* è qualsiasi sistema software o hardware che si comporta in modo simile ad alcuni aspetti della CPU target. Ad esempio, un emulatore di CPU o un disassemblatore. Un proxy è necessario quando non possiamo raccogliere direttamente informazioni sulla copertura dal target.

Applicando tecniche di fuzzing a un proxy, possiamo generare una serie di input di test (corpus) che producono un comportamento interessante nel proxy. La nostra ipotesi di base è che questo si traduca in un comportamento altrettanto interessante nel target. Per saperne di più, consulta la [documentazione](https://github.com/google/silifuzz/blob/main/doc/proxy_architecture.md).

##### Corpus / shard del corpus

Una raccolta di input utilizzati per testare il target è nota come *corpus*.

Un corpus ragionevolmente grande contiene milioni di input e viene di solito suddiviso in più blocchi non sovrapposti chiamati *shard*.

##### Snapshot

Uno snapshot di SiliFuzz descrive una breve sequenza di istruzioni della CPU più uno stato iniziale dei registri e della memoria della CPU per eseguire deterministicamente quella sequenza. Uno snapshot tipico contiene meno di 100 byte di codice e viene eseguito in microsecondi, ma può essere arbitrariamente grande. Gli snapshot sono memorizzati come protocol buffer `silifuzz.proto.Snapshot`.

Gli snapshot vengono in genere creati a partire dagli input generati da un motore di fuzzing. Ai fini del test della CPU, questi input vengono filtrati per eliminare tutti gli snapshot non deterministici. Per saperne di più, consulta la [documentazione](https://github.com/google/silifuzz/blob/main/doc/what_makes_a_good_test.md).

###### Stato finale atteso

Uno stato finale descrive il contenuto dei registri e della memoria che ci si aspetta esista al termine dell'esecuzione di uno Snapshot. Se lo snapshot viene eseguito in modo diverso su microarchitetture CPU differenti, avrà più stati finali attesi.

##### Snap

Uno Snap è una rappresentazione in memoria di uno **Snapshot** che può essere facilmente caricata ed eseguita dal **Runner**. Gli Snap vengono in genere caricati dal disco da un *reading runner*. Il formato su disco di uno Snap è essenzialmente lo stesso di quello in memoria, tranne per il fatto che i puntatori nativi sono sostituiti da offset. Vedi questo [header](https://github.com/google/silifuzz/blob/main/snap/gen/relocatable_snap_generator.h) per i dettagli. Questo formato è spesso chiamato *rilocabile*. Ogni Snap contiene esattamente uno stato finale atteso, ovvero gli Snap sono specifici per microarchitettura. Per saperne di più, consulta la [documentazione](https://github.com/google/silifuzz/blob/main/doc/snap.md).

##### Runner

Runner è un binario per testare un singolo core della CPU. Un runner consuma uno shard del corpus, esegue ripetutamente Snap casuali al suo interno e verifica che lo stato finale atteso venga raggiunto. Runner è un processo single-threaded.

##### Orchestrator

L'orchestrator è un processo che gestisce più runner. In una configurazione tipica, l'orchestrator esegue continuamente un runner per ogni core logico della CPU e accumula e segnala eventuali errori prodotti dai singoli processi runner.

## Piattaforme e microarchitetture supportate

Vedi [questo file](https://github.com/google/silifuzz/blob/main/util/platform.h) per l'elenco delle microarchitetture supportate.

SiliFuzz gira su sistemi Linux x86_64 e aarch64. È stato testato con versioni del kernel Linux 5.x e 6.x. Non vi è alcuna garanzia che sia compatibile con versioni precedenti del kernel. L'ABI legacy vsyscall deve essere disattivata per evitare falsi positivi.

## Trofei

Un elenco non esaustivo di bug e difetti trovati da SiliFuzz.

### Bug

Un bug logico è un comportamento non valido della CPU inerente a una particolare microarchitettura o stepping della CPU. SiliFuzz ha identificato i seguenti bug:

*   [CVE-2021-26339](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-1028.html)
*   [Erratum #1386](https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/revision-guides/56323-PUB_1_01.pdf)
*   [Erratum #1468](https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/revision-guides/56323-PUB_1_01.pdf)
*   [Erratum #3442699 per ARM Neoverse V2](https://developer.arm.com/documentation/SDEN-2332927/900)
*   [Erratum #3213672 per ARM Cortex-X3](https://developer.arm.com/documentation/SDEN-2055130/1400)

### Difetti

Un difetto (elettrico) è un comportamento non valido della CPU che si verifica solo su uno o più chip. SiliFuzz ha trovato i seguenti difetti che abbiamo descritto nell'articolo

*   Difetto F2XM1.
    [Articolo](https://github.com/google/silifuzz/blob/master/paper/silifuzz.pdf) /
    Appendice A
*   Overshoot di un'istruzione illegale.
    [Articolo](https://github.com/google/silifuzz/blob/master/paper/silifuzz.pdf) /
    Appendice B
*   FCOS calcola male.
    [Articolo](https://github.com/google/silifuzz/blob/master/paper/silifuzz.pdf) /
    Appendice C
*   Aggiornamento mancante del puntatore dati x87.
    [Articolo](https://github.com/google/silifuzz/blob/master/paper/silifuzz.pdf) /
    Appendice D

## Progetti correlati

*   [Centipede](https://github.com/google/fuzztest/blob/main/centipede/README.md)
    è un motore di fuzzing sviluppato da Google per fuzzare target grandi e lenti
    come gli emulatori di CPU.

## Lavoro preliminare

### Lavoro preliminare (per Bazel)

```shell
git clone https://github.com/google/silifuzz.git && cd silifuzz
SILIFUZZ_SRC_DIR=`pwd`
./install_build_dependencies.sh  # Currently, works for the latest Ubuntu only.
bazel build -c opt @silifuzz//tools:{snap_corpus_tool,fuzz_filter_tool,snap_tool,silifuzz_platform_id,simple_fix_tool_main} \
     @silifuzz//runner:reading_runner_main_nolibc \
     @silifuzz//orchestrator:silifuzz_orchestrator_main
SILIFUZZ_BIN_DIR=`pwd`/bazel-bin
cd "${SILIFUZZ_BIN_DIR}"
```

NOTA: Puoi usare un container Docker per evitare di sporcare il sistema host: `docker run -it --tty --security-opt seccomp=unconfined --mount type=bind,source=${SILIFUZZ_SRC_DIR},target=/app ubuntu:noble /bin/bash -c "cd /app && ./install_build_dependencies.sh && bazel build ... && bazel test ..."`

### Lavoro preliminare (fuzzing del target Unicorn)

Per Bazel, usa i seguenti comandi.

```shell
cd "${SILIFUZZ_SRC_DIR}"
COV_FLAGS_FILE="$(bazel info output_base)/external/fuzztest+/centipede/clang-flags.txt"
bazel build -c opt --copt=-UNDEBUG --dynamic_mode=off \
  --per_file_copt=unicorn/.*@$(xargs < "${COV_FLAGS_FILE}" |sed -e 's/,/\\,/g' -e 's/ /,/g') @//proxies:unicorn_x86_64
bazel build -c opt @fuzztest//centipede:centipede
mkdir -p /tmp/wd

# Fuzz the Unicorn proxy under Centipede 1000 times with parallelism of 30.
"${SILIFUZZ_BIN_DIR}/external/fuzztest+/centipede/centipede" \
  --binary="${SILIFUZZ_BIN_DIR}/proxies/unicorn_x86_64" \
  --workdir=/tmp/wd \
  -j=30 --num_runs=1000
```

NOTA: Fare riferimento alla documentazione di [Centipede](https://github.com/google/fuzztest/blob/main/centipede/README.md#run-centipede-locally-) su come eseguire efficientemente il motore di fuzzing.

## Strumenti

### silifuzz_platform_id

Questo strumento di supporto serve a verificare che la macchina su cui stai eseguendo sia supportata.

```shell
$ ${SILIFUZZ_BIN_DIR}/tools/silifuzz_platform_id --short
```

```
intel-skylake
```

NOTA: La logica di rilevamento della CPU di SiliFuzz non tiene conto di alcune varianti desktop di CPU altrimenti supportate. In questi casi lo strumento riporterà "Unsupported platform".

### fuzz_filter_tool

[fuzz_filter_tool](https://github.com/google/silifuzz/blob/main/tools/fuzz_filter_tool.cc) converte le istruzioni grezze in Snapshot compatibili con Snap. Restituisce 0 quando la conversione è possibile e 1 altrimenti. Questa interfaccia è compatibile con [input_filter](https://github.com/google/fuzztest/blob/main/centipede/environment.cc) di Centipede.

```
fuzz_filter_tool raw_input_sequence
```

Il file `raw_input_sequence` contiene istruzioni grezze che verranno convertite nel formato Snapshot usando [InstructionsToSnapshot](https://github.com/google/silifuzz/blob/main/common/raw_insns_util.h)

Esempio di utilizzo:

```shell
# INC EAX
echo -en '\xFF\xC0' > /tmp/inc_eax && ./tools/fuzz_filter_tool /tmp/inc_eax
echo $?
0
```

### snap_tool

`snap_tool` esamina e manipola i proto binari degli Snapshot. Può opzionalmente caricare istruzioni grezze e convertirle in Snapshot.

```shell
echo -en '\xFF\xC0' > /tmp/inc_eax
./tools/snap_tool --raw print /tmp/inc_eax
```

```
Metadata:
  Id: inc_eax
  Architecture: x86_64 Linux
  Completeness: complete
Registers:
  gregs (non-0 only)
    rax = 0x20000000
    ....
```

### simple_fix_tool

Il simple fix tool prende i risultati di fuzzing da Centipede, converte le istruzioni grezze in snapshot senza stati finali, aggiunge gli stati finali agli snapshot e infine impacchetta gli snapshot in un corpus snap rilocabile e shardato.

Attualmente viene eseguito come processo non riavviabile su un singolo host e tutto viene caricato in memoria, quindi la dimensione del corpus gestibile è limitata dalla memoria disponibile dell'host. Poiché gli stati finali vengono generati sull'host, il corpus risultante è a architettura singola.

### hashtest_generator

Sperimentale: gli hash test sono test strutturati randomizzati che immettono entropia in istruzioni generate casualmente e catturano gli output risultanti nel modo più efficiente possibile. Questo approccio si basa sull'osservazione che una percentuale non banale di difetti può essere rilevata chiamando l'istruzione giusta con l'input giusto. Gli hash test colpiscono in modo aggressivo questa semplice classe di difetti per fornire un punto di confronto sperimentale per Silifuzz. Attualmente è supportata solo x86_64.

Se vuoi generare, ad esempio, 30k snapshot di hash test contenenti istruzioni supportate dai processori Skylake nella directory `/tmp/hashtest`, puoi eseguire questo comando.

```shell
mkdir -p /tmp/hashtest && bazel run -c opt @silifuzz//fuzzer/hashtest:hashtest_generator -- --platform=intel-skylake -n 30000 --outdir /tmp/hashtest
```

## Domande frequenti

Il resto del documento è organizzato in modalità How-to, con ogni domanda che descrive un caso d'uso tipico. La progressione delle domande rappresenta la crescente complessità del compito che si sta cercando di realizzare. Ogni passaggio richiede in genere la comprensione o gli artefatti (a volte entrambi) ottenuti al passaggio precedente.

NOTA: Il documento presuppone una CPU host/target `x86_64`. L'output esatto può variare a seconda del vendor/stepping/etc della CPU e dell'ambiente (ad es. Docker/KVM).

ATTENZIONE: molte delle istruzioni seguenti eseguono codice binario **arbitrario** con i privilegi dell'utente in esecuzione. Lo strumento fa del suo meglio per confinare il codice con seccomp(2). Usalo a tuo rischio.

### Come creare uno snapshot semplice

```shell
# INC EAX
$ echo -en '\xFF\xC0' > /tmp/inc_eax
$ ./tools/snap_tool --raw  --out=/tmp/inc_eax.pb make /tmp/inc_eax
```

```shell
# CPUID
$ echo -en '\x0F\xA2' > /tmp/cpuid
$ ./tools/snap_tool --raw --out=/tmp/cpuid.pb make /tmp/cpuid
```

```
<error log omitted>
Could not load snapshot: INTERNAL: Tracing failed: Banned instruction: CPUID
```

NOTA: Per evitare risultati non deterministici, varie parti di SiliFuzz escludono alcune classi di istruzioni, ad esempio CPUID qui sopra.

### Come ispezionare uno snapshot

```shell
$ ./tools/snap_tool print /tmp/inc_eax.pb
```

```
Metadata:
  Id: inc_eax
  Architecture: x86_64 Linux
  Completeness: complete
Registers:
  gregs (non-0 only):
    rax = 0x20000000
    rip = 0xeb85c12b000
    <omitted>
End states (1):
  Endpoint:
    Instruction address: 0xeb85c12b002
  Platforms:
    intel-skylake
  Registers (diff vs snapshot's initial values):
    gregs (modified only):
      rax = 0x20000001
      rip = 0xeb85c12b002
      <omitted>
```

Nota come il valore dello stato finale del registro `RAX` sia `0x20000001` (`0x20000000+1`, che è esattamente ciò che fa `INC EAX`). Nota anche che il valore di `RIP` è quello originale `+2`, che è la dimensione dell'istruzione `INC EAX`.

### Come eseguire uno snapshot da un proto

```shell
$ ./tools/snap_tool play /tmp/inc_eax.pb
```

```
Snapshot played successfully.
```

### Come convertire un singolo snapshot in un corpus (rilocabile)

Nota: Dovrai specificare una piattaforma target per generare un corpus. In questo esempio, il corpus risultante ha come target la piattaforma su cui è stato generato.

```shell
$ cd "${SILIFUZZ_BIN_DIR}"
$ PLATFORM_ID=$(./tools/silifuzz_platform_id --short)

$ ./tools/snap_tool generate_corpus /tmp/inc_eax.pb \
--target_platform="${PLATFORM_ID}" > /tmp/inc_eax.corpus

# Will play the same "INC EAX" snapshot 1M times
$ ./runner/reading_runner_main_nolibc /tmp/inc_eax.corpus
```

Puoi ispezionare il processo con gdb:

```shell
$ gdb ./runner/reading_runner_main_nolibc
```

```
(gdb) b RestoreUContextNoSyscalls
(gdb) run /tmp/inc_eax.corpus
Starting program: .../reading_runner_main_nolibc /tmp/inc_eax.corpus

Breakpoint 1, 0x0000456700010598 in RestoreUContextNoSyscalls ()
(gdb) x/i 0xeb85c12b000 # same as the rip value produced by snap_tool print above
   0xeb85c12b000:       inc    %eax
```

### Come creare un corpus da un emulatore

NOTA: Questo passaggio si basa sul passaggio "fuzzing del target Unicorn" descritto in precedenza.

Converti i risultati di fuzzing corpus.* in un corpus eseguibile a 10 shard per l'architettura corrente.

```shell
cd "${SILIFUZZ_BIN_DIR}"

"${SILIFUZZ_BIN_DIR}/tools/simple_fix_tool_main" \
  --num_output_shards=10 \
  --output_path_prefix=/tmp/wd/runnable-corpus \
  --runner="${SILIFUZZ_BIN_DIR}/runner/reading_runner_main_nolibc" \
  /tmp/wd/corpus.*
```

Gli shard del corpus saranno in /tmp/wd/runnable-corpus.*

### Come ispezionare un file corpus

```shell
$ ./tools/snap_corpus_tool list_snaps /tmp/inc_eax.corpus
...
I0000 00:00:1661887744.019079 4074672 snap_corpus_tool.cc:155] inc_eax
```

NOTA: Al momento questo è uno strumento molto basilare che offre solo pochi comandi.

### Come invocare il runner per analizzare un singolo core di una CPU

```shell
# Will play the same "INC EAX" snapshot on CPU#1 10k times.
$ ./runner/reading_runner_main_nolibc \
    --cpu=1 --num_iterations=10000 /tmp/inc_eax.corpus
```

### Come analizzare tutti i core di una CPU

L'orchestrator scorrerà tutti gli shard elencati nel file passato nell'argomento `--shard_list_file`.

```shell
$ ls -1 /tmp/wd/runnable-corpus.* > /tmp/wd/shard_list
$ echo 'version: "local_corpus"' > /tmp/wd/corpus_metadata
# Will repeatedly run the corpus on all available CPU cores for 30s using
# /tmp/wd/runnable-corpus.* selected randomly.
$ ${SILIFUZZ_BIN_DIR}/orchestrator/silifuzz_orchestrator_main --duration=30s \
     --runner=${SILIFUZZ_BIN_DIR}/runner/reading_runner_main_nolibc \
     --shard_list_file=/tmp/wd/shard_list \
     --corpus_metadata_file=/tmp/wd/corpus_metadata
```

NOTA: L'orchestrator può anche caricare shard di corpus compressi con XZ da file che terminano con `.xz`.
Scarica lo strumento