Tuesday, May 30, 2017

ProcDOT plugin writing. Part 1 - Creating your first plugin.

ProcDOT is a malware analysis tool created by Christian Wojner (CERT.at - CERT Austria). The tool is designed to correlate Procmon logs and PCAP data. ProcDOT takes this data and lets you visualize the information in a graph loaded with useful information. It also contains a simple, yet powerful plugin engine designed to help analysts extend the capabilities of ProcDOT. More information can be found at the ProcDOT website.

I decided to write these tutorials to help others with the creation of plugins for ProcDOT. My hope is that these tutorials will help with some of the frustration and issues I have had when creating plugins. For these tutorials, we need to have our system setup properly.

Most, if not all, of my plugins are written in python. Why python? I wanted to have a language that could be used on both Windows and Linux so I did not have to write separate plugins for each. This also helps with maintaining plugins because if you can get it to work on one system, it should work on the other, for the most part.

Another thing to note. I also try to stick with LinuxShellScript and WindowsBatchScript for the architecture. This is so I don't need to create different pdp files for 32 and 64 bit systems.

I'm not going to go into how to setup ProcDOT. If I have to explain that then you probably shouldn't be reading this yet.

For these tutorials, I will be using Windows, ProcDOT 1.2 [Build 55u], and python2.7. You can download python2.7 here. When installing python, make sure the executable is in the system path. You need to be able to call python from the command line for these tutorials to work.

In this post, we will create our first plugin. As we go through other tutorials, this plugin will come in handy for troubleshooting and plugin development.
 
ProcDOT's plugins consist of two parts:
  • The plugin descriptor file
  • The plugin itself
The plugin descriptor file contains the information that ProcDOT needs to be able to handle the plugin. Simply put, it is a configuration file for the plugin itself. The descriptor file must have the extension ".pdp" (Note: it must be lower case on a linux system or it will not be read).

The following table lists the keynames and their uses for the descriptor file:

Keyname Description Possible values Supported plugin types
Name Specifies the name of the plugin. [Ascii] all
Author Specifies the name of the author. [Ascii] all
Description Specifies a description for the plugin. [Ascii] all
Version Specifies the version of the plugin. [Ascii] all
Type Specifies the type of the plugin.
Currently 3 types are supported:
- ContextMenuItemForGraph ... The plugin is available through the context menu that popps up when the right mouse button is pressed while hovering the canvas area of the graph.
- EventHandler ... The plugin is automatically registered (and therefore called) as an eventhandler for the given event constant(s) via "Event = " or "Events = ".
- MainMenuItem ... The plugin is available through the main menu item "Plugins". Currently there can exist 9 main menu item plugins in maximum.
ContextMenuItemForGraph
EventHandler
MainMenuItem
all
Architecture Specifies the architecture the plugin was developed for. Linux32BitExe
Linux32BitSo
Linux64BitExe
Linux64BitSo
LinuxShellScript
Windows32BitDll
Windows32BitExe
Windows64BitDll
Windows64BitExe
WindowsBatchScript
all
File Specifies the file to be used as the actual plugin. [Filename] all
Priority Specifies the position of the actual plugin in case of multiple matching plugins from 1 to 9 with 1 being the highest priority and 9 being the lowest. 1 - 9 all
RunHidden Tells ProcDOT to run the actual plugin hidden hennce preventing any windows from popping up. (1 = True, 0 = False) 1 / 0 all
RunExclusively Tells ProcDOT to not run any other non-exclusive plugin in parallel to this one. (1 = True, 0 = False) 1 / 0 all
CanOverrideOtherPlugins Specifies that if the actual plugin exits with a return code of 1 any other plugin being in the queue waiting to run will be skipped. (1 = True, 0 = False) 1 / 0 all
CanOverrideProcDot Specifies that if the actual plugin exits with a return code of 1 any following builtin functionality of ProcDOT will be skipped. (1 = True, 0 = False) 1 / 0 all
CanBeVerified Specifies that this plugin can also be called in verification mode (Environmentvariable PROCDOTPLUGIN_VerificationRun) to decide if it's able to handle the hovered node or situation. (1 = True, 0 = False)
The actual plugin needs to exit with a return code of 1 to signal that it's able to properly handle an according "real" call.
1 / 0 all
Event
or
Events
Specifies the event (or events seperated with colons) for which the actual plugin shall be registered for as an event handler. BeforeLeftClickOnGraph
BeforeLeftDblClickOnGraph
BeforeMiddleClickOnGraph
BeforeMiddleDblClickOnGraph
BeforeRightClickOnGraph
BeforeRightDblClickOnGraph
AfterLeftClickOnGraph
AfterLeftDblClickOnGraph
AfterMiddleClickOnGraph
AfterMiddleDblClickOnGraph
AfterRightClickOnGraph
AfterRightDblClickOnGraph
BeforeRefresh
AfterRefresh
BeforeProcmonButtonClick
AfterProcmonButtonClick
BeforeWindumpButtonClick
AfterWindumpButtonClick
BeforeLauncherButtonClick
AfterLauncherButtonClick
BeforeSwitchToFrameMode
AfterSwitchToFrameMode
BeforeSwitchToNormalMode
AfterSwitchToNormalMode
BeforeTimelineFirstFrame
AfterTimelineFirstFrame
BeforeTimelinePreviousFrame
AfterTimelinePreviousFrame
BeforeTimelineNextFrame
AfterTimelineNextFrame
BeforeTimelineLastFrame
AfterTimelineLastFrame
BeforeTimelinePlayAnimation
AfterTimelinePlayAnimation
BeforeTimelineStopAnimation
AfterTimelineStopAnimation
EventHandler
Figure 1. From ProcDOT's documentation.

Let's begin by making a plugin for the Main Menu that opens the Windows command prompt. Although this plugin will not be very useful right now, it will be in later posts to help write other plugins. Back to the descriptor file.

Create a file named cmd_line.pdp in the ProcDOT plugin folder. If you do not have this folder, it can be created in the same folder the ProcDOT executable is located in. Inside this file we will place the following:

Name = cmd
Author = <your name>
Description = Open cmd prompt from ProcDOT's Main Menu
Version = 1
Type = MainMenuItem
Architecture = WindowsBatchScript
File = cmd_line.bat
Priority = 9
RunHidden = 0
RunExclusively = 1
CanOverrideOtherPlugins = 0
CanOverrideProcdot = 0

Now that we have our descriptor file, we can start to create our plugin. Notice in the descriptor file, File = cmd_line.bat. This will be our plugin. In the plugin directory, create a file called cmd_line.bat and place the following inside:

@setlocal enabledelayedexpansion && python -x "%~f0" %* & exit /b !ERRORLEVEL!
#!/usr/bin/env python

import os

os.system("start /wait cmd /K")

Lets break down what what this plugin will do:

Because we are calling our plugin in a batch file, the first line, @setlocal enabledelayedexpansion && python -x "%~f0" %* & exit /b !ERRORLEVEL!, calls python and executes the rest of the script through the python interpreter. This is so we do not have to associate .py files with python itself.

The rest of the lines are our python code to open the command prompt.

Lets fire up ProcDOT and see if our new plugin works.
When we click on the Plugins menu, there should be an entry called cmd.



Lets double check to make sure there are no errors in out plugin. We can do this by clicking on the Plugins-Manager. If there are not any errors, your screen should look like the one below.


We can also view the details of the plugin by clicking on the plugin from the Plugins-Manager menu.



Time to load up a pcap and a procmon trace to see if everything is working with the plugin Once the graph is generated, open the Plugins menu and select cmd. If everything worked you should have a command prompt open on your screen. If we type set | find /i "procdot" into this cmd prompt, we should see a list of ProcDOT variables to work with.



Success! We have created our first plugin.

In the upcoming post, we will use this plugin to create and troubleshoot other plugins.