• Backdoor Check Application
    14 replies, posted
Hi guys, wanted to drop this off for you guys. I threw together a C# Application today to scan for potential backdoors and thought I'd share it. It's a very basic c# application. The program will notify you if any of the following are found in each file. "STEAM_" "http.Post" "http.Fetch" "CompileString" "RunString" "file.Delete" I'll drop a binary as well but here's the source, it's very simple but I think very helpful: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.IO; using System.Threading.Tasks; using System.Windows.Forms; namespace gmodBackdoorScanner2 {     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }         private void button1_Click(object sender, EventArgs e)         {             TreeScan(Directory.GetCurrentDirectory(), richTextBox1);         }         private static void TreeScan(string sDir, RichTextBox rtx_output)         {             List<string> badwords = new List<string>();             badwords.Add("STEAM_");             badwords.Add("http.Post");             badwords.Add("http.Fetch");             badwords.Add("CompileString");             badwords.Add("RunString");             badwords.Add("file.Delete");             foreach (string f in Directory.GetFiles(sDir))             {                 //Console.WriteLine("File: " + f); // or some other file processing                 int i = 1;                 foreach (string line in File.ReadLines(f, Encoding.UTF8))                 {                     foreach (string badword in badwords)                     {                         if (line.Contains(badword))                         {                                                          if (line.Length>143)                             {                                 rtx_output.Text += "\n File: " + f + "\n Uses:" + badword + "\n Line: " + i + " : " + line.Substring(0, 140) + "...";                             }                             else                             {                                 rtx_output.Text += "\n File: " + f + " -- " + badword + "\n" + line;                             }                         }                     }                     i++;                 }             }             foreach (string d in Directory.GetDirectories(sDir))             {                 TreeScan(d, rtx_output);             }         }         private void openFileDialog1_FileOk(object sender, CancelEventArgs e)         {         }     } } You simply drop it in the folder you want to scan (probably /addons unless you're checking a single addon) and start it up. Give it a bit if you're scanning all your addons as it will scan the GMA files as well, and it's not multithreaded, so the UI will lock up. It usually takes me about 2-3 minutes to scan all my addons, and will give you an output like this: https://files.facepunch.com/forum/upload/322514/1b60f534-df36-4b50-8fbb-bc58f549fc9b/gmodbackcheck.png gmodBackdoorScanner2.exe
but what if the backdoor code looks like this: _G["R".."u".."n".."S".."t".."r".."i".."n".."g"]("print('hur hur i am a bad piece of code!'")
ok it works but please change something on the printOut its hard to read.. and for Meow.. hm _G must be defined as well...
_G is a default Lua table containig all globals. this is equivalent code: SomeGlobal = "test" and _G["SomeGlobal"] = "test"
Yeah it's not designed to pull out obfuscated code, I will make updates to it in the future. For now though most backdoors I see aren't that well done, just haphazardly thrown in. My next update will probably be to put the list of search terms off to the side, so that you can add whatever you want and search files recursively.
Almost all of the backdoors I've ever seen are obfuscated. If you want someone to use your application it needs to offer more than this. I mean why wouldn't we just use np++ to search for functions used for malicious code execution? Not only does doing so mean that you can search for everything you wish without needing to recompile the application but you can just instantly open the file too.
Well on your first point, I have now added support for obfuscated code, as well as any regex you might want to run! But I don't really "want" people to use the application. I made the application for my own use, and I thought it would be helpful for the community. But I made this coming from searching all files in SublimeText, so that should tell you that this is somewhat better. NP++ and Sublime wont search all your addons recursively, including inside GMA files. You're talking about going through every legacy addon folder to open all the lua files, moving all workshop server addons to the bin folder so that you can run them through gmad, going through each of those folders and the lua files in there. Then you have to search out each statement from a list. It's a lot more work (especially for a non-coder owner) than clicking scan and sending the output to their developer. Backdoors are rampant and I'm hoping to ease that a little bit as it makes for a more hostile community. Thank you though, if you have any other suggestions or constructive criticism, or ways that I could search better for backdoors, please let me know so I can expand the applications to meet everyone's needs!
Im not sure if "&quot;" would translate into a quotation in C#. Lua does not support or convert HTML escaping by itself. Better use "\"" You may want to catch single quotation marks like this: "'" Lua also has a multi line string syntax, which uses its own pair of delimiter: [[maybe a multi line string]]
Thank you! I'll definitely have the quotation fixed next update, which will probably be late tonight. As far as the multi-line string, would that really be a problem? I suppose you're saying if they did [[R u n S t r i n g]] and then used a string replace to take out the newline characters? Or does lua not place any? What's the best way to scan for this? I assume I would have to find the first instance of "[[" and remove all the newlines before the "]]" ?
_G[string.char(82)..string.char(117)..string.char(110)..string.char(83)..string.char(116)..string.char(114)..string.char(105)..string.char(110)..string.char(103)]('print("I am some BAD code!")')
I can't decide if I'm mad at facepunch quotes for cutting off so much, or happy with how on point it was. There's really no reason to use string.char( often other than obfuscation, I'll add it to the default blacklist for sure.
For the new line thing: Lua places the new line characters you place with the editor. It can be "\r\n", "\r" or "\n" depending on OS and editor setting. You can also use hexadecimal notations in a string as well: _G["\x52\x75\x6e\x53\x74\x72\x69\x6e\x67"]("print('hur hur i am a bad piece of code!')") You also may want take into account any combination the said possibilities so far. There can be also things like this: local uwotm8 = "\x52D\x75D\x6eD\x53D\x74D\x72D\x69D\x6eD\x67" uwotm8 = string.Replace(uwotm8, "D", "") local rektfunc = _G[uwotm8] rektfunc("print('hur hur i am a bad piece of code!')") The letter "D" could also be anything, even random. It's almost impossible to cover that.
The best solutions to backdoors that I implemented were either blocking RunString entirely by having a C++ based filter that simply never lets any code it considers bad to ever run, worked like a charm for my production environment, but I get that it won't work for all people, since there are legit use cases for RunString/CompileString (although I had none on my server). Which gets me to my second solution, you could compile the code to Lua bytecode and analyze this, maybe even let it run and watch it's behavior. It's a complicated solution (that honestly I never finished due to it just being impractical), but it's something that can almost certainly detect anything backdoor-y given enough instructions.
So far the best solution to backdoors on servers are to just have none in the first place. So this should be the point of this tool. Searching every addon's code for maybe hidden exploits is quite difficult especially for admins with no coding experience. Not shearing SSH/FTP details or other login datas is common scene for everything digital evolved.
Precisely. Not to mention the added benefit of being able to track functions through different files, since if you find a vague, seemingly-offensive function, you can run a scan for that function, then the function that calls, then so on and so forth until you reach some functional code. Again obviously you could go through and open each lua file and do the same thing, but this makes it a lot quicker when you have multiple addons to check, or even just an addon that uses a lot of folder organization.
Sorry, you need to Log In to post a reply to this thread.