Sunday, October 4, 2015

SSHCommander Use Case 0: Example MITM Network Build

SSHCommander is a tool I am working on to help manage large clusters of systems using the SSH protocol. It is currently setup to use Public/Private key encryption to protect against eavesdropping, brute force password cracking, and repetitive stress injuries from typing commands across 50+ nodes.


I am quite proud of where it stands today. I use it in both my personal and professional life. That doesn't mean I think it is finished. The overall program has only had  ~30 Hours of development time. That is a great testament to the power of Python as a rapid development language (rather than my skills as a developer).
I have built it around the Paramiko library, which handles logging in to a remote SSH server and issuing commands as if you were sitting at the terminal. There are some quirks. But I have found it easy to work around most of them. one notable problem has been the cd command. When changing directories in a script, the commands need to be in a single line or else the script will switch back to the login home dir. I overcome this often times simply by using absolute paths.

Configuration

The code is available at https://github.com/dreilly369/SSHCommander If you want to follow along you will also need VirtualBox and Vagrant (to make firing up a group of example machines much easier. First, here is the SSHCommander config file

{
    "NODES": {
        "node-1-router":{
            "username": "sshc-user",
            "pass": "PrivateKeyPassword1",
            "key_path": "keys/node-1",
            "address":"192.168.0.1:2369"
        },
        "node-2-kali-client":{
            "username": "sshc-user",
            "pass": "PrivateKeyPassword2",
            "key_path": "keys/node-2",
            "address": "127.0.0.1:2200"
        },
        "node-3-kali-server":{
            "username": "sshc-user",
            "pass": "PrivateKeyPassword3",
            "key_path": "keys/node-3",
            "address": "127.0.0.1:2201"
        }
        "node-4-win-victim":{
            "username": "sshc-user",
            "pass": "PrivateKeyPassword4",
            "key_path": "keys/node-4",
            "address": "127.0.0.1:2202"
        } 
    }
}

For Node 1 I set up a Bridged Open WRT VM inside an Acer Aspire netbook  running Kali Linux. Nodes 2-4 are Virtual Box instances started by Vagrant for demonstration purposes.

In addition to the core tool, there are two more tools to help you manage the config files. They are add_node.py and del_node.py. Both take an SSHCommander config file as their only option.

The add_node.py tool will interactively walk you through adding a node to the given config. You will need to issue the command it spits out at you to move the newly generated key to the remote host. In most cases you do not need to restart an SSHCommander instance after adding a node to the config. It will be picked up automatically on the next iteration.

The del_node.py tool will do the reverse. It will interactively help you remove the node of your choice. It too will remind you of any commands you will need to run to complete the cleanup (like deleting keys).

Structure

The goal of SSHCommander is to allow someone to easily run commands on 1-n nodes. To do this the SSHCommander Directory structure reflects the configuration:

SSHCommander/
  |__ssh_commander.py
  |__add_node.py
  |__del_node.py
  |__keys/
           |__node-1
           |__node-2
           |__node-3
           |__node-4
           |__node-1.pub
           |__node-2.pub
           |__node-3.pub
           |__node-4.pub
|__conf/
            |__mitm.json
 |__custom/
           |__node-1-router/
                     |__node-1-setup.cmdr
                     |__iptables-setup.cmdr
           |__node-2-kali-client/
           |__node-3-kali-server/
           |__node-4-win-victim/
                     |__windows-update.cmdr
 |__common/
           |__download-rapidTriage.cmdr


To look at scripts for a particular node you can look under the custom/<node-name>/ directory. Any file that has the .cmdr extension will be run on that node. The common folder is run against all nodes. This needs to be carefully considered in a heterogeneous network like this. The scripts in this directory need to be able to run against every type of system you plan to include.

For explanation purposes, lets assume for the moment the scripts under the common and custom directories are all valid and do fun stuff. I will go into them in more detail in later posts. If we were to run python ssh_commander.py -c conf/mitm.json now we would run 3 scripts against node-1 and 2 scripts against node-4-win-victim.

Archiving

One of the coolest features (I think) is the ability to define scripts as 'One Shots' which will, as the name implies, only run once on the target host(s). Adding a % to the end of any .cmdr script makes SSHCommander archive the script after it runs. For custom scripts a % by itelf on any line will archive the script. for Common scripts though, it must be the last line. So it is my standard to add it at the end. Since SSHCommander tries to be non-destructive it does not delete the script. It simply renames it from .cmdr to .bkp. That way, you can also make a 'Sometimes Script' by unarchiving the script whenever you want it to run. A simple cron job to rename the file back to .cmdr does the trick nicely.

Moving Forward

From this point you can easily run commands on any or all the nodes simply by adding it under the appropriate directory. Scheduling commands to run in an order between nodes is also possible, but takes some creativity. SSHCommander will run any line that starts with a ! as a local command. So you can use this to create a script for node 2 once node 1 finishes running some command in it's script. Consider this like a weak/hacky semaphore.

I look forward to hearing what use cases people come up with. What bugs / features they find. If you have ideas drop a comment below or on the GitHub Project. 

No comments:

Post a Comment