☢[TUTORIAL]|- FIVEM - WIE HACKER DEINEN SERVER MANIPULIEREN KÖNNEN UND WAS DU DAGEGEN TUN KANNST| FIVEM-|☢
Exclusive FiveM Scripts
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
musst du selber verstehen, wie du Exploits auf deinem Server patchen kannst.
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!
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
	
	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
	
	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.
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.
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.
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.
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.
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)
	
	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.
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)
	
	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)
	
	Ende