Skip to content

Plugin Manager Design

Duncan Ogilvie edited this page Sep 4, 2019 · 1 revision

This document lays out the design of the plugin manager. The main goal is to provide an infrastructure with various layers/levels of security:

  1. Nobody => No security (basically for development or internal network situations).
  2. Plugin developer => Validate the hash of the plugin binaries (to check data corruption, basically no security).
  3. Plugin developer => Signature of the plugin hashes (to confirm authenticity and integrity of the plugin, the author delivers the contents they intended).
  4. Plugin manager => Co-sign trusted plugin versions (this hopefully provides a certain degree of comfort).

TODO: Add an additional level between 2 and 3 for 'trusted/known' authors. This would provide a bit of comfort between 'plugin is from this author' and 'plugin is completely trusted by x64dbg authors' namely: 'plugin is from trusted author'

TODO: Somehow support 'living' plugins (eg only one version but updates can still be done somehow). This can also be used to update x64dbg itself.

Root

The plugin manager is pointed to the root JSON file:

{  
  "plugins":[
    {
      "name":"plugin1",
      "author":"author1",
      "container":"https://author1.com/plugin.json",
      "co-signatures":{
        "0.1":"xxx",
        "0.2":"yyy"
      }
    },
    {
      "name":"plugin2",
      "author":"author2",
      "container":"https://author2.com/plugin.json",
      "co-signatures":{
        "0.1":"xxx"
      }
    }
  ],
  "authors":[
    {
      "name":"author1",
      "pubkey":"",
      "co-signature":""
    }
  ],
  "signature":"xxx"
}

The contents of root.json are to be signed by the plugin manager. This ensures that an attacker has to compromise both the server and the plugin manager signature to add/change this file.

Plugin container

Plugins are in the form of a container JSON file:

{
  "meta":{
    "name":"plugin1",
    "author":"author1",
    "description":"My first plugin"
  },
  "versions":[
    {
      "version":"0.1",
      "x32":[
        {
          "archive":true,
          "download":"https://author1.com/0.1.zip",
          "sha256":"e84e...",
          "install":[
            {
              "action":"Copy",
              "src":"x32/plugin1.dp32",
              "dst":"plugins/plugin1.dp32",
            },
            {
              "action":"CopyOverwrite",
              "src":"plugin1.cfg",
              "dst":"./plugin1.cfg",
            },
            {
              "action":"CopyRecursiveOverwrite",
              "src":"x32/directory",
              "dst":"plugins",
            }
          ],
          "uninstall":[
            {
              "action":"Delete",
              "src":"somefile"
            },
            {
              "action":"Execute",
              "src":"uninstall.bat"
            }
          ]
        },
        {
          "archive":false,
          "download":"https://author1.com/some.file",
          "sha256":"bb38...",
          "install":{
            "some.file":"./some.file"
          }
        }
      ],
      "x64":{},
      "signature":"xxx"
    }
  ]
}

Semantic versioning is to be used for versions.

The download can be a relative path to the url used for container.json (this allows you to install plugins locally).

The action a plugin JSON can do depends on the state (install/uninstall).

Attack vectors

This is a (probably incomplete) list of possible attacks on the system.

Attacker compromises root.json

Fine, but they also have to compromise the level 3 private key because every change to root.json requires a valid signature.

Attacker compromises container.json

This allows the attacker to issue a malicious update of level 1. This update will be rejected if the plugin was ever level 2 or higher.

Attacker compromises level 3 private key

This public key is hardcoded in the plugin manager. To change it you would have to compromise the plugin code, which means you no longer have to change the public key to do malicious things.

Attacker compromises author private key

This is dangerous when also compromising container.json, because it allows you to issue a malicious update of level 2.

Attacker compromises download

  • level 0: royally fucked (there are no integrity checks at this level).
  • level 1: with a clean container.json: safe because the hashes will mismatch.
  • level 2: clean.
  • level 3: clean.

Attacker manages to submit a (malicious) level 0 plugin

The attacker would be stupid because they can submit a level 1 plugin by computing the hash(es) of the download(s) on their system.

The GUI will mark these in red and give multiple confirmation dialogs to warn about possible malware.

Notice: Using HTTPS for the download gives no security guarantees.

Attacker manages to submit a (malicious) level 1 plugin

Basically anyone with a GitHub account and pull request skills can do this.

The GUI will mark these plugins in red and give multiple confirmation dialogs to warn about possible malware.

Attacker manages to submit a (malicious) level 2 plugin

This could happen with an attacker who already submitted a clean plugin and went through the process of getting their public key accepted in root.json (basically anybody will get accepted because the goal is to verify integrity and authenticity of the delivered plugin files).

The GUI will say 'Plugin authenticity and integrity validated' and mark this plugin as yellow. Just like connecting to a phishing site over HTTPS, this gives no guarantees about the contents of this plugin.

Attacker manages to submit a (malicious) level 3 plugin

At this point you are royally fucked. The GUI will say 'Plugin authenticity and integrity validated & marked as clean by x64dbg authors'. At this point it is up to the user to validate the plugin is clean before actually running it. The GUI will provide an option to delay the plugin load to the next restart.