Friday, November 22, 2013

Create your own Maltego graph sharing server

In Maltego it is possible to use any public XMPP server with the required features enabled (authentication, conferencing and item discovery) for graph sharing, but having your own private server can also be useful. It might be that you want complete control over the XMPP server or that you want all communication to happen only in 'n LAN behind a firewall. Having your own local server will also reduce the latency for your team if everyone is in the same geographic area. 

In this tutorial I will show how you can configure your own XMPP server and use it for sharing graphs in Maltego. I'll be using Prosody for the server since it is easy to install and configure.

Step 1 - Install Prosody


Have a look at the Prosody download page for instructions on how to install Prosody on different operating systems. 

For this tutorial I used an Ubuntu server as my Prosody server and most of the steps would be similar for other Linux distributions and OS X. Windows would require a little bit more effort only because the Windows version of Prosody does not include the prosodyctl utility for easily adding users.

So firstly install or extract Prosody as described on the download site. For Ubuntu you can run...

   sudo apt-get install prosody

Step 2 - Server name


In the Prosody config file (in the next step) you will have to specify the server name for the server running Prosody. 

If your server will only be accessed from your local LAN you can use the machine name as the server name, otherwise you can use the external domain name of the server. 

SRV records are also supported to resolve the domain name of your XMPP server, for more info about using SRV records for XMPP servers see wiki.xmpp.org/web/SRV_Records.

Step 3 - Configure Prosody


Prosody is configured by editing the Prosody configuration file (prosody.cfg.lua). The Configuring Prosody page has detailed information about configuring Prosody.

In Windows you can run editconfig.bat to edit the Prosody configuration file.

In Linux the location of the configuration file is... 

   /etc/prosody/prosody.cfg.lua

If the file does not exist create it and add the following lines, if the file does exist make sure the following lines are present and not commented out (comments start with --)...

   modules_enabled = {
      "saslauth";
      "tls";
      "disco";
      "version";
   }
   VirtualHost "my.domain.com"
   Component "conference.my.domain.com" "muc"

Replace my.domain.com in both lines with the server name from the previous step.

Step 4 - Create a user


In Windows you can use an XMPP client like Pidgin to connect to your Prosody server and add users.

In Linux you can create a user by running...

   sudo prosodyctl register anton my.domain.com mypassword

...where you replace anton with your username, my.domain.com with your server name and mypassword with a suitable password.

Step 5 - Start/restart Prosody


In Windows run prosody.bat to start Prosody.

In Linux run...

   sudo /etc/init.d/prosody restart

Step 6 - Connect with Maltego


Start Maltego on a machine that has access to your XMPP server machine through its server name.

Open Share Graph...


Fill in the session info. For this example I'll use the same session info as in the previous blog post (see Remote Graph Sharing with Maltego)...


Next change the server settings. Enter your server name from Step 2 in Server DNS Name. If using SRV records you can leave the port on Auto detect, else choose the Default port 5222 as below.  Also enter your Username and Password and then click Connect...



Connected


If everything went as planned then you should have a new graph connected to your new XMPP server with the Collaboration Session window displaying your server's details like in the screenshot below...


In the Server settings you might have noticed a Paterva (Private) option as well. If you are interested in buying your own private server that works the same as the public Paterva communication server with auto-registration and everything included then you can email the Paterva guys at support@paterva.com.

Anton van Aswegen

Thursday, November 21, 2013

Remote Graph Sharing with Maltego

With the new graph collaboration features in Maltego Tungsten 3.4 and Maltego CaseFile 2.0 it is possible for a whole team of people to work together on the same graph remotely and securely. Graphs are synchronized using the XMPP (Jabber) protocol so the graph is never stored anywhere in the 'cloud', it is only stored on the machines of the users sharing a graph. Communication is encrypted with TLS and 128-bit AES. With some configuration 256-bit encryption can also be used, but it is important to be wary of the cryptography laws in your country.

The best thing about the graph sharing in Maltego is that it's really easy, especially if using the default public Paterva communication server, which comes with all the security mentioned above. With a few clicks your whole team could be collaborating on a graph in no time.

As an example of how to share a graph the following tutorial shows how Bob can share a graph remotely with Alice.

Step 1 - Key Exchange

Bob and Alice decides to collaborate on a research project using Maltego. Beforehand they have to exchange the security key that they will use for sharing graphs. Since the security key must be kept secret they decide to meet up and exchange the key verbally in person.  

Step 2 - Bob shares a new graph

Later on Bob is at home and decides to start doing research. He fires up Maltego.

Step 2a - Share Graph

Bob clicks on Share Graph...

Step 2b - Session Info

Bob enters the following session info and clicks Connect...

Step 2c - Bob notifies Alice

Bob lets Alice know that he shared a graph with the name "Wonderland42".

Step 3 - Alice connects

Alice also fires up Maltego.

Step 3a - Share Graph

Alice clicks on Share Graph...


Step 3b - Session Info

Alice enters the same Session Name and Security Key as Bob but uses "Alice" as her User Alias...


Both Bob and Alice are now be connected to the same graph as shown in the Collaboration window...


Step 4 - Collaborate!

Bob and Alice can now chat using the chat window and both of them can make changes to the same shared graph... 


Bob and/or Alice can then save the graph locally and share it again later to continue collaborating and more than two people can share the same graph in this way.

One thing to note is that attachments are currently not synchronized to the other users. Your current view of the graph (location & zoom level) is also not synchronized to other users so that users can work with different parts of the graph at the same time, but everything else is synchronized including bookmarks, notes and the layout (per Main/Bubble view).

An encrypted XMPP communication channel is used to share a graph between users. When sharing graphs without changing the server settings (as with Bob and Alice) then a public XMPP server hosted by Paterva is used, but it is also possible to use another public XMPP server or configure and use your own XMPP server. If not using the public Paterva server then the server used must be specified in the "Server" tab of the Share Graph dialog.

Anton van Aswegen


Friday, August 2, 2013

A Proximity View for Maltego

By following the steps bellow you will be able to visualize the proximity of entities in your graph to other preselected target entities. This step-by-step guide was created as a tutorial as well as a proof-of-concept illustration for what can be done using Maltego Viewlets. Let's get started...

Step 1: Open or create a graph in Maltego

To download Maltego visit Paterva's Website. Open an existing graph or create a new graph and drag a few entities from the palette onto the graph and connect them with links (or run transforms to generate links).

Step 2: Select the Bubble View



Step 3: Change to Organic layout for a better view (Optional)


Step 4: Select a target entity 

Select an entity that you want to use as a target for displaying the proximity of other entities to this entity.

Step 5: Show property view toolbar

If the toolbar in the Property View is not visible, right click on the Property View title and click on Show/Hide Toolbar.



Step 6: Add a color property

Click on the plus button in the Property View toolbar to add a new dynamic property. (Note that you can also customize any entity type instead to add the property to that entity type permanently)


Complete the fields as shown below and click OK.


Step 7: Set the color property

Set the color property in the Property View in html/hex format. (Blue in this case)


Step 8: Choose other proximity targets

Repeat steps 6 and 7 for any other entities, optionally using different colors for each one.

Step 9: Add the proximity Viewlet

Click on Configure in the Viewlet drop-down menu.



Click on New Viewlet, enter a name for the Viewlet and click OK.


Click on the Add Binding button.



Choose the "Entity Color" binding property.



Add the following JavaScript code to the binding and click OK twice.

var colorProperty = "proximity.color";

// Converts RGB bytes to hex color (e.g. [255,255,255]->"#FFFFFF")
function rgbToHex(r, g, b) {
    r = Math.floor(r);
    g = Math.floor(g);
    b = Math.floor(b);
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

// Converts hex color to RGB
function hexToRgb(hex) {
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
}

// Populate "colors" with the closest distance for each color found
function recurse(entity, colors, maxDepth, depth) {
    if (depth === maxDepth) {
        return;
    }
    var color = entity.getPropertyValue(colorProperty);
    if (color) {
        var minDepth = colors[color];
        if (!minDepth || depth < minDepth) {
            minDepth = depth;
        }
        colors[color] = minDepth;
    } else {
        var newDepth = depth + 1;
        var links = entity.incoming();
        for (var i in links) {
            recurse(links[i].source(), colors, maxDepth, newDepth);
        }
        links = entity.outgoing();
        for (var i in links) {
            recurse(links[i].target(), colors, maxDepth, newDepth);
        }
    }
}

if (hasProperty(colorProperty)) {
    // If we have a color property then use that
    getPropertyValue(colorProperty);
} else {
    // else get color from proximity to other entities with color properties
    var maxDepth = 6;
    var colors = [];
    recurse(entity, colors, maxDepth, 0);
    var totalWeight = 1;
    var mycolor = {r: 240, g: 240, b: 240};
    for (var i in mycolor) {
        mycolor[i] *= totalWeight;
    }
    for (var c in colors) {
        var color = hexToRgb(c);
        var weight = (maxDepth - colors[c]) / maxDepth;
        for (var i in color) {
            mycolor[i] += color[i] * weight;
        }
        totalWeight += weight;
    }
    for (var i in color) {
        mycolor[i] /= totalWeight;
    }
    rgbToHex(mycolor["r"], mycolor["g"], mycolor["b"]);
    var DEBUG = false;
    if (DEBUG) {
        var out = "";
        for (var i in colors) {
            out += i + ":" + colors[i] + " ";
        }
        out;
    }
}

Result

Your resulting graph should look something like the following, where I have set the indicated entities as my "targets".



There are a lot of optimizations that can be done to the Viewlet code but hopefully this will come in handy for someone working with large and complex graphs where proximity of entities play an important role in analyzing the data.


Anton van Aswegen