• [Concept] Protected Lua Sub-State
    6 replies, posted
I apologise for a thread that might seem useless, and being an 'Idea Guy'. Anyway, time for a concept. Now 9/11 times of servers being exploited (sorry for the shit steel beam joke), it's due to a workshop addon incorporating malicious code to take control of a server without the knowledge of the server owner. Now, there is only a set number of ways for someone to do this. And now I will explain exactly what might be able to prevent most of these cases. Lua has the ability to modify the function environment. Interestingly you are able to setup a global table ( _G ) to take advantage of the __index and the __nexindex methods. Your initial thought might be that you can override these access functions by using rawget() and rawset(). However when calling these functions, this is essentially _G['rawget']() and _G['rawset'](), which will be caught by the __index method. This will mean that after correctly setting up the function enrivonment, there is no way (without using a module) to escape this environment. Now the next idea is to allow the Sub-State and the State to interact, but only for certain functions. In other words, Only allowing certain function calls from the State to call functions in the Sub-State, and vice versa. This will mean that you can prevent certain functions from executing, without the chance of the author from detouring your protection. I don't currently have a PoC code, but it's simple enough to be done in less than an hour. Before I do this however I just need input on ways that we have observed for workshop authors to exploit servers. A further step in this idea would be to create a sub directory that will execute addons in the Sub-State only. Easily done. This is just to allow for server owners to install addons without the worry of their server being compromised. Should be easy enough to create a way of decompiling gma files in runtime to allow for execution, as well as modification functions that require access to the file system to load Materials or Lua files. Easily done. As said, all I need is examples of ways that have been employed to compromise servers in Workshop addons, and critisism for how this might not work, and a discussion for how might I better this idea.
The majority of back-doors I've seen end up using net messages to run lua (using CompileString/RunString)/con-commands on the server/clients, and/or post the host IP/client's IPs to some website [b]Edit:[/b] Isn't __index only called if nothing is found on a table? Wouldn't you have to localize _G.rawset/_G.rawget, then remove _G.rawset/_G.rawget?
I feel like this is a bad idea because it's every server owners own responsibility to keep track of what shit they put on their server. Of course they can be lazy, but they still carry the risk for what they do with it. While you can limit what stuff addons can use, some stuff will always be mandatory. As long as what they can use has the ability to affect the gameplay you can't stop addons from fucking with the server.
I will also be adding the ability to see which addons call these functions. Not only offering protection for those who use this sandbox like system, but also to warn other users who might be at risk if they don't. And I am not aiming to fix all 'trojan' like addons, just to stop the ones that can be most damaging to a server. And for those interested, just a WIP: [lua] --[[ Project Name: TRON "Well, it's called Tron. It's a security program itself, actually. It monitors all contacts between our system and other systems. It finds anything going on that's not scheduled, it shuts it down." ―Alan Bradley Two States: -State : Main State, the one we are currently in -Sub-State: The state we will create as a Sandbox We need to rewrite the first state in order to establish contact between the State and the Sub-State. ]] TRON = {} TRON.AccessModification = {} TRON.AccessModification._DATA = {} TRON.State = {} TRON.State.__STATE = nil --just a reminder for later TRON.SubState = {} TRON.SubState.__STATE = nil function TRON.State.Setup() --Right NowQuiteUsless. local fenv = debug.getfenv(1) local mt = { __index = function( tab, key ) end, __newindex = function( tab, key, value) end } setmetatable(fenv, mt) TRON.State.__STATE = fenv return fenv end function TRON.SubState.Setup() local fenv = debug.getfenv(2) local mt = { __index = function( tab, key ) if type( rawget( tab, key ) ) == 'function' then if TRON.AccessModification.Get( key ) then return TRON.AccessModification.Get( key ) end elseif type( rawget( tab, key ) ) == 'table' then if tab == TRON.SubState._STATE and key == 'TRON' then return nil end end end, __newindex = function( tab, key, value) rawset( tab, key, value ) end } setmetatable(fenv, mt) return fenv end function TRON.AccessModification.Add( key, mod ) mod = mod or function() end TRON.AccessModification._DATA[key] = function( ... ) local tab = table.pack( xpcall( mod, TRON.AccessModification.ErrorHandler ) ) --8 returns at least if tab[1] = true then tab[1] = nil for i = 2,#tab do tab[i - 1] = tab[i] end end return unpack( tab ) end end function TRON.AccessModification.Get( key ) return TRON.AccessModification._DATA[key] and TRON.AccessModification._DATA[key] end TRON.AccessModification.Add( 'RunString', function() end ) TRON.AccessModification.Add( 'CompileString', function() end ) TRON.AccessModification.Add( 'CompileFile', function() end ) TRON.AccessModification.Add( 'rawget', function( tab, key ) return tab[key] end ) --caught in __index TRON.AccessModification.Add( 'rawset', function( tab, key, value ) return tab[key] = value end ) --caught in __newindex --Keep these in a function to reset the function environment after loading sun directories. debug.setfenv( 2, TRON.State.Setup() ) debug.setfenv( 3, TRON.SubState.Setup() ) [/lua] not tested, and not finished. I plan to allow the first state to call functions in the second and vice versa.
[QUOTE=dingusnin;47949332]I will also be adding the ability to see which addons call these functions. Not only offering protection for those who use this sandbox like system, but also to warn other users who might be at risk if they don't. And I am not aiming to fix all 'trojan' like addons, just to stop the ones that can be most damaging to a server. And for those interested, just a WIP: [lua] --[[ Project Name: TRON "Well, it's called Tron. It's a security program itself, actually. It monitors all contacts between our system and other systems. It finds anything going on that's not scheduled, it shuts it down." ―Alan Bradley Two States: -State : Main State, the one we are currently in -Sub-State: The state we will create as a Sandbox We need to rewrite the first state in order to establish contact between the State and the Sub-State. ]] TRON = {} TRON.AccessModification = {} TRON.AccessModification._DATA = {} TRON.State = {} TRON.State.__STATE = nil --just a reminder for later TRON.SubState = {} TRON.SubState.__STATE = nil function TRON.State.Setup() --Right NowQuiteUsless. local fenv = debug.getfenv(1) local mt = { __index = function( tab, key ) end, __newindex = function( tab, key, value) end } setmetatable(fenv, mt) TRON.State.__STATE = fenv return fenv end function TRON.SubState.Setup() local fenv = debug.getfenv(2) local mt = { __index = function( tab, key ) if type( rawget( tab, key ) ) == 'function' then if TRON.AccessModification.Get( key ) then return TRON.AccessModification.Get( key ) end elseif type( rawget( tab, key ) ) == 'table' then if tab == TRON.SubState._STATE and key == 'TRON' then return nil end end end, __newindex = function( tab, key, value) rawset( tab, key, value ) end } setmetatable(fenv, mt) return fenv end function TRON.AccessModification.Add( key, mod ) mod = mod or function() end TRON.AccessModification._DATA[key] = function( ... ) local tab = table.pack( xpcall( mod, TRON.AccessModification.ErrorHandler ) ) --8 returns at least if tab[1] = true then tab[1] = nil for i = 2,#tab do tab[i - 1] = tab[i] end end return unpack( tab ) end end function TRON.AccessModification.Get( key ) return TRON.AccessModification._DATA[key] and TRON.AccessModification._DATA[key] end TRON.AccessModification.Add( 'RunString', function() end ) TRON.AccessModification.Add( 'CompileString', function() end ) TRON.AccessModification.Add( 'CompileFile', function() end ) TRON.AccessModification.Add( 'rawget', function( tab, key ) return tab[key] end ) --caught in __index TRON.AccessModification.Add( 'rawset', function( tab, key, value ) return tab[key] = value end ) --caught in __newindex --Keep these in a function to reset the function environment after loading sun directories. debug.setfenv( 2, TRON.State.Setup() ) debug.setfenv( 3, TRON.SubState.Setup() ) [/lua] not tested, and not finished. I plan to allow the first state to call functions in the second and vice versa.[/QUOTE] I feel like you didn't entirely understand my point. Most exploits end up allowing the person to run lua or to set himself to a certain usergroup. However, there's also a shitton doing other stuff like making someone not killable, stealing people money, kicking others, bannning others, arresting others - the list could go on forever. All of those would be just as damaging. The only thing RunString/CompileString/CompileFile/SetUserGroup etc. do for the person who placed the backdoor is, giving him more options. Secondly, I doubt you'll warn users for every single function which could affect the abuser in some positive way, considering the amount of times some simple stuff is even used like Player.SetHealth.
I feel like you're making this a lot more complicated than it needs to be.
[QUOTE=Leystryku;47950936]I feel like you didn't entirely understand my point. Most exploits end up allowing the person to run lua or to set himself to a certain usergroup. However, there's also a shitton doing other stuff like making someone not killable, stealing people money, kicking others, bannning others, arresting others - the list could go on forever. All of those would be just as damaging. The only thing RunString/CompileString/CompileFile/SetUserGroup etc. do for the person who placed the backdoor is, giving him more options. Secondly, I doubt you'll warn users for every single function which could affect the abuser in some positive way, considering the amount of times some simple stuff is even used like Player.SetHealth.[/QUOTE] In the post your quotes: [i]And I am not aiming to fix all 'trojan' like addons, just to stop the ones that can be most damaging to a server.[/i] All I am aiming to do is stop being from completly taking over a server. This would include code execution and adding a player to a usergroup. I will only be able to create something that offers a 'bit' of protection. I am not trying to stop exploitation once and for all. Again, just a concept where people can post a general way of exploiting a server, I will add a way to stop it. Not unlike an anti cheat, but more an anti-hack.
Sorry, you need to Log In to post a reply to this thread.