Wie Hacker deinen Server manipulieren können und was du dagegen unternehmen kannst.
Die Anleitung habe ich aus dem offiziellen FiveM Forum.
Da ich die Informationen für sehr wichtig halte , habe ich es mal übersetzt.
Quelle: KLICK
Wichtig zu merken ist dass Hacker, wie jede andere Person mit böswilliger Absicht, immer neue Exploits und Wege finden werden um Abwehrmechanismen zu umgehen die eingerichtet wurden um sie zu stoppen. Die Entwickler von FiveM arbeiten unermüdlich daran, nicht nur jeden zu bannen der betrügt sondern auch unschuldige Spieler davon abzuhalten Ausversehen gebannt zu werden. Es gibt jedoch immer Menschen, die es schaffen, durch die Ritze zu rutschen. Hier kommst du ins Spiel! Die Sicherheit deines Servers sollte von größter Bedeutung sein. Selbst wenn Sie in einer Wohnanlage leben, schließen Sie nachts immer noch die Haustür ab. Warum sollten Sie Ihren Server also offen lassen, damit die Leute ihn ausnutzen können?
musst du selber verstehen, wie du Exploits auf deinem Server patchen kannst.
Was nutzen die Hacker überhaupt aus?
Fast jeder Hack der zum Zeitpunkt des Schreibens für FiveM verfügbar war, konzentriert sich darauf, beliebigen Lua-Code auf dem Client auszuführen. Die Möglichkeit beliebigen clientseitigen Lua-Code auszuführen, ermöglicht den Zugriff auf Spielfunktionen wie CreateVehicle , das Fahrzeuge erzeugt, oder AddExplosion , das Explosionen erzeugt.
Was jedoch am meisten missbraucht wird, ist die TriggerServerEvent-Funktion. TriggerServerEvent wird verwendet, um Signale an den Server zu senden und ihn aufzufordern den in den Serverskriptdateien definierten Lua-Code auszuführen. Auf dem Papier scheint dies völlig in Ordnung und für die Kommunikation zwischen Client und Server notwendig zu sein, aber leider berücksichtigen die meisten Ressourcen nicht, dass Clients Events willkürlich auslösen können. Nehmen wir zB. die Ressource esx_pizza.
In dieser Ressource gibt es ein Servererevents mit dem Namen esx_pizza: pay. Wenn ein Client dieses Event auslöst, ermittelt der Server anhand des Namens wie viel Geld der Spieler der es ausgelöst hat je nach der von ihm geleisteten Arbeit erhalten sollte und gibt es dann an ihn weiter.
Serverseitige Code:
ESX = nil
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
RegisterServerEvent('esx_pizza:pay')
AddEventHandler('esx_pizza:pay', function(amount)
local _source = source
local xPlayer = ESX.GetPlayerFromId(_source)
xPlayer.addMoney(tonumber(amount))
end)
Wenn der Job abgeschlossen ist, löst der Client das Event esx_pizza: pay (mithilfe von TriggerServerEvent) zusammen mit einem Betragswert aus. Der Betrag entspricht dem Geldbetrag den der Kunde erhalten sollte. Wenn der Server das Event empfängt, führt der Server den Code in AddEventHandler aus. Dieser Code erhält den vom Spielers an ihn gesendeten Betragswert und addiert nur den Betrag zum Gesamtgeld des Spielers.
Siehst du, wo das Problem liegt? Es gibt keine Berechtigung, ob der Spieler zum Job gehört. Der Client steuert, wie viel der Server ausgibt, dies bedeutet, dass ein Hacker einfach den Code verlieren kann, der das Event esx_pizza: Bezahle mit einem obszönen Ablauf auslöst, und sich Millionen von Dollar geben kann, wann immer er Lust dazu hat!
Was können wir dagegen unternehmen?
Ressourcen Patchen:
Eine schlechte Nachricht ist, dass es keine einfache Lösung für Ressourcenschwachstellen gibt. Du (oder im Idealfall die einzelnen Ressourcenhersteller) müsst Ausnutzbare Events im serverseitigen Code suchen und diesen Code neu schreiben, um den Exploit zu entfernen.
Kehren wir als Beispiel für die Suche zu esx_pizza zurück. Als erstes musst du den clientseitigen Code ansehen und genau herausfinden, wo esx_pizza: pay aufgerufen wird. Mit der Suchfunktion meines Code-Editors wird angezeigt, dass esx_pizza: pay in der folgenden Funktion aufgerufen wird:
Auszahlungsfunktion (Original):
function donnerlapaye()
ped = GetPlayerPed(-1)
vehicle = GetVehiclePedIsIn(ped, false)
vievehicule = GetVehicleEngineHealth(vehicle)
calculargentretire = round(viemaxvehicule-vievehicule)
if calculargentretire <= 0 then
argentretire = 0
else
argentretire = calculargentretire
end
ESX.Game.DeleteVehicle(vehicle)
local amount = livraisonTotalPaye-argentretire
if vievehicule >= 1 then
if livraisonTotalPaye == 0 then
ESX.ShowNotification(_U('not_delivery'))
ESX.ShowNotification(_U('pay_repair'))
ESX.ShowNotification(_U('repair_minus')..argentretire)
TriggerServerEvent("esx_pizza:pay", amount)
livraisonTotalPaye = 0
else
if argentretire <= 0 then
ESX.ShowNotification(_U('shipments_plus')..livraisonTotalPaye)
TriggerServerEvent("esx_pizza:pay", amount)
livraisonTotalPaye = 0
else
ESX.ShowNotification(_U('shipments_plus')..livraisonTotalPaye)
ESX.ShowNotification(_U('repair_minus')..argentretire)
TriggerServerEvent("esx_pizza:pay", amount)
livraisonTotalPaye = 0
end
end
else
if livraisonTotalPaye ~= 0 and amount <= 0 then
ESX.ShowNotification(_U('truck_state'))
livraisonTotalPaye = 0
else
if argentretire <= 0 then
ESX.ShowNotification(_U('shipments_plus')..livraisonTotalPaye)
TriggerServerEvent("esx_pizza:pay", amount)
livraisonTotalPaye = 0
else
ESX.ShowNotification(_U('shipments_plus')..livraisonTotalPaye)
ESX.ShowNotification(_U('repair_minus')..argentretire)
TriggerServerEvent("esx_pizza:pay", amount)
livraisonTotalPaye = 0
end
end
end
end
Alles anzeigen
Auszahlungsfunktion:
function donnerlapaye()
local ped = PlayerPedId() -- This is the player's ped
local jobVehicle = GetVehiclePedIsIn(ped, false) -- This is the player's vehicle that they are currently sitting in
local jobVehicleHealth = GetVehicleEngineHealth(jobVehicle) -- This is that vehicles health
local jobVehicleDamage = round(jobVehicleMaxHealth-jobVehicleHealth) -- This is the job vehicles damage
if jobVehicleDamage <= 0 then
jobVehicleDamage = 0
end
ESX.Game.DeleteVehicle(jobVehicle)
local amount = jobCurrentPayout-jobVehicleDamage
if jobVehicle >= 1 then
if jobCurrentPayout == 0 then
ESX.ShowNotification(_U('not_delivery'))
ESX.ShowNotification(_U('pay_repair'))
ESX.ShowNotification(_U('repair_minus')..jobVehicleDamage)
TriggerServerEvent("esx_pizza:pay", amount)
jobCurrentPayout = 0
else
if jobVehicleDamage <= 0 then
ESX.ShowNotification(_U('shipments_plus')..jobCurrentPayout)
TriggerServerEvent("esx_pizza:pay", amount)
jobCurrentPayout = 0
else
ESX.ShowNotification(_U('shipments_plus')..jobCurrentPayout)
ESX.ShowNotification(_U('repair_minus')..jobVehicleDamage)
TriggerServerEvent("esx_pizza:pay", amount)
jobCurrentPayout = 0
end
end
else
if jobCurrentPayout ~= 0 and amount <= 0 then
ESX.ShowNotification(_U('truck_state'))
jobCurrentPayout = 0
else
if jobVehicleDamage <= 0 then
ESX.ShowNotification(_U('shipments_plus')..jobCurrentPayout)
TriggerServerEvent("esx_pizza:pay", amount)
jobCurrentPayout = 0
else
ESX.ShowNotification(_U('shipments_plus')..jobCurrentPayout)
ESX.ShowNotification(_U('repair_minus')..jobVehicleDamage)
TriggerServerEvent("esx_pizza:pay", amount)
jobCurrentPayout = 0
end
end
end
end
Alles anzeigen
Um diesen Code einfach auszudrücken: Er erhält zuerst den Gesundheitszustand des Jobfahrzeugs, berechnet seinen Schaden, nimmt diesen aus der potenziellen Auszahlung und weist den Server an, das Geld dem Spieler zu geben. Das massive Problem ist, dass das gesamte Skript clientseitig ist und wenn der Client dem Server einen der Zahlungswerte geben muss, ist es Ausnutzbar! Wie ich zuvor gezeigt habe, ist der Servercode nur diese anfällige Funktion und sonst nichts. Dies bedeutet, dass dieses Skript neu geschrieben werden muss, damit die Werte nicht auf dem Client, sondern auf dem Server berechnet werden. Dies erhöht zwar die Komplexität, erschwert jedoch die Ausnutzung um das 1000-fache.
Überprüfen von Clientaktionen
Nun gehe ich davon aus, dass Ihr jedes Ausnutzbare Event auf eurem gesamten Server gepatcht habt. Jetzt könnt Ihr in die Offensive gehen und sicherstellen, dass Clients die eurem Server beitreten keine Dinge tun dürfen die Ihnen nicht erlaubt sind.
Event Honeypots
Das Konzept besteht darin, eine Reihe von Ereignishandlern für Events einzurichten, die häufig von Hackern (und ihren Hack-Menüs) ausgenutzt werden, aber auf Ihrem eigenen Server nicht vorhanden sind. Jemand hat es_admin: banPlayer ausgeführt und du führst nicht einmal einen ESX-Server aus? Jemand anderes hat versucht, einen Spieler ins Gefängnis zu bringen ohne Polizist zu sein? Verhindere, dass der Spieler eingesperrt wird. Die Möglichkeiten sind endlos!
Jetzt kannst du einen Eventshandler einrichten, der auf alle Events reagiert und sperrt. Wenn ein Event ausgeführt wird, das von keinem deiner Skripte verarbeitet wird. Dies ist derzeit jedoch eine schlechte Idee, da FiveM-Updates ständig neue Netzereignisse hinzufügen. Ein Update genügt, um jeden, der eine Verbindung zu Ihrem Server herstellt, automatisch zu sperren, bis du dieses Event zu deiner Whitelist hinfügst. Die gute Nachricht ist jedoch, dass dies möglicherweise eine praktikable Option ist, wenn die Eventdokumentation in Arbeit ist. Vorausgesetzt, dass alle Events in Zukunft dokumentiert werden, es könnte ein System eingerichtet werdendas die Eventsdokumentationen für neue Events durchsucht und diese automatisch auf die Whitelist setzt.
Andere clientseitige Prüfungen
Während du alles was Spieler auf deinem Server tun können, effektiv nur mit serverseitigem Code blockieren könntest, gibt es einige zusätzliche Erkennungen, die nur durch die Verwendung von Clientskripten erreichbar sind.
Befehlslistenprüfung
Es wäre richtig deine eigenen Menüs und Client-Befehle wie Killmenu oder Panickey zu registrieren. Zum Glück bietet FiveM eine Möglichkeit, alle registrierten Befehle abzurufen, die nativen GET_REGISTERED_COMMANDS . Das Problem ist, dass diese Informationen nur auf dem Client verfügbar sind. Es reicht jedoch aus, nur die Liste in einem Event an den Server zu senden.
Beispielcode
Client:
CreateThread(function()
while true do
TriggerServerEvent("checkMyCommandList", GetRegisteredCommands())
Wait(15000)
end
end)
Server:
local commandBlacklist = {
["killmenu"] = true,
["menu"] = true,
["chocolate"] = true,
["lol"] = true,
["pk"] = true,
["haha"] = true,
["panickey"] = true,
["FunCtionOk"] = true
}
RegisterNetEvent("checkMyCommandList")
AddEventHandler("checkMyCommandList", function(givenList)
for _, commmand in ipairs(givenList) do
if commandBlacklist[command] then
-- bad client!
DropClient(source)
break
end
end
end)
Alles anzeigen
Überprüfung der Ressourcenliste
Um Lua-Code tatsächlich in der Skriptlaufzeit von FiveM auszuführen, hängen sich Hacks entweder an eine vorhandene Laufzeit an und führen ein eigenes Skript darin aus, oder sie erstellen eine völlig neue Ressource häufig mit einem zufälligen Namen. Wir können dieses zweite Verhalten für uns selbst ausnutzen, indem wir den Server von Zeit zu Zeit über die auf dem Client registrierten Ressourcen informieren und dem Server ermöglichen zu überprüfen ob neue Ressourcen gestartet wurden.
Wenn dies nicht der Fall sein sollte dann, rufe dazu einfach die Ressourcenmenge mit GET_NUM_RESOURCES ab und verwende für i = 0, GetNumResources () - 1, GET_RESOURCE_BY_FIND_INDEX , um eine Liste der Ressourcen abzurufen und an den Server zu senden.
Der Server kann dann mit einer eigenen Liste, aller Ressourcen auf dem Server überprüfen . Wenn auf dem Client Ressourcen gefunden werden, die nicht auf dem Server sind, wird der Spieler gebannt.
Beispielcode
Client:
local function collectAndSendResourceList()
local resourceList = {}
for i=0,GetNumResources()-1 do
resourceList[i+1] = GetResourceByFindIndex(i)
end
TriggerServerEvent("checkMyResources", resourceList)
end
CreateThread(function()
while true do
collectAndSendResourceList()
Wait(15000)
end
end)
Alles anzeigen
Server:
local validResourceList
local function collectValidResourceList()
validResourceList = {}
for i=0,GetNumResources()-1 do
validResourceList[GetResourceByFindIndex(i)] = true
end
end
collectValidResourceList()
-- This makes sure that the resource list is always accurate
AddEventHandler("onResourceListRefresh", collectValidResourceList)
RegisterNetEvent("checkMyResources")
AddEventHandler("checkMyResources", function(givenList)
for _, resource in ipairs(givenList) do
if not validResourceList[resource] then
-- bad client!
DropClient(source)
break
end
end
end)
Alles anzeigen
Ende
Kommentare
Neu erstellte Kommentare unterliegen der Moderation und werden erst sichtbar, wenn sie durch einen Moderator geprüft und freigeschaltet wurden.
Neu erstellte Kommentare unterliegen der Moderation und werden erst sichtbar, wenn sie durch einen Moderator geprüft und freigeschaltet wurden.