(New removal plugin!) SirHurt server-side backdoor location "CSGDictionaryService" inaccessable outside of the place xml file

It’s completely undetectable if you aren’t specifically looking for it in the XML, which is worrying.

Not entirely true. The way I knew something was still there was the dev console Network logs. I noticed the HttpService request to the exploiter’s website in there which told me the infection was still hidden in the game. Once I deleted literally everything and the infection persisted I knew it had to be somewhere neither I nor my scanner code could access/view (Which would require hiding inside something that’s access level 6+ in order to evade my scanner code.) You can detect the infection in-game fairly easily through multiple means (especially once you find the source code of said infection) and even disable/break the backdoor but finding the true backdoor injection script listed above is the real pain.

Bad wording on my part - to actually disable/find the exact malicious code you had to scroll through the XML.
If they properly pcalled it to prevent errors and didn’t post to HTTP? It’d be undetectable.

The specific backdoor we located might be detectable, but this exploit is effectively impossible to detect through any in-game or in-studio means.

Undectable if you don’t look in the XML, yes. You can gather that something shady is going on though if you dig through the plugin’s Lua scripts however.

Scary part is if you’re in a teamcreate and one person has the plugin - nobody knows.

1 Like

The only thing I want to know, is why in the world is the CommandBar below the Plugin security identity?

I’ll look into writing a plugin for this as I think a few of my places are infected by it.

EDIT
Security identities on the old Roblox wiki are outdated.

1 Like

On the good side, support for private modules is being discontinued, so any infected assets will need to insert raw code to be able to function as intended and flushing out the culprit may not be as difficult. On the other hand however, the very fact that something can be inserted in this manner is concerning: especially when the only way to remove it is not easily accessible or understandable by all developers.

People go to some lengths to get a cheap kick, don’t they?

I had mentioned this in the post. When I just looked up the list I did notice that the security context page is not official. (It’s on a user’s self-created page by Anaminus) though creating a plugin to clean the infection was my first thought as well. Unfortunately I hit the same access level insufficient error that you did which is what prompted the creation of this post.

1 Like

Oh, my apologies.

I tend to skip over large paragraphs of text, skimming through them. It’s a habit I’ve gotten into over the years, and is something I should get out of probably.

My apologies. :stuck_out_tongue:

I’ve decided to go ahead and take a closer look at this.

Turns out, you can actually get a list of all Instances in any given game that require an unusual identity to access using pcall and GetDescendants. That’s not very useful on its own, but you can actually use Selection::Set to get all of those item selected (or any list of them). You can then just delete them like you would any other selected items. I wouldn’t recommend doing this for all of them because this list includes the descendants of CorePackages, which should really not be tampered with, but if something has a conspicuous name, I would check it out.

In this instance (I’m using a modified ReflectionMetadata to let me better mess around with this), the names are very suspicious and could easily be removed with this method.

That being said, all it would take is naming it something seemingly normal like Value and this method would fail without a visual representation.

My recommendation would be to make it so anything that isn’t supposed to be there makes the service show up in Explorer regardless of what it is. That would solve this problem now and forever.

In the meantime, here’s a convenient plugin I made to just select things that aren’t meant to be there so they can be more closely inspected (and deleted) in the Properties menu. It’s relatively simple but it should work to identify and clean up stuff like this.

EDIT: There are errors that pop up when you select something like this but they’re from other plugins or built-in plugins so there’s not much I can do about them.

6 Likes

you’re a genius. Thank you!

2 Likes

Oh my, can’t believe I didn’t know about GetDescendants until this! Thank you for sharing. Using this information and a few hacky methods I was able to create a plugin for the automated detection and removal of this infection (as well as any script hiding in a protected locations or known infections located in the game.) The plugin will also allow you to choose to “Store” the infections in a new folder in ServerStorage that it will name “Infections” so you can view the scripts it detected as infections if you’d like.

https://www.roblox.com/library/2670956620/Hidden-Infection-Script-Detector for anyone who wants to use it.

(This plugin uses 1 require so I can easily update the known infection source excerpt string table that the plugin uses to scan scripts and check if they are infection scripts or not. This module is located here: https://www.roblox.com/library/2682779959/Hidden-Script-Scanner-Known-Infections-Table)

1 Like

Oh jeez. I may or may not have completely forgotten about Insert, because, well, that’s not something you think about… Ever. Shout out to Roblox for unintentionally leaving us the tools we need to get the job done.

My initial worry was that now that we’ve called attention to this method it could be used maliciously by doing something like inserting the CoreGui into the workspace, but Insert is actually restricted already so it works in our favor! Please no patch Roblox! We mean well!

Incidentally, if you’re worried about a property being named ‘PropertyThatDoesNotExistPlz’ existing at any point in the future (I cannot possibly imagine you are) you can get the Classname of an Instance by checking the error that shows up when you call it with no arguments. Apparently calling an Instance is a thing because it actually casts a proper and unique error?

The fact that the infected plugin was disguised as a simple class converter is really worrying. I could have easily fallen for that.

I’m really not liking having to fear installing plugins (or even updating my current ones) because they might have backdoors I don’t know about.

here’s the… actual plugin if anyone is interested

not sure how to get that one taken down lol

Also a quick note, you should check if you’re in studio to run this because it currently sends an error whenever you’re on a client.

I already built in a Selection service fallback for just in case the InsertService method gets patched for this reason. Also in reply to your next post I’m pushing an update now for this, thanks for letting me know!

1 Like

It would be nice if you could hook this up to #learning-resources:community-tutorials-resources for public exposure, since infected assets affect many developers, evidently.

A word of caution though: you should not be using a require module, even if the source code is public, because such support is being discontinued in no more than 3 months. Have the module placed internally in the plugin and instead prompt the user if the plugin is outdated and to go update it. When you update a plugin, people will be able to bring their installation up to speed and Studio will automatically refresh the toolbar to allow the updated plugin to commence its functions.

I’ll probably do that. (Update: Done, link to this post is here.)

As for the caution; That’s likely why I built in support for require failure to fallback to a local version of the table. Also to my knowledge the support is only removed for closed-source modules. Meaning as long as I leave it public it should be fine. (Which I intended to do anyways.)

1 Like

We are investigating what we can do to resolve this issue.

6 Likes