From e74c80e5c519099708cff4ebaed80c43a5d73cd6 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Mon, 29 Oct 2018 01:43:35 +1100 Subject: [PATCH 1/3] bot-attack-module --- gamemodes/irresistible/security.pwn | 3 +- gamemodes/sf-cnr.pwn | 68 ++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/gamemodes/irresistible/security.pwn b/gamemodes/irresistible/security.pwn index 694a7f7..3005998 100644 --- a/gamemodes/irresistible/security.pwn +++ b/gamemodes/irresistible/security.pwn @@ -119,8 +119,9 @@ hook OnPlayerDisconnect( playerid, reason ) #if defined DEBUG_MODE // aims to clear the banned from the server bug - public OnIncomingConnection( playerid, ip_address[ ], port ) { + hook OnIncomingConnection( playerid, ip_address[ ], port ) { SendRconCommand( "reloadbans" ); + return 1; } #endif diff --git a/gamemodes/sf-cnr.pwn b/gamemodes/sf-cnr.pwn index dc04397..8a637d5 100644 --- a/gamemodes/sf-cnr.pwn +++ b/gamemodes/sf-cnr.pwn @@ -16,7 +16,7 @@ #pragma option -d3 #pragma dynamic 7200000 -#define DEBUG_MODE +//#define DEBUG_MODE #if defined DEBUG_MODE #pragma option -d3 @@ -1275,6 +1275,52 @@ public OnNpcConnect( npcid ) return Kick( npcid ), 1; } +new g_LastConnection = 0; +new g_ConnectionSpamCount = 0; + +public OnIncomingConnection( playerid, ip_address[ ], port ) { + + new player_name[ 24 ]; + new player_version[ 24 ]; + new player_ip[ 16 ]; + new player_ping = GetPlayerPing( playerid ); + new netstats[ 500 ]; + new playerserial[ 45 ]; + + GetPlayerName( playerid, player_name, sizeof( player_name ) ); + GetPlayerVersion( playerid, player_version, sizeof( player_version ) ); + GetPlayerIp( playerid, player_ip, sizeof( player_ip ) ); + GetPlayerNetworkStats( playerid, netstats, sizeof( netstats ) ); + gpci( playerid, playerserial, sizeof( playerserial ) ); + + if ( ! ( 0 <= playerid < MAX_PLAYERS ) ) { + BlockIpAddress( ip_address, 60000 ); // block id if invalid ip + } + + // script will only work if the server is online for more than 10 minutes + if ( g_iTime - g_ServerUptime > 300 ) + { + new + time = GetTickCount( ); + + switch( time - g_LastConnection ) + { + case 0 .. 500: + { + if ( ++ g_ConnectionSpamCount >= 5 ) + { + BlockIpAddress( ip_address, 60 * 1000 ); + printf( "Name:%s(%d)\nVersion:%s\nIP:%s / %s:%d\nNetwork Stats:{%s}\nPing:%d\nNPC:%d\nGPCI:%s", player_name, playerid, player_version, player_ip, ip_address, port, netstats, player_ping, IsPlayerNPC( playerid ), playerserial ); + return 1; + } + } + default: g_ConnectionSpamCount = 0; + } + g_LastConnection = time; + } + return 1; +} + public OnPlayerConnect( playerid ) { static @@ -1286,6 +1332,26 @@ public OnPlayerConnect( playerid ) if ( textContainsIP( ReturnPlayerName( playerid ) ) ) return Kick( playerid ), 1; + if ( g_iTime - g_ServerUptime > 300 ) + { + new player_name[ 24 ]; + new player_version[ 24 ]; + new player_ip[ 16 ]; + new player_ping = GetPlayerPing( playerid ); + new netstats[ 500 ]; + new playerserial[ 45 ]; + + GetPlayerName( playerid, player_name, sizeof( player_name ) ); + GetPlayerVersion( playerid, player_version, sizeof( player_version ) ); + GetPlayerIp( playerid, player_ip, sizeof( player_ip ) ); + GetPlayerNetworkStats( playerid, netstats, sizeof( netstats ) ); + gpci( playerid, playerserial, sizeof( playerserial ) ); + + if ( strlen( player_name ) >= 16 ) { + printf( "Name:%s(%d)\nVersion:%s\nIP:%s\nNetwork Stats:{%s}\nPing:%d\nNPC:%d\nGPCI:%s", player_name, playerid, player_version, player_ip, netstats, player_ping, IsPlayerNPC( playerid ), playerserial ); + } + } + // Ultra fast queries... format( Query, sizeof( Query ), "SELECT * FROM `BANS` WHERE (`NAME`='%s' OR `IP`='%s') AND `SERVER`=0 LIMIT 0,1", mysql_escape( ReturnPlayerName( playerid ) ), mysql_escape( ReturnPlayerIP( playerid ) ) ); mysql_function_query( dbHandle, Query, true, "OnPlayerBanCheck", "i", playerid ); From d03591a9a24aea748ff4fbf9e6065762fa16ffbd Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Mon, 29 Oct 2018 02:12:09 +1100 Subject: [PATCH 2/3] move bot attack code into its own module --- .../irresistible/anticheat/_anticheat.pwn | 1 + .../irresistible/anticheat/bot_attack.pwn | 57 ++++++++++++++++ gamemodes/sf-cnr.pwn | 66 ------------------- 3 files changed, 58 insertions(+), 66 deletions(-) create mode 100644 gamemodes/irresistible/anticheat/bot_attack.pwn diff --git a/gamemodes/irresistible/anticheat/_anticheat.pwn b/gamemodes/irresistible/anticheat/_anticheat.pwn index 8014a0c..0825fd7 100644 --- a/gamemodes/irresistible/anticheat/_anticheat.pwn +++ b/gamemodes/irresistible/anticheat/_anticheat.pwn @@ -158,6 +158,7 @@ stock AC_SetPlayerSpawned( playerid, bool: spawned ) { /* ** Modules (remove to disable) ** */ #include "irresistible\anticheat\money.pwn" +#include "irresistible\anticheat\bot_attack.pwn" #include "irresistible\anticheat\hitpoints.pwn" #include "irresistible\anticheat\weapon.pwn" #include "irresistible\anticheat\carmod_checker.pwn" diff --git a/gamemodes/irresistible/anticheat/bot_attack.pwn b/gamemodes/irresistible/anticheat/bot_attack.pwn new file mode 100644 index 0000000..197342a --- /dev/null +++ b/gamemodes/irresistible/anticheat/bot_attack.pwn @@ -0,0 +1,57 @@ +/* + * Irresistible Gaming (c) 2018 + * Developed by Lorenc Pekaj + * Module: anticheat\bot_attack.pwn + * Purpose: mitigates bot attacks with random IP addresses + */ + +/* ** Includes ** */ +#include < YSI\y_hooks > + +/* ** Constants ** */ +static const BOT_ATTACK_BLOCK_TIME = 120000; // 2 minutes + +/* ** Variables ** */ +static stock botattack_ServerInitTS = 0; +static stock botattack_LastConnection = 0; +static stock botattack_ConnectionSpamCount = 0; + +/* ** Hooks ** */ +hook OnScriptInit( ) +{ + botattack_ServerInitTS = gettime( ); + return 1; +} + +hook OnIncomingConnection( playerid, ip_address[ ], port ) +{ + // block id if invalid player ID ... otherwise our bots go + if ( ! ( 0 <= playerid < MAX_PLAYERS ) ) { + BlockIpAddress( ip_address, BOT_ATTACK_BLOCK_TIME ); + } + + new + current_time = gettime( ); + + // script will only work if the server is online for more than 5 minutes + if ( current_time - botattack_ServerInitTS >= 300 ) + { + // if the last connection was within 2 seconds + if ( current_time - botattack_LastConnection <= 2 ) + { + // and we had more than 5 connections in this interval + if ( ++ botattack_ConnectionSpamCount >= 5 ) + { + BlockIpAddress( ip_address, BOT_ATTACK_BLOCK_TIME ); + return 1; + } + } + else + { + botattack_ConnectionSpamCount = 0; + } + + botattack_LastConnection = current_time; + } + return 1; +} diff --git a/gamemodes/sf-cnr.pwn b/gamemodes/sf-cnr.pwn index 8a637d5..26d84f9 100644 --- a/gamemodes/sf-cnr.pwn +++ b/gamemodes/sf-cnr.pwn @@ -1275,52 +1275,6 @@ public OnNpcConnect( npcid ) return Kick( npcid ), 1; } -new g_LastConnection = 0; -new g_ConnectionSpamCount = 0; - -public OnIncomingConnection( playerid, ip_address[ ], port ) { - - new player_name[ 24 ]; - new player_version[ 24 ]; - new player_ip[ 16 ]; - new player_ping = GetPlayerPing( playerid ); - new netstats[ 500 ]; - new playerserial[ 45 ]; - - GetPlayerName( playerid, player_name, sizeof( player_name ) ); - GetPlayerVersion( playerid, player_version, sizeof( player_version ) ); - GetPlayerIp( playerid, player_ip, sizeof( player_ip ) ); - GetPlayerNetworkStats( playerid, netstats, sizeof( netstats ) ); - gpci( playerid, playerserial, sizeof( playerserial ) ); - - if ( ! ( 0 <= playerid < MAX_PLAYERS ) ) { - BlockIpAddress( ip_address, 60000 ); // block id if invalid ip - } - - // script will only work if the server is online for more than 10 minutes - if ( g_iTime - g_ServerUptime > 300 ) - { - new - time = GetTickCount( ); - - switch( time - g_LastConnection ) - { - case 0 .. 500: - { - if ( ++ g_ConnectionSpamCount >= 5 ) - { - BlockIpAddress( ip_address, 60 * 1000 ); - printf( "Name:%s(%d)\nVersion:%s\nIP:%s / %s:%d\nNetwork Stats:{%s}\nPing:%d\nNPC:%d\nGPCI:%s", player_name, playerid, player_version, player_ip, ip_address, port, netstats, player_ping, IsPlayerNPC( playerid ), playerserial ); - return 1; - } - } - default: g_ConnectionSpamCount = 0; - } - g_LastConnection = time; - } - return 1; -} - public OnPlayerConnect( playerid ) { static @@ -1332,26 +1286,6 @@ public OnPlayerConnect( playerid ) if ( textContainsIP( ReturnPlayerName( playerid ) ) ) return Kick( playerid ), 1; - if ( g_iTime - g_ServerUptime > 300 ) - { - new player_name[ 24 ]; - new player_version[ 24 ]; - new player_ip[ 16 ]; - new player_ping = GetPlayerPing( playerid ); - new netstats[ 500 ]; - new playerserial[ 45 ]; - - GetPlayerName( playerid, player_name, sizeof( player_name ) ); - GetPlayerVersion( playerid, player_version, sizeof( player_version ) ); - GetPlayerIp( playerid, player_ip, sizeof( player_ip ) ); - GetPlayerNetworkStats( playerid, netstats, sizeof( netstats ) ); - gpci( playerid, playerserial, sizeof( playerserial ) ); - - if ( strlen( player_name ) >= 16 ) { - printf( "Name:%s(%d)\nVersion:%s\nIP:%s\nNetwork Stats:{%s}\nPing:%d\nNPC:%d\nGPCI:%s", player_name, playerid, player_version, player_ip, netstats, player_ping, IsPlayerNPC( playerid ), playerserial ); - } - } - // Ultra fast queries... format( Query, sizeof( Query ), "SELECT * FROM `BANS` WHERE (`NAME`='%s' OR `IP`='%s') AND `SERVER`=0 LIMIT 0,1", mysql_escape( ReturnPlayerName( playerid ) ), mysql_escape( ReturnPlayerIP( playerid ) ) ); mysql_function_query( dbHandle, Query, true, "OnPlayerBanCheck", "i", playerid ); From ee1e436258138cdb03b21671c0958aa7d3cace42 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Mon, 29 Oct 2018 02:13:47 +1100 Subject: [PATCH 3/3] remove debug --- gamemodes/sf-cnr.pwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamemodes/sf-cnr.pwn b/gamemodes/sf-cnr.pwn index 26d84f9..dc04397 100644 --- a/gamemodes/sf-cnr.pwn +++ b/gamemodes/sf-cnr.pwn @@ -16,7 +16,7 @@ #pragma option -d3 #pragma dynamic 7200000 -//#define DEBUG_MODE +#define DEBUG_MODE #if defined DEBUG_MODE #pragma option -d3