---------------------------------------------------------------------- -- deflood version 4.x ---------------------------------------------------------------------- ---- the script only kicks by default altho the message says banned. ---- change this if you want it 2 really ban. ---- check my website reguarly, there are more updates then you think. ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- pre V4.x things ----- -- only filter chat for unreged users. -- bounch the flood msg back to the sender. -- now kicks after x times (user is warned). -- added phatty's ban on description. -- added chilla's script against the myInfo flooder. -- added share check thx psf8500. -- added choise on were to show the msg's to the ops (own window or opchat). -- added test by removing numbers from the msg, so chat flooders can't count in there msg. -- added detection for user flooders which show a number behind the tag. -- added filter for me mode. -- added filter so away msg don't get seen as flooding. ---------------------------------------------------------------------- -- V4+ ----- -- added filter for crimson. -- added filter for omega. -- added filter for midnight. -- changed logs now also store the ip's of the banned users. -- thx to ruri_ruri for helping on this new version of deflood, ---------------------------------------------------------------------- -- V4.1 ----- -- fixed strfind error. ---------------------------------------------------------------------- -- V4.2 ----- -- added direct kick/ban for the pm/chat flooders. -- small optimization on the description table. ---------------------------------------------------------------------- -- V4.3 ----- -- added protection against GetNickList floods (thx to psf8500). -- added protection against fake MyInfo's with random chars (thx to psf8500). -- added protection against fake IP's on ConnectToMe (thx to psf8500). -- changed removed the need for 2 versions of deflood, mode can be set from the script now. -- changed made it optional to set what to do with flooders (no need 2 mod the script anymore). ---------------------------------------------------------------------- -- V4.3.1 ----- -- changed the amount of times a user can do $GetNickList can be set from the config. -- added table with imune IP's on the fake $ConnectToMe's (some hubowners need this). ---------------------------------------------------------------------- -- V4.3.2 ----- -- changed the $ConnectToMe has now only the option to do a timeban of x minutes. -- instead of showing "you banned" it gives the correct IP and links to some site's -- with info about how to setup active mode while being behind a router. ---------------------------------------------------------------------- -- V4.3.3 ----- -- changed the $ConnectToMe check now disconnects private ip ranges, and tells them the right IP to use -- changed reason msg send to the kicked/banned users matched the kick/ban type. ---------------------------------------------------------------------- -- V4.3.4 ----- -- fixed bug on not kicking/banning (thx reefa) -- fixed bug on level checking (thx reefa) ---------------------------------------------------------------------- -- V4.3.5 ----- -- quick fix for the !me flooder from TE. ---------------------------------------------------------------------- -- V4.3.6 ----- -- added filter for the scrolling statusbar flooder (thx uffetjur/plop/sUiCiDeMAniC). ---------------------------------------------------------------------- -- V4.4 ----- -- added filter for the OpZone hub flooder. -- this way filters all flooders which use a new connection for every chat/pm msg. ---------------------------------------------------------------------- -- V4.4.1 ----- -- fixed conflict on double used table (tIPs changed to tUIPs on the hammer check). ---------------------------------------------------------------------- -- V4.4.2 ----- -- removed the cleaning of the table in UserDisconnected on the hammer. ---------------------------------------------------------------------- -- V4.4.3 ----- -- added bad share table. ---------------------------------------------------------------------- -- V4.5 ----- -- added filter for the search flooder. (thx uffetjur) -- changed chatcheck so it's open to accept tables from all kinds of checks (future work). -- added "anime & music" to the description table. -- added the 666GB share to the badshare table. -- done some cleaning. -- added comments all over the script. -- found a cleaning lady willing to work for free for you ppl. ---------------------------------------------------------------------- -- V4.5.1 ----- -- changed iMaxCon from 10 to 5, so the yhub flooder in ruri's OMEGA flooder is also filtered. ---------------------------------------------------------------------- -- V4.5.2 ----- -- fixed error on incorrect IP's (forgotten numbers). ---------------------------------------------------------------------- -- V4.5.3 ----- -- fixed. error on the share check (index is nil). -- added. warning on the search filter, starts on half the max amount. -- added. level check on ConnectToMe, not checked levels are only disconnected. -- added. level/name system on notifications. -- changed. log file handling, new file every day. -- changed. optimized the kick/ban routine a bit -- changed. cleaned up the config part. hope it's easyer to read now ---------------------------------------------------------------------- -- V4.5.4 ----- -- fixed disconnect mode not working (thx CommanderKeen). -- added filter for nemesis (thx some mystery guy). ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- paybacks a biotch!! -- enjoy. plop -- http://www.plop.nl ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- Config part. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- name of the bot. Bot = "deflood" ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- maximum msg's stored from the user. iMaxStored = 6 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- maximum amount of warnings before it bans for chat flooding. iMaxWarn = 3 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- location/name of the log file. fFile = "flood.log" fFolder = "logs" ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- filter levels. use 1 for everything but OP's, nil for the table with level numbers. iMode = 1 tMode = { [-1] = 1 } ---------------------------------------------------------------------- ---------------------------------------------------------------------- ------- do what to flooders. ---- use nil for disconnect, 1 for a kick, 2 for a ban, 3 for a tempban, 4 for a timeban. iKill = nil ---- if timeban then how many minutes. iTimeBan = 15 ---- time the tempban on bad IP's in the dc active setup should last ---- (don't make it 2 long, mostly this check hits on bad settings but it could be a flooder ---- but keep it above 5 so the automatic reconnect from dc++ doesn't make it flood your opchat/logs). iConnect = 8 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- maximum amount of times an ip can connect per xx seconds (table flush timer). iMaxCon = 5 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- the table for banning by description (["search string"] = number). tDesc = { ["Ruri_Ruri"]=1, ["R u r i_ R u r i "]=2, ["TEAMELITE"]=3, ["F8X0R"]=4, ["KNUCKLES"]=5, ["OPZONE"]=6, ["K-N-U-C-K-L-E-S"]=7, ["Meka_Meka"]=8, ["O-M-E-G-A"]=9, ["OMEGA"]=10, ["HaX0R"]=11, ["HaXOR"]=12, ["Anime&Music"]=13 } ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- name of the opchat so the output of this script shows up there instead of it's own window. ---- comment this for own window (aka place -- before it like this text has). sOpchat = "-OPChat-" -- fill in the name here if you use a scripted opchat. --sOpchat = frmHub:GetOpChatName() -- uncomment this and make the above a comment if you use the ptokax build-in opchat. --sOpchat = nil ---- uncomment this if you want deflood to show the notification in it's own window. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- table with user levels or names of seperate users which should see the notifications from defloods kicks/bans. --tNotUs = nil -- uncomment this for the old style (all op's) tNotUs = { [0] = 1, -- level number. [1] = 1, -- level number. ["plop2"] = 1 -- name of the user. } ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- filter away msg's (use nil to disable, 1 to enable). AWAY = 1 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- don't check the next IP's on fake $ConnectToMe's. ---- (for hub owners who are behind a NAT router) tIPs = { ["127.0.0.1"] = 1, ["127.0.0.2"] = 1 } ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- known bad shares from flooders. tBadShare = { [166430355311] = 1, [715112427375] = 2, [24772828362] = 3, [74324433643] = 4 } ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- max amount of times someone can do $GetNickList before deflood treads it as a flooder. iMaxGetNick = 5 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- max amount of the searches a user can do (flush interval is halved here). iMaxSrch = 4 ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- explain the script what seconds, minutes, hours and day's are. iSec = 1000 iMin = 60 * iSec iHour = 60 * iMin iDay = 24 * iHour ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---- time between table flushes. ---- 10 * sec == 10 sec memory ---- 2 * hour == 2 hour memory iFlushTime = 10 * iSec ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- end of the config part. ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- main script starts here. ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- don't even think about changing the next table (private ip ranges in decimal format). tPriv = { [3232235520] = 3232301055, [2886729728] = 2887778303, [167772160] = 184549375 } ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- the tables needed. tMsg= {} tSearch = {} tShare = {} tNames = {} tMyInfo = {} tGetNick = {} tUIPs = {} ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- starting up the script. function Main() -- setting script mode. frmHub:EnableFullData(1) -- regging the bot. frmHub:RegBot(Bot) -- setting the timer. SetTimer(iFlushTime) StartTimer() -- pre-processing the description table. tDesc2 = {} for i,v in tDesc do local a = gsub(gsub(gsub(i, "-",""), " ", ""), " ","") a = strlower(a) tDesc2[a]=1 end tDesc = nil iHalfSrch = iMaxSrch / 2 end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- the flush timer. function OnTimer() -- flushing the tables. tMsg= nil tShare = nil tNames = nil tMyInfo = nil tGetNick = nil tUIPs = nil -- the flush with halved interval if (iSC or 0) > 1 then tSearch = nil -- call the cleaning lady Clear() tSearch = {} else iSC = (iSC or 0) + 1 -- call the cleaning lady Clear() end -- building the empty tables tMsg= {} tShare = {} tNames = {} tMyInfo = {} tGetNick = {} tUIPs = {} end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- the kick/ban stuff. function ByeBye(user) if iKill and tByeBye[iKill] then call(tByeBye[iKill], {user}) else user:SendPM(Bot, "You are now disconnected on suspision of using a hub flooder!!|") user:Disconnect() end return 1 end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- the table with the kick/ban routines. tByeBye = { [1] = function(user) user:SendPM(Bot, "You are now kicked on suspision of using a hub flooder!!|") user:Kick() end, [2] = function(user) user:SendPM(Bot, "You are now banned on suspision of using a hub flooder!!|") user:Ban() end, [3] = function(user) user:SendPM(Bot, "You are now temp banned on suspision of using a hub flooder!!|") user:TempBan() end, [4] = function(user) user:SendPM(Bot, "You are now time banned on suspision of using a hub flooder for the next "..iTimeBan.." minutes!!|") user:TimeBan(iTimeBan) end } ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- level check. function CheckLevel(user) if iMode then return user.bOperator else return not tMode[user.iProfile] end end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- share check. function CheckShare(user) if user.sMyInfoString then local i,j,temp = strfind(user.sMyInfoString, "%$(%d+)%$%|*$") if temp and tBadShare[temp] then return 1 end end end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- the cleaning lady. function Clear() collectgarbage() flush() end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- main filters. function DataArrival(user, data) -- bad share. if user.sMyInfoString then local i,j,temp = strfind(user.sMyInfoString, "%$(%d+)%$%|*$") if temp and tonumber(temp) then temp = tonumber(temp) if tBadShare[temp] then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (badshare table)" StoreLog(user.sName, msg) return ByeBye(user) end end end -- me/hard flood msg filter. if strfind(data, "€AM€LiT€ OWN€D YOU") then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (!me/hard flooder)" StoreLog(user.sName, msg) return ByeBye(user) -- mainchat msg. elseif( strsub(data, 1, 1) == "<" ) then if not CheckLevel(user) then data = strsub(data, 1, (strlen(data)-1)) s,e,nick, data = strfind(data, "^(%b<>)(.+)") if nick == nil then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (!me flooder - nemesis)" StoreLog(user.sName, msg) return ByeBye(user) end nick = GetItemByName(strsub(nick, 2, -2)) if nick == nil then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (fake nick version)" StoreLog(user.sName, msg) return ByeBye(user) elseif ChatCheck(user, data,tMsg) then return 1 end end -- me filter msg. elseif( strsub(data, 1, 1) == "*" ) then if not CheckLevel(user) then data = strsub(data, 1, (strlen(data)-1)) s,e,data = strfind(data, "^%*%s*(.+)") if ChatCheck(user, data, tMsg) then return 1 end end -- pm filter msg. elseif(strsub(data, 1, 4) == "$To:") then if not CheckLevel(user) then data = strsub(data, 1, (strlen(data)-1)) s,e,data = strfind(data, "$%b<>(.+)") local t,c = gsub(data, "xXxX", "") if c >1 then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a client flooder!!" StoreLog(user.sName, msg) return ByeBye(user) elseif ChatCheck(user, data, tMsg) then return 1 end end -- search filter. elseif strsub(data, 1, 7) == "$Search" then if tSearch[user.sName] then tSearch[user.sName] = tSearch[user.sName] + 1 if tSearch[user.sName] > iMaxSrch then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a search flooder!!" StoreLog(user.sName, msg) return ByeBye(user) elseif tSearch[user.sName] > iHalfSrch then user:SendData(Bot, "Slow down your searching, you're close to getting banned.(search is dropped)") return 1 end else tSearch[user.sName] = 1 end -- GetNickList filter. elseif strsub(data, 1, 12) == "$GetNickList" then if tGetNick[user.sName] == nil then tGetNick[user.sName] = 1 else tGetNick[user.sName] = tGetNick[user.sName] +1 if tGetNick[user.sName] >= iMaxGetNick then tGetNick[user.sName] = nil msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (GetNickList flood)" StoreLog(user.sName, msg) return ByeBye(user) end end -- ConnectToMe filter. elseif strsub(data, 1, 12) == "$ConnectToMe" then local s,e,ip = strfind(data, "(%S+):%d+|$") if ip and tIPs[user.sIP] == nil then if ip ~= user.sIP then local s,e,dIP1,dIP2,dIP3,dIP4 = strfind(ip, "(%d+)%.(%d+)%.(%d+)%.(%d+)") if dIP1 and dIP2 and dIP3 and dIP4 then dIP1 = (tonumber(dIP1) * 16777216) + (tonumber(dIP2) *65536) + (tonumber(dIP3) * 256) + (tonumber(dIP4)) for a,b in tPriv do if dIP1 >= a and dIP1 <= b then user:SendPM(Bot, "You either left the IP box from your active settings empty or you placed a private IP in there by accident!\r\n".. "IP's like this will not resolve outside your local network, change it for "..user.sIP.."|") user:Disconnect() return 1 end end user:SendPM(Bot, "You have the wrong IP in the active settings from your DC client!!\r\n".. "You have set it to "..ip..", the IP you should have set it on is: "..user.sIP..".\r\n".. "For Safety reasons you are now banned for "..iConnect.." minutes\r\n".. "For more info about how to setup active mode you should look at the next website's:\r\n".. "Default router setup manual: ---> http://www.plop.nl/lua_tools/dc-active.zip\r\n".. "Specialized router manuals: ---> http://www.portforward.com\r\n".. "Official dc++ faq: ---> http://dcplusplus.sourceforge.net/faq/faq.php?display=faq&faqnr=11&catnr=2&prog=1&lang=en&onlynewfaq=1 |") msg = user.sName.." - "..user.sIP.." - "..date().." - time banned for a wrong ip in the $ConnectToMe, but this could be a hub flooder!! (bad/fake ConnectToMe)" StoreLog(user.sName, msg) if CheckLevel(user) then if iKill then user:TimeBan(iConnect) else user:Disconnect() end else user:Disconnect() end else user:SendPM(Bot, "An IP contains 4 numbers seperated by 3 dots. Your correct IP is "..user.sIP.."|") user:Disconnect() end return 1 end end -- MyInfo filter. elseif strsub(data, 1, 7) == "$MyINFO" then if tMyInfo[user.sName] then tMyInfo[user.sName] = tMyInfo[user.sName] +1 local t =(frmHub:GetUsersCount()+10) if tMyInfo[user.sName] >= t then tMyInfo[user.sName] = nil msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (myInfo flood)" StoreLog(user.sName, msg) return ByeBye(user) end else tMyInfo[user.sName] = 1 end -- bad share filter (same ending size). local i,j,temp = strfind(data, "$(%d+)%$") if temp then if strlen(temp) >= 11 then temp = strsub(temp, -11, -1) if tonumber(temp) == 99511627776 then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (share version)" StoreLog(user.sName, msg) return ByeBye(user) end end end -- bad tag filter. local _,_,tmp = strfind(data, "%b<>(%d+)%$") if tmp then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (tag version)" StoreLog(user.sName, msg) return ByeBye(user) end -- fake MyInfo flooder. local _,_,nick = strfind(data,"^%$MyINFO %$ALL (%S+)") if nick and (nick ~= user.sName) then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (myInfo version)" StoreLog((nick.." -"..user.sName), msg) nick = GetItemByName(nick) if nick then ByeBye(nick) end return ByeBye(user) end -- nil/counting nick filter. local name = gsub(user.sName, "%d", "") if strlen(name) == 0 then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (banned on nickname)" StoreLog(user.sName, msg) return ByeBye(user) end -- description filter. s,e,data = strfind(data, "%$ALL%s+%S+(.*)%b<>%$") if data then data = strlower(data) data = gsub(gsub(gsub(data, "-", ""), " ", ""), " ", "") for i,v in tDesc2 do local s,e,no = strfind(data, ".*("..i..").*") if no then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (banned on description)" StoreLog(user.sName, msg) return ByeBye(user) end end -- share match filter (also solves clones). local s,e,share = strfind(data, "$(%d+)%$") if share then if tShare[share] == nil then tShare[share] = 1 tNames[user.sName] = 1 elseif tNames[user.sName] == nil then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (banned on share match)" StoreLog(user.sName, msg) return ByeBye(user) end end end end end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- the repeating msg filter. function ChatCheck(user, data, Table) data = gsub(data, "[%s%d]", "") -- filter away msg's or not. if AWAY then s,e,away = strfind(data,"(%b<>)$") if away then return end end -- back to normal. local name = user.sName local count = 0 if Table[name] == nil then Table[name] = {} Table[name][1]=data return else for i=1,iMaxStored do if Table[name][i] then if data == Table[name][i] then if Table[name]["count"] == nil then user:SendPM(Bot, "Stop flooding you fool : "..data.."|") user:SendPM(Bot, "This is your 1st warning. After "..iMaxWarn.." you will be banned!!|") Table[name]["count"]=1 msg = user.sName.." - "..user.sIP.." - "..date().." - flood warning number: 1. msg was: "..data StoreLog(user.sName, msg) count = 1 return 1 else Table[name]["count"]=Table[name]["count"] +1 if Table[name]["count"] >= iMaxWarn then what = "You have been warned!! You are now banned for flooding the hub!!" msg = user.sName.." - "..user.sIP.." - "..date().." - now banned for flooding. msg was: "..data StoreLog(user.sName, msg) Table[name] = nil user:SendPM(Bot, what.."|") return ByeBye(user) else user:SendPM(Bot, "This is warning number "..Table[name]["count"]..". After "..iMaxWarn.." you will be banned!!|") msg = user.sName.." - "..user.sIP.." - "..date().." - flood warning number: "..Table[name]["count"]..". msg was: "..data StoreLog(user.sName, msg) return 1 end end end end end end -- cleaning the table. if count == 0 then local count2 = 0 for i=1,iMaxStored do if Table[name][i] then count2 = count2 +1 else break end end if count2 >= iMaxStored then for i=1,iMaxStored do if Table[name][i] ~= nil then local tmp = i+1 if Table[name][tmp] then Table[name][i] = Table[name][tmp] else Table[name][i]=data break end end end else count2 = count2 +1 Table[name][count2]=data end end end ---------------------------------------------------------------------- function NotOps(msg) if tNotUs then for a,b in tNotUs do if tonumber(a) then for c,d in GetUsersByProfile(GetProfileName(a)) do local usr = GetItemByName(d) if usr then if sOpchat then usr:SendPM(sOpchat, msg.."|") else usr:SendPM(Bot, msg.."|") end end end else if GetItemByName(a) then local usr = GetItemByName(a) if sOpchat then usr:SendPM(sOpchat, msg.."|") else usr:SendPM(Bot, msg.."|") end end end end else if sOpchat then SendPmToOps(sOpchat, msg.."|") else SendPmToOps(Bot, msg.."|") end end end ---------------------------------------------------------------------- -- write the log file. function StoreLog(nick, msg) local sDate = gsub(date("%x"), "%D", "-") appendto(fFolder.."/"..sDate.."-"..fFile) NotOps(msg) write(msg.."\n") writeto() msg = nil end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- check's done on entry. function NewUserConnected(user) -- bad share filter. if CheckShare(user) then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (badshare table)" StoreLog(user.sName, msg) return ByeBye(user) end -- hammer filter. if tUIPs[user.sIP] then tUIPs[user.sIP] = tUIPs[user.sIP] +1 if tUIPs[user.sIP] >= iMaxCon then msg = user.sName.." - "..user.sIP.." - "..date().." - banned for using a hub flooder!! (IP connected more then "..iMaxCon.."x within "..(iFlushTime / 1000).." seconds)" StoreLog(user.sName, msg) return ByeBye(user) end else tUIPs[user.sIP] = 1 end end ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- all done. ----------------------------------------------------------------------