Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add recently introduced events, name and explosion/projectile checking #588

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion [admin]/security/events.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,26 @@ addEventHandler("onPlayerTriggerInvalidEvent", root, clientTriggersInvalidEvent)
function clientTriggersEventThreshold()
logViolation(source, "Exceeded event trigger threshold of "..tostring(getServerConfigSetting("max_player_triggered_events_per_interval")));
end
addEventHandler("onPlayerTriggerEventThreshold", root, clientTriggersEventThreshold);
addEventHandler("onPlayerTriggerEventThreshold", root, clientTriggersEventThreshold);



-- https://wiki.multitheftauto.com/wiki/OnPlayerConnect
-- we use onPlayerConnect event to check if the player got a valid username
function clientConnectServer(strPlayerNick, strPlayerIP, strPlayerUsername, strPlayerSerial, iPlayerVersionNumber, strPlayerVersionString)
if(not isPlayerNameValid(strPlayerNick)) then
logAction("Client "..strPlayerNick.." with IP "..strPlayerIP.." and Serial "..strPlayerSerial.." tried to join with invalid nickname! Version: "..iPlayerVersionNumber.." | "..strPlayerVersionString);
cancelEvent(true, "INVALID NICKNAME!");
return;
end
end
addEventHandler("onPlayerConnect", root, clientConnectServer);



-- https://wiki.multitheftauto.com/wiki/OnPlayerChangesWorldSpecialProperty
-- gets triggered when client changes world special property
function clientChangesWorldSpecialProperty(strProperty, bEnabled)
logViolation(source, "Changed world special property \""..strProperty.."\" to "..tostring(bEnabled));
end
addEventHandler("onPlayerChangesWorldSpecialProperty", root, clientChangesWorldSpecialProperty);
3 changes: 2 additions & 1 deletion [admin]/security/meta.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<meta>
<info name="Security" author="-ffs-PLASMA" type="misc" version="1.0" description="Basic security functionality" />

<min_mta_version server="1.6.0-9.22470" />
<min_mta_version server="1.6.0-9.22790" />

<script src="utils.lua" type="server"/>
<script src="logging.lua" type="server"/>
<script src="events.lua" type="server"/>
<script src="misc.lua" type="server"/>
Expand Down
101 changes: 100 additions & 1 deletion [admin]/security/players.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
-- used to check how many explosion/projectile sync packets a client sends overtime
local iExplosionCheckInterval = 3000; -- the interval in ms to check for players sending too many explosion and projectile sync packets
local tblPlayerProjectiles = {}; -- store players sending projectile sync packets
local tblRegularExplosions = {}; -- store players sending regular explosion sync packets
local tblVehicleExplosions = {}; -- store players sending vehicle explosion sync packets
local iPlayerProjectileThreshold = 10; -- the threshold when we consider client suspicious for projectile creations
local iRegularExplosionThreshold = 10; -- the threshold when we consider client suspicious for regular explosions
local iVehicleExplosionThreshold = 10; -- the threshold when we consider client suspicious for vehicle explosions



-- add the elementdatas you want to protect from client updates in here
local tblProtectedElementDatas = {["Score"] = true};

Expand All @@ -16,6 +27,18 @@ addEventHandler("onElementDataChange", root, clientChangesElementData);



-- https://wiki.multitheftauto.com/wiki/OnPlayerChangesProtectedData
-- gets triggered when a client tries to change protected element data
-- see elementdata_whitelisted config https://wiki.multitheftauto.com/wiki/Server_mtaserver.conf#elementdata_whitelisted
-- this needs to be setup in conjunction with your existing elementdatas to take necessary action!
-- the key feature is to prevent the client from updating non synced server elementdatas if they know the key and attached element
function clientChnagesProtectedData(uElement, strKey, unValue)
logViolation(source, "Tried to change protected elementdata for key "..tostring(strKey).." to value "..tostring(unValue).." for element "..tostring(uElement).." ("..getElementType(uElement)..")");
end
addEventHandler("onPlayerChangesProtectedData", root, clientChnagesProtectedData);



-- https://wiki.multitheftauto.com/wiki/OnPlayerACInfo
-- gets triggered when AC detects something for client on connect
function clientNotifyACInfo(tblDetectedACList, iD3D9Size, strD3D9MD5, strD3D9SHA256)
Expand Down Expand Up @@ -55,4 +78,80 @@ function clientNetworkStatus(iStatus, iTicks)
logViolation(source, "Network interruption has stopped after "..iTicks.." ticks");
end
end
addEventHandler("onPlayerNetworkStatus", root, clientNetworkStatus);
addEventHandler("onPlayerNetworkStatus", root, clientNetworkStatus);



-- https://wiki.multitheftauto.com/wiki/OnPlayerProjectileCreation
-- gets triggered when a player creates a projectile sync packets (eg. shoots a weapon, vehicle weapon or via createProjectile)
function clientCreateProjectile(iWeaponType, fPX, fPY, fPZ, fForce, uTarget, fRX, fRY, fRZ, fVX, fVY, fVZ)
if(isElement(source)) then
if(tblPlayerProjectiles[source]) then
tblPlayerProjectiles[source] = tblPlayerProjectiles[source] + 1;
else
tblPlayerProjectiles[source] = 1;
end
end
end
addEventHandler("onPlayerProjectileCreation", root, clientCreateProjectile);



-- https://wiki.multitheftauto.com/wiki/OnExplosion
-- gets triggered when an explosion occurs, either via server script or client sync packet
function clientCreateExplosion(fPX, fPY, fPZ, iType)
if(isElement(source)) then
if(getElementType(source) == "player") then
if(tblRegularExplosions[source]) then
tblRegularExplosions[source] = tblRegularExplosions[source] + 1;
else
tblRegularExplosions[source] = 1;
end
end
end
end
addEventHandler("onExplosion", root, clientCreateExplosion);



-- https://wiki.multitheftauto.com/wiki/OnVehicleExplode
-- gets triggered when a vehicle explodes, either via server script or client sync packet
function clientCreateVehicleExplosion(bWithExplosion, uPlayer)
if(isElement(uPlayer)) then
if(tblVehicleExplosions[uPlayer]) then
tblVehicleExplosions[uPlayer] = tblVehicleExplosions[uPlayer] + 1;
else
tblVehicleExplosions[uPlayer] = 1;
end
end
end
addEventHandler("onVehicleExplode", root, clientCreateVehicleExplosion);



-- setup a timer with specified interval above and check if any client sent too many sync packets in the given time
-- thresholds need to be adjusted for your need and actions taken!
setTimer(function()
for uPlayer, iCounter in pairs(tblPlayerProjectiles) do
if(iCounter >= iPlayerProjectileThreshold) then
logViolation(uPlayer, "Exceeded projectile threshold "..tostring(iPlayerProjectileThreshold).." - Count: "..tostring(iCounter));
end
end

for uPlayer, iCounter in pairs(tblRegularExplosions) do
if(iCounter >= iRegularExplosionThreshold) then
logViolation(uPlayer, "Exceeded regular explosions threshold "..tostring(iRegularExplosionThreshold).." - Count: "..tostring(iCounter));
end
end

for uPlayer, iCounter in pairs(tblVehicleExplosions) do
if(iCounter >= iVehicleExplosionThreshold) then
logViolation(uPlayer, "Exceeded vehicle explosions threshold "..tostring(iVehicleExplosionThreshold).." - Count: "..tostring(iCounter));
end
end

tblPlayerProjectiles = {};
tblRegularExplosions = {};
tblVehicleExplosions = {};

end, iExplosionCheckInterval, 0);
16 changes: 16 additions & 0 deletions [admin]/security/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- checks if a player nickname is valid in terms of length and ascii chars
function isPlayerNameValid(strPlayerName)
if(not strPlayerName) then return false end;
if(not tostring(strPlayerName)) then return false end;
if(#strPlayerName == 0) then return false end;
if(#strPlayerName > 22) then return false end;

for i = 1, #strPlayerName do
local strChar = strPlayerName:sub(i, i);
local iCharByte = strChar:byte();

if(iCharByte < 33 or iCharByte > 126) then return false end;
end

return true;
end
Loading