jedisct1 / 6Jack

A framework for analyzing/testing/fuzzing network applications.
http://download.pureftpd.org/6jack/
Other
46 stars 7 forks source link

6jack

A framework for analyzing/testing/fuzzing network applications.

Releases can be downloaded from: http://download.pureftpd.org/6jack/

DESCRIPTION

6jack runs a command, intercepts calls to common network-related functions and passes them through a filter as MessagePack serialized objects.

     App                External process
     ---                ----------------         
      |                (started on-demand)
      V
+----------+
|   ....   |
+----------+
      |
      V                    +-----+
+----------+  pre-filter   |     |
|  call()  | ------------> |  F  |
+----------+               |  i  |
                           |  l  |
                           |  t  |
+----------+  post-filter  |  e  |
|   ....   | <-----------  |  r  |
+----------+               |     |
      |                    +-----+
      V

6jack is especially suitable for:

6jack works at application level. It's a simple library that gets preloaded before the actual application.

Pre-filters can inspect and alter the content prior to calling the actual function. Data, options and local/remote IP addresses and port can be easily changed by the filter. A pre-filter can also totally bypass the actual call, in order to simulate a call without actually hitting the network.

Post-filters can inspect and alter the content after the actual call. In particular, post-filters can change return values and the errno value in order to simulate failures.

SYNOPSIS

6jack filter command [args]

FILTERS

A filter is a standalone application that can be written in any language currently supported by MessagePack: Ruby, C, C++, C#, Scala, Lua, PHP, Python, Java, D, Go, Node.JS, Perl, Haskell, Erlang, Javascript and OCaml.

A filter should read a stream of MessagePack objects from the standard input (stdin) and for every object, should push a serialized reply to the standard output (stdout).

Every diverted function sends exactly one PRE object and one POST object, and synchronously waits for a reply to each object.

SAMPLE FILTER

This is a simple Ruby filter that forces everything written and read to upper case, and logs every object to stderr:

require "msgpack"
require "awesome_print"
pac = MessagePack::Unpacker.new
loop do
  begin
    data = STDIN.readpartial(65536)
  rescue EOFError
    break
  end
  pac.feed(data)
  pac.each do |obj|
    obj["data"].upcase! if obj["data"]
    warn obj.awesome_inspect
    STDOUT.write obj.to_msgpack
    STDOUT.flush
  end
end

Other examples are available in the example-filters directory.

COMMON PROPERTIES

Objects sent by all diverted functions include the following properties:

The reply from a filter should at least include:

Additional properties that can be added to replies for all functions (everything is optional):

FUNCTION-SPECIFIC PROPERTIES

write()

PRE filter

POST filter

writev()

PRE filter

POST filter

socket()

PRE filter

POST filter

Same as a PRE filter.

sendto()

PRE filter

POST filter

sendmsg()

PRE filter

send()

PRE filter

POST filter

recvmsg()

PRE filter

POST filter

recvfrom()

PRE filter

POST filter

recv()

PRE filter

POST filter

read()

PRE filter

POST filter

connect()

PRE filter

close()

This function has no specific properties. However, local_host, local_port, remote_host and remote_port are filled accordingly in both types of filters.

bind()

PRE filter

ENVIRONMENT

When a SIXJACK_BYPASS environment variable is defined, calls are not diverted to the filter any more.

An application is free to set and unset SIXJACK_BYPASS, in order to explicitly disable 6jack in some sections.

SAMPLE OUTPUT

$ 6jack /tmp/filter-passthrough.rb curl http://example.com    
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "socket",
             "fd" => -1,
         "domain" => "PF_INET6",
           "type" => "SOCK_DGRAM",
       "protocol" => "IPPROTO_IP"
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "socket",
             "fd" => 7,
    "return_code" => 7,
          "errno" => 2,
         "domain" => "PF_INET6",
           "type" => "SOCK_DGRAM",
       "protocol" => "IPPROTO_IP"
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "close",
             "fd" => 7,
     "local_host" => "::ffff:0.0.0.0",
     "local_port" => 0
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "close",
             "fd" => 7,
    "return_code" => 0,
          "errno" => 2,
     "local_host" => "::ffff:0.0.0.0",
     "local_port" => 0
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "socket",
             "fd" => -1,
         "domain" => "PF_LOCAL",
           "type" => "SOCK_STREAM",
       "protocol" => "IPPROTO_IP"
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "socket",
             "fd" => 8,
    "return_code" => 8,
          "errno" => 2,
         "domain" => "PF_LOCAL",
           "type" => "SOCK_STREAM",
       "protocol" => "IPPROTO_IP"
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "socket",
             "fd" => -1,
         "domain" => "PF_INET6",
           "type" => "SOCK_STREAM",
       "protocol" => "IPPROTO_TCP"
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "socket",
             "fd" => 7,
    "return_code" => 7,
          "errno" => 2,
         "domain" => "PF_INET6",
           "type" => "SOCK_STREAM",
       "protocol" => "IPPROTO_TCP"
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "connect",
             "fd" => 7,
     "local_host" => "::",
     "local_port" => 0,
    "remote_host" => "2001:500:88:200::10",
    "remote_port" => 80
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "connect",
             "fd" => 7,
    "return_code" => -1,
          "errno" => 65,
     "local_host" => "::",
     "local_port" => 50716,
    "remote_host" => "2001:500:88:200::10",
    "remote_port" => 80
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "close",
             "fd" => 7,
     "local_host" => "::",
     "local_port" => 50716
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "close",
             "fd" => 7,
    "return_code" => 0,
          "errno" => 57,
     "local_host" => "::",
     "local_port" => 50716
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "socket",
             "fd" => -1,
         "domain" => "PF_INET",
           "type" => "SOCK_STREAM",
       "protocol" => "IPPROTO_TCP"
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "socket",
             "fd" => 7,
    "return_code" => 7,
          "errno" => 57,
         "domain" => "PF_INET",
           "type" => "SOCK_STREAM",
       "protocol" => "IPPROTO_TCP"
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "connect",
             "fd" => 7,
     "local_host" => "0.0.0.0",
     "local_port" => 0,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "connect",
             "fd" => 7,
    "return_code" => -1,
          "errno" => 36,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "send",
             "fd" => 7,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80,
          "flags" => 0,
           "data" => "GET / HTTP/1.1\r\nUser-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3\r\nHost: example.com\r\nAccept: */*\r\n\r\n"
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "send",
             "fd" => 7,
    "return_code" => 145,
          "errno" => 36,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80,
          "flags" => 0,
           "data" => "GET / HTTP/1.1\r\nUser-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3\r\nHost: example.com\r\nAccept: */*\r\n\r\n"
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "recv",
             "fd" => 7,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80,
          "flags" => 0,
          "nbyte" => 16384
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "recv",
             "fd" => 7,
    "return_code" => 128,
          "errno" => 36,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80,
          "flags" => 0,
           "data" => "HTTP/1.0 302 Found\r\nLocation: http://www.iana.org/domains/example/\r\nServer: BigIP\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n"
}
{
        "version" => 1,
    "filter_type" => "PRE",
            "pid" => 2233,
       "function" => "close",
             "fd" => 7,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80
}
{
        "version" => 1,
    "filter_type" => "POST",
            "pid" => 2233,
       "function" => "close",
             "fd" => 7,
    "return_code" => 0,
          "errno" => 36,
     "local_host" => "192.168.100.7",
     "local_port" => 50717,
    "remote_host" => "192.0.43.10",
    "remote_port" => 80
}