diff --git a/Moonlight/App/Helpers/StringHelper.cs b/Moonlight/App/Helpers/StringHelper.cs index bbcf33bb..a8834c21 100644 --- a/Moonlight/App/Helpers/StringHelper.cs +++ b/Moonlight/App/Helpers/StringHelper.cs @@ -54,4 +54,37 @@ public static class StringHelper return input.Substring(0, halfLength); } + + public static bool EndsInOneOf(string suffix, IEnumerable strings) + { + foreach (string str in strings) + { + if (suffix.EndsWith(str)) + { + return true; + } + } + + return false; + } + + public static bool ContainsOneOf(string textToSearch, IEnumerable strings, out string foundText) + { + foreach (string str in strings) + { + if (textToSearch.Contains(str)) + { + foundText = str; + return true; + } + } + + foundText = ""; + return false; + } + + public static bool ContainsOneOf(string textToSearch, IEnumerable strings) + { + return ContainsOneOf(textToSearch, strings, out _); + } } \ No newline at end of file diff --git a/Moonlight/App/MalwareScans/BadScriptsScan.cs b/Moonlight/App/MalwareScans/BadScriptsScan.cs new file mode 100644 index 00000000..d349b789 --- /dev/null +++ b/Moonlight/App/MalwareScans/BadScriptsScan.cs @@ -0,0 +1,74 @@ +using Moonlight.App.Database.Entities; +using Moonlight.App.Helpers; +using Moonlight.App.Models.Misc; +using Moonlight.App.Services; + +namespace Moonlight.App.MalwareScans; + +public class BadScriptsScan : MalwareScan +{ + public override string Name => "BadScripts Scan"; + public override string Description => "This scanner tries to find scripts like proxies or other bad stuff"; + public async override Task Scan(Server server, IServiceProvider serviceProvider) + { + var serverService = serviceProvider.GetRequiredService(); + var fileAccess = await serverService.CreateFileAccess(server, null!); + + string[] fileExtensions = + { + ".py", + ".js", + ".json", + ".txt", + ".sh", + ".env", + ".md" + }; + + string[] badWords = + { + "cloudscraper", + "shadowsocks", + "karma-ddos", + "quake", + "nuked by", + "nuke bot", + "t-e-s-tweb", + "nezha", + "rblxwild.com", + "proxyscrape", + "vless://", + "vmess://", + "trojan://", + "shadowrocket", + "urfate/afk-bot", + "token vc spammer", + "pretreer.com", + "madfutters.com", + "ultrafut", + "selfcord.py" + }; + + var files = await fileAccess.Ls(); + var filteredFiles = files.Where(x => + StringHelper.EndsInOneOf(x.Name, fileExtensions)); + + foreach (var file in filteredFiles) + { + var content = await fileAccess.Read(file); + var processableContent = content.ToLower(); + + if (StringHelper.ContainsOneOf(processableContent, badWords, out string foundText)) + { + return new() + { + Title = "Software which is not allowed", + Description = $"Found bad word in script '{file.Name}': '{foundText}'", + Author = "Marcel Baumgartner" + }; + } + } + + return null; + } +} \ No newline at end of file diff --git a/Moonlight/App/MalwareScans/DiscordNukeScan.cs b/Moonlight/App/MalwareScans/DiscordNukeScan.cs deleted file mode 100644 index 2fa0f8fc..00000000 --- a/Moonlight/App/MalwareScans/DiscordNukeScan.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Moonlight.App.Database.Entities; -using Moonlight.App.Models.Misc; -using Moonlight.App.Services; - -namespace Moonlight.App.MalwareScans; - -public class DiscordNukeScan : MalwareScan -{ - public override string Name => "Discord nuke"; - public override string Description => "Discord nuke bot detector"; - public override async Task Scan(Server server, IServiceProvider serviceProvider) - { - var serverService = serviceProvider.GetRequiredService(); - var access = await serverService.CreateFileAccess(server, null!); - - var files = await access.Ls(); - var filteredFiles = files.Where(x => - x.Name.EndsWith(".py") || - x.Name.EndsWith(".js") || - x.Name.EndsWith(".json") || - x.Name.EndsWith(".env")); - - foreach (var file in filteredFiles) - { - var content = await access.Read(file); - var filteredContent = content.ToLower(); - - if (filteredContent.Contains("quake") || - filteredContent.Contains("nuked by") || - filteredContent.Contains("nuke bot") || - (filteredContent.Contains("fucked by") && filteredContent.Contains("nuke"))) // fucked by in context with nuke - { - return new() - { - Title = "Discord nuke bot", - Description = "Found suspicious content which may indicate there is a nuke bot running", - Author = "Marcel Baumgartner" - }; - } - - if (files.Any(x => x.Name == "nukes.json")) - { - return new() - { - Title = "Discord nuke bot", - Description = "Found suspicious content which may indicate there is a nuke bot running", - Author = "Marcel Baumgartner" - }; - } - } - - return null; - } -} \ No newline at end of file diff --git a/Moonlight/App/MalwareScans/MinerScan.cs b/Moonlight/App/MalwareScans/MinerScan.cs deleted file mode 100644 index 65ea6c4d..00000000 --- a/Moonlight/App/MalwareScans/MinerScan.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Moonlight.App.Database.Entities; -using Moonlight.App.Models.Misc; -using Moonlight.App.Services; - -namespace Moonlight.App.MalwareScans; - -public class MinerScan : MalwareScan -{ - public override string Name => "Miner (NEZHA)"; - public override string Description => "Probably a miner"; - public override async Task Scan(Server server, IServiceProvider serviceProvider) - { - var serverService = serviceProvider.GetRequiredService(); - - var access = await serverService.CreateFileAccess(server, null!); - var files = await access.Ls(); - - foreach (var file in files.Where(x => x.IsFile && (x.Name.EndsWith(".sh") || x.Name.EndsWith(".yml")) || x.Name == "bed")) - { - var content = await access.Read(file); - - if (content.ToLower().Contains("nezha")) - { - return new() - { - Title = "Miner", - Description = "Miner start script (NEZHA)", - Author = "Marcel Baumgartner" - }; - } - } - - return null; - } -} \ No newline at end of file diff --git a/Moonlight/App/MalwareScans/ProxyScan.cs b/Moonlight/App/MalwareScans/ProxyScan.cs deleted file mode 100644 index f6d26d76..00000000 --- a/Moonlight/App/MalwareScans/ProxyScan.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Moonlight.App.Database.Entities; -using Moonlight.App.Models.Misc; -using Moonlight.App.Services; - -namespace Moonlight.App.MalwareScans; - -public class ProxyScan : MalwareScan -{ - public override string Name => "Proxy software"; - public override string Description => "Software to use nodes as a proxy"; - public override async Task Scan(Server server, IServiceProvider serviceProvider) - { - var serverService = serviceProvider.GetRequiredService(); - var access = await serverService.CreateFileAccess(server, null!); - - var files = await access.Ls(); - - foreach (var file in files.Where(x => x.Name.EndsWith(".sh"))) - { - var fileContent = await access.Read(file); - var processableContent = fileContent.ToLower(); - - if (processableContent.Contains("t-e-s-tweb")) - { - return new MalwareScanResult() - { - Title = "Proxy software", - Description = "Software to use nodes as a proxy", - Author = "Marcel Baumgartner" - }; - } - } - - return null; - } -} \ No newline at end of file diff --git a/Moonlight/App/MalwareScans/SelfBotCodeScan.cs b/Moonlight/App/MalwareScans/SelfBotCodeScan.cs deleted file mode 100644 index 77b6a6a6..00000000 --- a/Moonlight/App/MalwareScans/SelfBotCodeScan.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Moonlight.App.Database.Entities; -using Moonlight.App.Models.Misc; -using Moonlight.App.Services; - -namespace Moonlight.App.MalwareScans; - -public class SelfBotCodeScan : MalwareScan -{ - public override string Name => "Selfbot code scan"; - public override string Description => "This scan is a simple selfbot code scan provided by moonlight"; - - public override async Task Scan(Server server, IServiceProvider serviceProvider) - { - var serverService = serviceProvider.GetRequiredService(); - var access = await serverService.CreateFileAccess(server, null!); - var fileElements = await access.Ls(); - - foreach (var script in fileElements.Where(x => x.Name.EndsWith(".py") && x.IsFile)) - { - var rawScript = await access.Read(script); - - if (rawScript.Contains("https://discord.com/api") && !rawScript.Contains("https://discord.com/api/oauth2") && !rawScript.Contains("https://discord.com/api/webhook") || rawScript.Contains("https://rblxwild.com")) //TODO: Export to plugins, add regex for checking - { - return new MalwareScanResult - { - Title = "Potential selfbot", - Description = $"Suspicious script file: {script.Name}", - Author = "Marcel Baumgartner" - }; - } - } - - return null; - } -} \ No newline at end of file diff --git a/Moonlight/App/MalwareScans/SelfBotScan.cs b/Moonlight/App/MalwareScans/SelfBotScan.cs deleted file mode 100644 index b015b1ba..00000000 --- a/Moonlight/App/MalwareScans/SelfBotScan.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Moonlight.App.Database.Entities; -using Moonlight.App.Models.Misc; -using Moonlight.App.Services; - -namespace Moonlight.App.MalwareScans; - -public class SelfBotScan : MalwareScan -{ - public override string Name => "Selfbot Scan"; - public override string Description => "This scan is a simple selfbot scan provided by moonlight"; - - public override async Task Scan(Server server, IServiceProvider serviceProvider) - { - var serverService = serviceProvider.GetRequiredService(); - var access = await serverService.CreateFileAccess(server, null!); - var fileElements = await access.Ls(); - - if (fileElements.Any(x => x.Name == "tokens.txt")) - { - return new MalwareScanResult - { - Title = "Found SelfBot", - Description = "Detected suspicious 'tokens.txt' file which may contain tokens for a selfbot", - Author = "Marcel Baumgartner" - }; - } - - return null; - } -} \ No newline at end of file diff --git a/Moonlight/App/Services/MalwareScanService.cs b/Moonlight/App/Services/MalwareScanService.cs index 8fd36349..0481b450 100644 --- a/Moonlight/App/Services/MalwareScanService.cs +++ b/Moonlight/App/Services/MalwareScanService.cs @@ -20,13 +20,9 @@ public class MalwareScanService { var defaultScans = new List { - new SelfBotScan(), new MinerJarScan(), - new SelfBotCodeScan(), new FakePlayerPluginScan(), - new MinerScan(), - new ProxyScan(), - new DiscordNukeScan() + new BadScriptsScan() }; var scans = await PluginService.BuildMalwareScans(defaultScans.ToArray());