Maya Security project

We keep a private github of infected files – we tend to keep it secret to avoid giving bad guys any ideas. If you have infected files please LMK and I’ll see if they are duplicates of any of our existing ones.

1 Like

Hi @Theodox and techart teams, thank you for coming up with this project. This is a very solid security module instead of just using MayaScanner or any custom tool that attempts to find Malware by string check (“vaccine”, “fuckVirus”, “uifiguration”, etc). Is there any new update to this project?

Since there is new type of malware detected (payloads in base64 encoded strings), It is possible we may see more in the future.

We are currently in the process of testing and implementing in our studio (Maya 2018-2022), but we encountered some issues when trying to use Manik. Can we propose to modify some things (sorry if this is too long):

  • Manik does not allow opening binary file .mb (yes I know .ma is better, but currently Manik just fails silently while accessing/loading .mb). We prefer to log to script editor and still able to open it at least with executeScriptNode=False
  • Manik does not categorise warnings (all threats are treated with same red warning, and artist can still open the file). We personally modify the manik.semantic.api and rules to use several threat levels (critical/severe, default, and mild). For critical level threat, artists cannot open the file and must report it (reserved for any embedded code, scriptNodes, anything that is not handled by MayaScanner/does not have any fix) . For mild level threat, Manik will just log warning to the script editor (skipping any warning dialog, or use different colored warning if you wish), this is reserved for mild issues that we will fix using our own callback for cleaning maya file after passing Manik and MayaScanner callback (such as modelEditor change/rogue procedure, outliner selectCommand, extraneous dataStructure, etc)
  • Manik messes up with reference load if one of the reference is dirty and we choose “Do not open”. Maya will still proceed to open the master file, but no references will show up, even if they are clean (in reference editor, outliner, and viewport). Rather than preventing user to open the master file, we can fix this by using addCheckReferenceCallback and kBeforeLoadReferenceCheck, instead of addCheckFileCallback and kBeforeCreateReferenceCheck in runtime.py (the ma_precheck function will need slight refactoring for this callback, we opted to create a new function for reference check). We will be able to open the master file and the references will still be created (and exist in reference editor), but this will prevent any dirty reference to load.
  • add context while traversing “requires” command. We know that requires command can spread from file to file (especially in file references or opening files in Maya with dirty prefs). We found that this “requires” command for older plugin might include longer form such as parentheses and thus screwing up the parsing. We fix it by adding context (just like for “setAttr” command) in traverse parse_stream in manik.semantic.api. Also in our case, we will clean this unused “requires XXX” later by using our own callbacks to remove unused plugins.
  • in prefilter_stream, split any text under UIConfiguration using “;\n” instead of just “;” as we found sometimes there are rogue procedure under modelEditor command that will consist of two procedure calls separated with just semicolon ( ; ) for example:
    modelEditor -editorChanged 'DCF_updateViewportList;updateModelPanelBar'
    thus using just semicolon to split will screw up the parsing in this section.
  • add extra condition in assigned_callbacks in rules.py, if it encounter setAttr type string, then check the value of the string (for example, we can test whether the commands inside the string is a member of UI_CONFIG_COMMANDS, e.g.: viewSet)
  • add timeControl in UI_CONFIG_COMMANDS in mel_Reference.py (yes we encountered some scene that have timeControl command under uiConfiguration)
  • in ma_preprocessor_2.py, add new regex under variable for example:
    _unparent = re.compile('\$panelName = (shape|scripted|model|outliner|pose)Panel -unParent -l (localizedPanelLabel(".*")) -mbv .menusOkayInPanels ;$')
    and add it to _safe_ui_config to skip parsing it in uiConfiguration (else it would result in false positive in many scenes we scan at least in Maya 2020)

Just to make sure, we are free to modify/fork this right? I found no licence in the provided zip archive. Or is better to submit pull request and see if this can be accepted for the next update?

1 Like

Thanks for the feedback! It’s good to see folks getting value from the project!

As far as licensing goes, the README is

This project is provided under the MIT license, which basically says “keep the copyright notice but use as you will”. Please note that part of the terms of the licenses is the phrase “without warranty of any kind” – this is a community effort to address a common problem but its not a commercial product and comes with no guarantee that some clever hacker won’t figure out how to beat us. Manik includes a redistributed copy of PyParsing, which is (c) Paul McGuire. See the file pyparsing.py for the copyright and licensing terms for PyParsing.

I guess I failed to include the LICENSE file in the built zip… Oops! TLDR, though: feel free to modify and fork as needed, but it would probably be better for the community if we added you to the team and incorporated your fixes into the main line – that will let others benefit from it too.

We haven’t gotten a lot of bug reports over the last couple of years so not much has changed since the release that’s pinned to the TAO forums, but I can update a few things based on your feedback here. . My work for the last few years has not put me in a Maya-centric position so I’m also eager to find more maintainers, it’s not good for this kind of thing to be entirely dependent on me!

MB is an interesting problem . We made a conscious decision not to scan MB at the time we did the package: MA is essentially just executable code, which makes it much more dangerous but, being text, we are able to get in and pre-screen it. MB has fewer vulnerabilities but can’t easily be pre-filtered so we ended up choosing not to try. We talked to ADSK about this in 2021 and 22, at that point they didn’t have any real tools for disabling script execution in MEL so it was trivially easy to bypass their plugin with a little hacking – that made securing MA the highest priority.

I have not had a chance make a serious effort at defeating the 2024 security options, I’m guessing that having a good paranoid policy set on both mel and python script execution will be enough to secure MBs . For MAs however, I believe the fundamental problem remains, an attacker does not need to ‘execute as script’ in MA they can just drop the malicious commands into the file and they run during the file load (!!!) This was the whole reason for Manik to go with the prefiltering approach,

As far as threat categorization goes, I’d be interested to see what you’ve been seeing in the wild. Our original design was simply “throw up a flare for anything unusual”, because it became obvious from our penetration testing that there were a lot of sneaky ways people could try to cheat and only a detailed manual inspection was likely to catch them all – but it’s possible that our sample data, which was not too extensive, did not include enough files which harmless use cases which were not problematic.

If you want to contribute to the project LMK, I can add you to our private github team. Given the nature of the subject, it’s best to take detailed conversations private,

Attn: @bob.w , @ldhunham1 for visibility

2 Likes

PS, I’m pretty sure the current version should not be bothered by the linked issue in an MA file – did you see it miss a live example?

yeah we tested and encounter the issue in some production scenes (mainly done in Maya 2018-2020). File usually contain references with file format .ma, .mb, or both. I guess when there is issue Manik prevent the creation of references instead of only preventing the references to load. Also encountered some false positive because of parsing issues that I mentioned.

I’ll PM you with more details.

Just seen this. Really appreciate the feedback. Looking forward to seeing what improvements can be made!