Merge pull request #301 from Moonlight-Panel/NewBadScriptScan

Added new bad script scan in order to find reduce scan time
This commit is contained in:
Marcel Baumgartner 2023-09-05 01:24:20 +02:00 committed by GitHub
commit 707776f1ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 195 deletions

View file

@ -54,4 +54,37 @@ public static class StringHelper
return input.Substring(0, halfLength);
}
public static bool EndsInOneOf(string suffix, IEnumerable<string> strings)
{
foreach (string str in strings)
{
if (suffix.EndsWith(str))
{
return true;
}
}
return false;
}
public static bool ContainsOneOf(string textToSearch, IEnumerable<string> 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<string> strings)
{
return ContainsOneOf(textToSearch, strings, out _);
}
}

View file

@ -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<MalwareScanResult?> Scan(Server server, IServiceProvider serviceProvider)
{
var serverService = serviceProvider.GetRequiredService<ServerService>();
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;
}
}

View file

@ -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<MalwareScanResult?> Scan(Server server, IServiceProvider serviceProvider)
{
var serverService = serviceProvider.GetRequiredService<ServerService>();
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;
}
}

View file

@ -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<MalwareScanResult?> Scan(Server server, IServiceProvider serviceProvider)
{
var serverService = serviceProvider.GetRequiredService<ServerService>();
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;
}
}

View file

@ -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<MalwareScanResult?> Scan(Server server, IServiceProvider serviceProvider)
{
var serverService = serviceProvider.GetRequiredService<ServerService>();
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;
}
}

View file

@ -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<MalwareScanResult?> Scan(Server server, IServiceProvider serviceProvider)
{
var serverService = serviceProvider.GetRequiredService<ServerService>();
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;
}
}

View file

@ -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<MalwareScanResult?> Scan(Server server, IServiceProvider serviceProvider)
{
var serverService = serviceProvider.GetRequiredService<ServerService>();
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;
}
}

View file

@ -20,13 +20,9 @@ public class MalwareScanService
{
var defaultScans = new List<MalwareScan>
{
new SelfBotScan(),
new MinerJarScan(),
new SelfBotCodeScan(),
new FakePlayerPluginScan(),
new MinerScan(),
new ProxyScan(),
new DiscordNukeScan()
new BadScriptsScan()
};
var scans = await PluginService.BuildMalwareScans(defaultScans.ToArray());