SECURITY EDUCATION, PRIVACY GUIDANCE, THREAT AWARENESS, OPEN SOURCE TOOLS, RESEARCH NOTES, AND RESPONSIBLE TECHNOLOGY CONTENT

  • Penetration Testing Distribution - BackBox

    BackBox is a penetration test and security assessment oriented Ubuntu-based Linux distribution providing a network and informatic systems analysis toolkit. It includes a complete set of tools required for ethical hacking and security testing...
  • Pentest Distro Linux - Weakerth4n

    Weakerth4n is a penetration testing distribution which is built from Debian Squeeze.For the desktop environment it uses Fluxbox...
  • The Amnesic Incognito Live System - Tails

    Tails is a live system that aims to preserve your privacy and anonymity. It helps you to use the Internet anonymously and circumvent censorship...
  • Penetration Testing Distribution - BlackArch

    BlackArch is a penetration testing distribution based on Arch Linux that provides a large amount of cyber security tools. It is an open-source distro created specially for penetration testers and security researchers...
  • The Best Penetration Testing Distribution - Kali Linux

    Kali Linux is a Debian-based distribution for digital forensics and penetration testing, developed and maintained by Offensive Security. Mati Aharoni and Devon Kearns rewrote BackTrack...
  • Friendly OS designed for Pentesting - ParrotOS

    Parrot Security OS is a cloud friendly operating system designed for Pentesting, Computer Forensic, Reverse engineering, Hacking, Cloud pentesting...

Wednesday, January 6, 2016

Codetainer - A Docker Container In Your Browser



codetainer allows you to create code 'sandboxes' you can embed in your web applications (think of it like an OSS clone of codepicnic.com ).

Codetainer runs as a webservice and provides APIs to create, view, and attach to the sandbox along with a nifty HTML terminal you can interact with the sandbox in realtime. It uses Docker and its introspection APIs to provide the majority of this functionality.

Codetainer is written in Go. For more information, see the slides from a talk introduction .

Build & Installation

Requirements
  • Docker >=1.8 (required for file upload API)
  • Go >=1.4
  • godep

Building & Installing From Source
# set your $GOPATH
go get github.com/codetainerapp/codetainer
# you may get errors about not compiling due to Asset missing, it's ok. bindata.go needs to be created
# by `go generate` first.
cd $GOPATH/src/github.com/codetainerapp/codetainer
# make install_deps # if you need the dependencies like godep
make
This will create ./bin/codetainer.

Configuring Docker
You must configure Docker to listen on a TCP port.
DOCKER_OPTS="-H tcp://127.0.0.1:4500 -H unix:///var/run/docker.sock"

Configuring codetainer
See ~/.codetainer/config.toml. This file will get auto-generated the first time you run codetainer, please edit defaults as appropriate.
# Docker API server and port
DockerServer = "localhost"
DockerPort = 4500

# Enable TLS support (optional, if you access to Docker API over HTTPS)
# DockerServerUseHttps = true
# Certificate directory path (optional)
# e.g. if you use Docker Machine: "~/.docker/machine/certs"
# DockerCertPath = "/path/to/certs"

# Database path (optional, default is ~/.codetainer/codetainer.db)
# DatabasePath = "/path/to/codetainer.db"

Running an example codetainer
$ sudo docker pull ubuntu:14.04
$ codetainer image register ubuntu:14.04
$ codetainer create ubuntu:14.04 my-codetainer-name
$ codetainer server # to start the API server on port 3000

Embedding a codetainer in your web app
  1. Copy codetainer.js to your webapp.
  2. Include codetainer.js and jquery in your web page. Create a div to house the codetainer terminal iframe (it's #terminal in the example below).
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>lsof tutorial</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script src="/javascripts/codetainer.js"></script>
    <script src="/javascripts/lsof.js"></script>
    </head>
    <body>
    <div id="terminal" data-container="YOUR CODETAINER ID HERE">
    </body>
    </html>
  3. Run the javascript to load the codetainer iframe from the codetainer API server (supply data-container as the id of codetainer on the div, or supply codetainer in the constructor options).
 $('#terminal').codetainer({
terminalOnly: false, // set to true to show only a terminal window
url: "http://127.0.0.1:3000", // replace with codetainer server URL
container: "YOUR CONTAINER ID HERE",
width: "100%",
height: "100%",
});


Share:

LiME - Linux Memory Extractor



A Loadable Kernel Module (LKM) which allows for volatile memory acquisition from Linux and Linux-based devices, such as Android. This makes LiME unique as it is the first tool that allows for full memory captures on Android devices. It also minimizes its interaction between user and kernel space processes during acquisition, which allows it to produce memory captures that are more forensically sound than those of other tools designed for Linux memory acquisition.

Features
  • Full Android memory acquisition
  • Acquisition over network interface
  • Minimal process footprint

Usage
Detailed documentation on LiME's usage and internals can be found in the "doc" directory of the project.
LiME utilizes the insmod command to load the module, passing required arguments for its execution.
insmod ./lime.ko "path=<outfile | tcp:<port>> format=<raw|padded|lime> [dio=<0|1>]"

path (required): outfile ~ name of file to write to on local system (SD Card)
tcp:port ~ network port to communicate over

format (required): raw ~ concatenates all System RAM ranges
padded ~ pads all non-System RAM ranges with 0s
lime ~ each range prepended with fixed-size header containing address space info

dio (optional): 1 ~ attempt to enable Direct IO
0 ~ default, do not attempt Direct IO

localhostonly (optional): 1 restricts the tcp to only listen on localhost, 0 binds on all interfaces (default)


Examples
In this example we use adb to load LiME and then start it with acquisition performed over the network
$ adb push lime.ko /sdcard/lime.ko
$ adb forward tcp:4444 tcp:4444
$ adb shell
$ su
# insmod /sdcard/lime.ko "path=tcp:4444 format=lime"

Now on the host machine, we can establish the connection and acquire memory using netcat
$ nc localhost 4444 > ram.lime
Acquiring to sdcard
# insmod /sdcard/lime.ko "path=/sdcard/ram.lime format=lime"


Share:

WAP - Web Application Protection




WAP is a source code static analysis and data mining tool to detect and correct input validation vulnerabilities in web applications written in PHP (version 4.0 or higher) with a low rate of false positives.

WAP detects and corrects the following vulnerabilities:
  • SQL Injection (SQLI)
  • Cross-site scripting (XSS)
  • Remote File Inclusion (RFI)
  • Local File Inclusion (LFI)
  • Directory Traversal or Path Traversal (DT/PT)
  • Source Code Disclosure (SCD)
  • OS Command Injection (OSCI)
  • PHP Code Injection

This tool semantically analyses the source code. More precisely, it does taint analysis (data-flow analysis) to detect the input validation vulnerabilities. The aim of the taint analysis is to track malicious inputs inserted by entry points ($_GET, $_POST arrays) and to verify if they reach some sensitive sink (PHP functions that can be exploited by malicious input). After the detection, the tool uses data mining to confirm if the vulnerabilities are real or false positives. At the end, the real vulnerabilities are corrected with the insertion of the fixes (small pieces of code) in the source code.
WAP is written in Java language and is constituted by three modules:

  • Code Analyzer: composed by the tree generator and taint analyzer. The tool has integrated a lexer and a parser generated by ANTLR, and based in a grammar and a tree grammar written to PHP language. The tree generator uses the lexer and the parser to build the AST (Abstract Sintatic Tree) to each PHP file. The taint analyzer performs the taint analysis navigating through the AST to detect potentials vulnerabilities.

  • False Positives Predictor: composed by a supervised trained data set with instances classified as being vulnerabilities and false positives and by the Logistic Regression machine learning algorithm. For each potential vulnerability detected by code analyzer, this module collects the presence of the attributes that define a false positive. Then, the Logistic Regression algorithm receives them and classifies the instance as being a false positive or not (real vulnerability).

  • Code Corrector: Each real vulnerability is removed by correction of its source code. This module for the type of vulnerability selects the fix that removes the vulnerability and signalizes the places in the source code where the fix will be inserted. Then, the code is corrected with the insertion of the fixes and new files are created.     

Share:

Bluto - DNS Recon, DNS Zone Transfer, and Email Enumeration



BLUTO DNS recon | Brute forcer | DNS Zone Transfer | Email Enumeration

The target domain is queried for MX and NS records. Sub-domains are passively gathered via NetCraft. The target domain NS records are each queried for potential Zone Transfers. If none of them gives up their spinach, Bluto will brute force subdomains using parallel sub processing on the top 20000 of the 'The Alexa Top 1 Million subdomains'. NetCraft results are presented individually and are then compared to the brute force results, any duplications are removed and particularly interesting results are highlighted.

Bluto now does email address enumeration based on the target domain, currently using Bing and Google search engines. It is configured in such a way to use a random User Agent: on each request and does a country look up to select the fastest Google server in relation to your egress address. Each request closes the connection in an attempt to further avoid captchas, however exsesive lookups will result in captchas (Bluto will warn you if any are identified).

Bluto requires various other dependencies. So to make things as easy as possible, pip is used for the installation. This does mean you will need to have pip installed prior to attempting the Bluto install.

Pip Install Instructions
Note: To test if pip is already installed execute.
  pip -V

(1) Mac and Kali users can simply use the following command to download and install pip.
  curl https://bootstrap.pypa.io/get-pip.py -o - | python

Bluto Install Instructions
(1) Once pip has successfully downloaded and installed, we can install Bluto:
  sudo pip install git+git://github.com/RandomStorm/Bluto

(2) You should now be able to execute 'bluto' from any working directory in any terminal.
  bluto

Upgrade Instructions
(1) The upgrade process is as simple as;
  sudo pip install git+git://github.com/RandomStorm/Bluto --upgrade


Share:

Wireshark v2.0 - The World’s Foremost Network Protocol Analyzer




Wireshark is the world’s foremost network protocol analyzer. It lets you capture and interactively browse the traffic running on a computer network. It is the de facto (and often de jure) standard across many industries and educational institutions.

Wireshark development thrives thanks to the contributions of networking experts across the globe. It is the continuation of a project that started in 1998.

Wireshark 2.0.0rc2 has been released. This is the second release candidate for Wireshark 2.0. Installers for Windows, OS X, and source code are now available.
The following features are new (or have been significantly updated) since version 2.0.0rc1:
  • For new installations on UN*X, the directory for user preferences is $HOME/.config/wireshark rather than $HOME/.wireshark. If that directory is absent, preferences will still be found and stored under $HOME/.wireshark.
  • Qt port:
    • The SIP Statistics dialog has been added.
    • You can now create filter expressions from the display filter toolbar.
    • Bugs in the UAT prefererences dialog has been fixed.
  • Several dissector and Qt UI crash bugs have been fixed.
  • Problems with the Mac OS X application bundle have been fixed.
The following features are new (or have been significantly updated) since version 1.99.9:
  • Qt port:
    • The LTE RLC Graph dialog has been added.
    • The LTE MAC Statistics dialog has been added.
    • The LTE RLC Statistics dialog has been added.
    • The IAX2 Analysis dialog has been added.
    • The Conversation Hash Tables dialog has been added.
    • The Dissector Tables dialog has been added.
    • The Supported Protocols dialog has been added.
    • You can now zoom the I/O and TCP Stream graph X and Y axes independently.
    • The RTP Player dialog has been added.
    • Several memory leaks have been fixed.

Changes in Wireshark 2.0

Capture options. Capture options have been simplified and consolidated. In 1.12 they are spread out in many places across several windows. In 2.0 they are in two places: the Capture Options dialog (Capture→Options or the “gear” icon in the toolbar) and the Manage Interfaces dialog, which you can open by pressing “Manage Interfaces” in the Capture Options dialog.

Streamlined preferences. Preferences windows usually aren’t something to get excited about and this is no exception, but it’s important to note that in the process of removing clutter some preferences have been removed from the main window. They’re still available in the “Advanced” preference section which lists every available preference item.

Translations. Thanks to the hard work of many contributors the new interface supports multiple languages. You can now select between Chinese, English, French, German, Italian, Japanese, and Polish in the “Appearance” preferences section. Many more translations are underway. You can see the status the translation efforts and help out with the effort at https://www.transifex.com/wireshark/wireshark/.

Related packets. As you scroll through the packet list you might notice little symbols pop up along its left edge. For example, you might see left and right arrows for DNS requests and Replies, or a check mark to denote an ACKed TCP packet. These are related packets. This exposes some plumbing we’ve had in place for a long time, but it’s now shown in the main window instead of buried deep in the packet detail tree.

Intelligent scrollbar. As you scroll through the packet list you might notice that the scroll bar itself looks odd. It now features a map of nearby packets, similar to the “minimap” available in many modern text editors. The number of packets shown in the map is the same as the number of physical vertical pixels in your scrollbar. The more pixels you have, the more packets you can see. In other words, if you use Wireshark regularly you now have a legitimate business case for a retina display.

Statistics dialogs. The dialogs under the Statistics and Telephony menus have seen many improvements. The backend code has been consolidated so that most of Wireshark’s statistics now share common internal logic. This in turn let us create common UI code with many workflow improvements and a much more consistent interface.

I/O Graph dialog. You can now graph as many items as you like and save graphs as PDF, PNG, JPEG, and BMP. Graph settings stay with your profile so you can customize them for multiple environments.

Follow Stream dialog. You can now switch between streams and search for text.

General dialogs. Many dialogs now have context-aware hints. For example the I/O Graph and Follow Stream dialogs will tell you which packet corresponds to the graph or stream data under your cursor. Most of them will stay open after you close a capture file so that you can compare statistics or graphs between captures.

Share:

Toxy - Hackable Http Proxy To Simulate Server Failure Scenarios And Network Conditions




Toxy is a fully programmatic and hackable HTTP proxy to simulate server failure scenarios and unexpected network conditions , built for node.js / io.js .

It was mainly designed for fuzzing/evil testing purposes, when toxy becomes particularly useful to cover fault tolerance and resiliency capabilities of a system, especially in disruption-tolerant networks and service-oriented architectures, where toxy may act as MitM proxy among services.

toxy allows you to plug in poisons, optionally filtered by rules, which essentially can intercept and alter the HTTP flow as you need, performing multiple evil actions in the middle of that process, such as limiting the bandwidth, delaying TCP packets, injecting network jitter latency or replying with a custom error or status code. It operates only at L7 (application level).

toxy can be fluently used programmatically or via HTTP API . It was built on top of rocky , a full-featured middleware-oriented HTTP proxy, and it's also pluggable in connect / express as standard middleware.

Requires node.js +0.12 or io.js +1.6

Features
  • Full-featured HTTP/S proxy (backed by rocky and http-proxy )
  • Hackable and elegant programmatic API (inspired on connect/express)
  • Admin HTTP API for external management and dynamic configuration
  • Featured built-in router with nested configuration
  • Hierarchical and composable poisoning with rule based filtering
  • Hierarchical middleware layer (both global and route scopes)
  • Easily augmentable via middleware (based on connect/express middleware)
  • Supports both incoming and outgoing traffic poisoning
  • Built-in poisons (bandwidth, error, abort, latency, slow read...)
  • Rule-based poisoning (probabilistic, HTTP method, headers, body...)
  • Supports third-party poisons and rules
  • Built-in balancer and traffic interceptor via middleware
  • Inherits API and features from rocky
  • Compatible with connect/express (and most of their middleware)
  • Able to run as standalone HTTP proxy

Introduction

Why toxy?
There're some other similar solutions like toxy in the market, but most of them do not provide a proper programmatic control and usually are not easy to hack, configure or are directly closed to extensibility.
Furthermore, the majority of the those solutions only operates at TCP L3 level stack instead of providing high-level abstractions to cover common requirements in the specific domain and nature of the HTTP L7 protocol, like toxy tries to provide
toxy brings a powerful hackable and extensible solution with a convenient abstraction, but without losing a proper low-level interface capabilities to deal with HTTP protocol primitives easily.
toxy was designed based on the rules of composition, simplicity and extensibility. Via its built-in hierarchical domain specific middleware layer you can easily augment toxy features to your own needs.

Concepts
toxy introduces two directives: poisons and rules.
Poisons are the specific logic which infects an incoming or outgoing HTTP transaction (e.g: injecting a latency, replying with an error). One HTTP transaction can be poisoned by one or multiple poisons, and those poisons can be also configured to infect both global or route level traffic.
Rules are a kind of match validation filters that inspects an HTTP request/response in order to determine, given a certain rules, if the HTTP transaction should be poisioned or not (e.g: if headers matches, query params, method, body...). Rules can be reused and applied to both incoming and outgoing traffic flows, including different scopes: global, route or poison level.

How it works
↓  ( Incoming request )  ↓
↓ ||| ↓
↓ +-------------+ ↓
↓ | Toxy Router | ↓ -> Match the incoming request
↓ +-------------+ ↓
↓ ||| ↓
↓ +--------------------+ ↓
↓ | Incoming phase | ↓ -> The proxy receives the request from the client
↓ |~~~~~~~~~~~~~~~~~~~~| ↓
↓ | ---------------- | ↓
↓ | | Exec Rules | | ↓ -> Apply configured rules for the incoming request
↓ | ---------------- | ↓
↓ | ||| | ↓
↓ | ---------------- | ↓
↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow
↓ | ---------------- | ↓
↓ +~~~~~~~~~~~~~~~~~~~~+ ↓
↓ / \ ↓
↓ \ / ↓
↓ +--------------------+ ↓
↓ | HTTP dispatcher | ↓ -> Forward the HTTP traffic to the target server, either poisoned or not
↓ +--------------------+ ↓
↓ / \ ↓
↓ \ / ↓
↓ +--------------------+ ↓
↓ | Outgoing phase | ↓ -> Receives response from target server
↓ |~~~~~~~~~~~~~~~~~~~~| ↓
↓ | ---------------- | ↓
↓ | | Exec Rules | | ↓ -> Apply configured rules for the outgoing request
↓ | ---------------- | ↓
↓ | ||| | ↓
↓ | ---------------- | ↓
↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow before send it to the client
↓ | ---------------- | ↓
↓ +~~~~~~~~~~~~~~~~~~~~+ ↓
↓ ||| ↓
↓ ( Send to the client ) ↓ -> Finally, send the request to the client, either poisoned or not


Usage

Installation
npm install toxy

Examples
See examples directory for more use cases.
var toxy = require('toxy')
var poisons = toxy.poisons
var rules = toxy.rules

// Create a new toxy proxy
var proxy = toxy()

// Default server to forward incoming traffic
proxy
.forward('http://httpbin.org')

// Register global poisons and rules
proxy
.poison(poisons.latency({ jitter: 500 }))
.rule(rules.probability(25))

// Register multiple routes
proxy
.get('/download/*')
.forward('http://files.myserver.net')
.poison(poisons.bandwidth({ bps: 1024 }))
.withRule(rules.headers({'Authorization': /^Bearer (.*)$/i }))

// Infect outgoing traffic only (after the server replied properly)
proxy
.get('/image/*')
.outgoingPoison(poisons.bandwidth({ bps: 512 }))
.withRule(rules.method('GET'))
.withRule(rules.timeThreshold({ duration: 1000, threshold: 1000 * 10 }))
.withRule(rules.responseStatus({ range: [ 200, 400 ] }))

proxy
.all('/api/*')
.poison(poisons.rateLimit({ limit: 10, threshold: 1000 }))
.withRule(rules.method(['POST', 'PUT', 'DELETE']))
// And use a different more permissive poison for GET requests
.poison(poisons.rateLimit({ limit: 50, threshold: 1000 }))
.withRule(rules.method('GET'))

// Handle the rest of the traffic
proxy
.all('/*')
.poison(poisons.slowClose({ delay: 1000 }))
.poison(poisons.slowRead({ bps: 128 }))
.withRule(rules.probability(50))

proxy.listen(3000)
console.log('Server listening on port:', 3000)
console.log('Test it:', 'http://localhost:3000/image/jpeg')

Poisons
Poisons host specific logic which intercepts and mutates, wraps, modify and/or cancel an HTTP transaction in the proxy server. Poisons can be applied to incoming or outgoing, or even both traffic flows.
Poisons can be composed and reused for different HTTP scenarios. They are executed in FIFO order and asynchronously.

Poisoning scopes
toxy has a hierarchical design based on two different scopes: global and route .
Global scope points to all the incoming HTTP traffic received by the proxy server, regardless of the HTTP method or path.
Route scope points to any incoming traffic which matches with a specific HTTP verb and URI path.
Poisons can be plugged to both scopes, meaning you can operate with better accuracy and restrict the scope of the poisoning, for instance, you might wanna apply a bandwidth limit poisoning only to a certain routes, such as /download or /images .
See routes.js for a featured example.

Poisoning phases
Poisons can be plugged to incoming or outgoing traffic flows, or even both.
Incoming poisoning is applied when the traffic has been received by proxy but it has not been forwarded to the target server yet.
Outgoing poisoning refers to the traffic that has been forwarded to the target server and when proxy recieves the response from it, but that response has not been sent to the client yet.
This means, essentially, that you can plug in your poisons to infect the HTTP traffic before or after the request is forwarded to the target HTTP server or sent to the client.
This allows you apply a better and more accurated poisoning based on the request or server response. For instance, given the nature of some poisons, like inject error , you may want to enable it according to the target server response (e.g: some header is present or not).
See poison-phases.js for a featured example.

Built-in poisons

Latency
Name latency
Poisoning Phase incoming / outgoing
Reaches the server true
Infects the HTTP flow injecting a latency jitter in the response
Arguments :
  • options object
    • jitter number - Jitter value in miliseconds
    • max number - Random jitter maximum value
    • min number - Random jitter minimum value
toxy.poison(toxy.poisons.latency({ jitter: 1000 }))
// Or alternatively using a random value
toxy.poison(toxy.poisons.latency({ max: 1000, min: 100 }))

Inject response
Name inject
Poisoning Phase incoming / outgoing
Reaches the server false (only as incoming poison)
Injects a custom response, intercepting the request before sending it to the target server. Useful to inject errors originated in the server.
Arguments :
  • options object
    • code number - Response HTTP status code. Default 500
    • headers object - Optional headers to send
    • body mixed - Optional body data to send. It can be a buffer or string
    • encoding string - Body encoding. Default to utf8
toxy.poison(toxy.poisons.inject({
code: 503,
body: '{"error": "toxy injected error"}',
headers: {'Content-Type': 'application/json'}
}))

Bandwidth
Name bandwidth
Poisoning Phase incoming / outgoing
Reaches the server true
Limits the amount of bytes sent over the network in outgoing HTTP traffic for a specific time frame.
This poison is basically an alias to throttle.
Arguments :
  • options object
    • bytes number - Amount of chunk of bytes to send. Default 1024
    • threshold number - Packets time frame in miliseconds. Default 1000
toxy.poison(toxy.poisons.bandwidth({ bytes: 512 }))

Rate limit
Name rateLimit
Poisoning Phase incoming / outgoing
Reaches the server true
Limits the amount of requests received by the proxy in a specific threshold time frame. Designed to test API limits. Exposes typical X-RateLimit-* headers.
Note that this is very simple rate limit implementation, indeed limits are stored in-memory, therefore are completely volalite. There're a bunch of featured and consistent rate limiter implementations in npm that you can plug in as poison. You might be also interested in token bucket algorithm.
Arguments :
  • options object
    • limit number - Total amount of requests. Default to 10
    • threshold number - Limit time frame in miliseconds. Default to 1000
    • message string - Optional error message when limit is reached.
    • code number - HTTP status code when limit is reached. Default to 429 .
toxy.poison(toxy.poisons.rateLimit({ limit: 5, threshold: 10 * 1000 }))

Slow read
Name rateLimit
Poisoning Phase incoming
Reaches the server true
Reads incoming payload data packets slowly. Only valid for non-GET request.
Arguments :
  • options object
    • chunk number - Packet chunk size in bytes. Default to 1024
    • threshold number - Limit threshold time frame in miliseconds. Default to 1000
toxy.poison(toxy.poisons.slowRead({ chunk: 2048, threshold: 1000 }))

Slow open
Name: slowOpen
Name slowOpen
Poisoning Phase incoming
Reaches the server true
Delays the HTTP connection ready state.
Arguments :
  • options object
    • delay number - Delay connection in miliseconds. Default to 1000
toxy.poison(toxy.poisons.slowOpen({ delay: 2000 }))

Slow close
Name slowClose
Poisoning Phase incoming / outgoing
Reaches the server true
Delays the HTTP connection close signal (EOF).
Arguments :
  • options object
    • delay number - Delay time in miliseconds. Default to 1000
toxy.poison(toxy.poisons.slowClose({ delay: 2000 }))

Throttle
Name throttle
Poisoning Phase incoming / outgoing
Reaches the server true
Restricts the amount of packets sent over the network in a specific threshold time frame.
Arguments :
  • options object
    • chunk number - Packet chunk size in bytes. Default to 1024
    • delay object - Data chunk delay time frame in miliseconds. Default to 100
toxy.poison(toxy.poisons.throttle({ chunk: 2048, threshold: 1000 }))

Abort connection
Name abort
Poisoning Phase incoming / outgoing
Reaches the server false (only as incoming poison)
Aborts the TCP connection. From the low-level perspective, this will destroy the socket on the server, operating only at TCP level without sending any specific HTTP application level data.
Arguments :
  • options object
    • delay number - Aborts TCP connection after waiting the given miliseconds. Default to 0
    • next boolean - If true , the connection will be aborted if the target server takes more than the delay param time to reply. Default to false
    • error Error - Custom internal node.js error to use when destroying the socket. Default to null
// Basic connection abort
toxy.poison(toxy.poisons.abort())
// Abort after a delay
toxy.poison(toxy.poisons.abort(1000))
// In this case, the socket will be closed if
// the target server takes more than
// 2 seconds to respond
toxy.poison(toxy.poisons.abort({ delay: 2000, next: true }))

Timeout
Name timout
Poisoning Phase incoming / outgoing
Reaches the server true
Defines a response timeout. Useful when forward to potentially slow servers.
Arguments :
  • miliseconds number - Timeout limit in miliseconds
toxy.poison(toxy.poisons.timeout(5000))

How to write poisons
Poisons are implemented as standalone middleware (like in connect/express).
Here's a simple example of a server latency poison:
var toxy = require('toxy')

function customLatency(delay) {
/**
* We name the function since toxy uses it as identifier to get/disable/remove it in the future
*/
return function customLatency(req, res, next) {
var timeout = setTimeout(clean, delay)
req.once('close', onClose)

function onClose() {
clearTimeout(timeout)
next('client connection closed')
}

function clean() {
req.removeListener('close', onClose)
next()
}
}
}

var proxy = toxy()

// Register and enable the poison
proxy
.get('/foo')
.poison(customLatency(2000))
You can optionally extend the build-in poisons with your own poisons:
toxy.addPoison(customLatency)

// Then you can use it as a built-in poison
proxy
.get('/foo')
.poison(toxy.poisons.customLatency)
For featured real example, take a look to the built-in poisons implementation.

Rules
Rules are simple validation filters which inspects an incoming or outgoing HTTP traffic in order to determine, given a certain rules (e.g: matches the method, headers, query params, body...), if the current HTTP transaction should be poisoned or not, based on the resolution value of the rule.
Rules are useful to compose, decouple and reuse logic among different scenarios of poisoning. Rules can be applied to global, route or even poison scope, and it also applies to both phases of poisoning .
Rules are executed in FIFO order. Their evaluation logic is equivalent to Array#every() in JavaScript: all the rules must pass in order to proceed with the poisoning.

Built-in rules

Probability
Name probability
Poison Phase incoming / outgoing
Enables the rule by a random probabilistic. Useful for random poisoning.
Arguments :
  • percentage number - Percentage of filtering. Default 50
var rule = toxy.rules.probability(85)
toxy.rule(rule)

Time threshold
Name timeThreshold
Poison Phase incoming / outgoing
Simple rule to enable poisons based on a specific time threshold and duration. For instance, you can enable a certain poisons during a specific amount of time (e.g: 1 second) within a time threshold (e.g: 1 minute).
Arguments :
  • options object
    • duration number - Enable time inverval in miliseconds. Default to 1000
    • threshold number - Time threshold in miliseconds to wait before re-enable the poisoning. Default to 10000
// Enable the poisoning only 100 miliseconds per each 10 seconds
proxy.rule(toxy.rules.timeThreshold(100))
// Enable poisoning during 1 second every minute
proxy.rule(toxy.rules.timeThreshold({ duration: 1000, period: 1000 * 60 }))

Method
Name method
Poison Phase incoming / outgoing
Filters by HTTP method.
Arguments :
  • method string|array - Method or methods to filter.
var method = toxy.rules.method(['GET', 'POST'])
toxy.rule(method)

Content Type
Filters by content type header. It should be present
Arguments :
  • value string|regexp - Header value to match.
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)

Headers
Name headers
Poison Phase incoming / outgoing
Filter by request headers.
Arguments :
  • headers object - Headers to match by key-value pair. value can be a string, regexp, boolean or function(headerValue, headerName) => boolean
var matchHeaders = {
'content-type': /^application/\json/i,
'server': true, // meaning it should be present,
'accept': function (value, key) {
return value.indexOf('text') !== -1
}
}

var rule = toxy.rules.headers(matchHeaders)
toxy.rule(rule)

Response headers
Name responseHeaders
Poison Phase outgoing
Filter by response headers from target server. Same as headers rule, but evaluating the outgoing request.
Arguments :
  • headers object - Headers to match by key-value pair. value can be a string , regexp , boolean or function(headerValue, headerName) => boolean
var matchHeaders = {
'content-type': /^application/\json/i,
'server': true, // meaning it should be present,
'accept': function (value, key) {
return value.indexOf('text') !== -1
}
}

var rule = toxy.rules.responseHeaders(matchHeaders)
toxy.rule(rule)

Body
Name body
Poison Phase incoming / outgoing
Match incoming body payload by a given string , regexp or custom filter function .
This rule is pretty simple, so for complex body matching (e.g: validating against a JSON schema) you should probably write your own rule.
Arguments :
  • match string|regexp|function - Body content to match
  • limit string - Optional. Body limit in human size. E.g: 5mb
  • encoding string - Body encoding. Default to utf8
  • length number - Body length. Default taken from Content-Length header
var rule = toxy.rules.body('"hello":"world"')
toxy.rule(rule)

// Or using a filter function returning a boolean
var rule = toxy.rules.body(function contains(body) {
return body.indexOf('hello') !== -1
})
toxy.rule(rule)

Response body
Name responseBody
Poison Phase outgoing
Match outgoing body payload by a given string , regexp or custom filter function .
Arguments :
  • match string|regexp|function - Body content to match
  • encoding string - Body encoding. Default to utf8
  • length number - Body length. Default taken from Content-Length header
var rule = toxy.rules.responseBody('"hello":"world"')
toxy.rule(rule)

// Or using a filter function returning a boolean
var rule = toxy.rules.responseBody(function contains(body) {
return body.indexOf('hello') !== -1
})
toxy.rule(rule)

Response status
Name responseStatus
Poison Phase outgoing
Evaluates the response status from the target server. Only applicable to outgoing poisons.
Arguments :
  • range array - Pair of status code range to match. Default [200, 300] .
  • lower number - Compare status as lower than operation. Default to null .
  • higher number - Compare status as higher than operation. Default to null .
  • value number - Status code to match using a strict equality comparison. Default null .
  • include array - Unordered list of status codes to match. Useful to specify custom status. Default null
// Strict evaluation of the status code
toxy.rule(toxy.rules.responseBody(200))
// Using a range of valid status
toxy.rule(toxy.rules.responseBody([200, 204]))
// Using relational comparison
toxy.rule(toxy.rules.responseBody({ higher: 199, lower: 400 }))
// Custom unordered status code to match
toxy.rule(toxy.rules.responseBody({ include: [200, 204, 400, 404] }))

Third-party rules
List of available third-party rules provided by the community. PR are welcome.
  • IP - Enable/disable poisons based on the client IP address (supports CIDR, subnets, ranges...).

How to write rules
Rules are simple middleware functions that resolve asyncronously with a boolean value to determine if a given HTTP transaction should be ignored when poisoning.
Your rule must resolve with a boolean param calling the next(err, shouldIgnore) function in the middleware, passing a true value if the rule has not matches and should not apply the poisoning, and therefore continuing with the next middleware stack.
Here's an example of a simple rule matching the HTTP method to determine if:
var toxy = require('toxy')

function customMethodRule(matchMethod) {
/**
* We name the function since it's used by toxy to identify the rule to get/disable/remove it in the future
*/
return function customMethodRule(req, res, next) {
var shouldIgnore = req.method !== matchMethod
next(null, shouldIgnore)
}
}

var proxy = toxy()

// Register and enable the rule
proxy
.get('/foo')
.rule(customMethodRule('GET'))
.poison(/* ... */)
You can optionally extend the build-in rules with your own rules:
toxy.addRule(customMethodRule)

// Then you can use it as a built-in poison
proxy
.get('/foo')
.rules(toxy.rules.customMethodRule)
For featured real examples, take a look to the built-in rules implementation

Programmatic API
toxy API is completely built on top the rocky API . In other words, you can use any of the methods, features and middleware layer natively provided by rocky .

toxy([ options ])
Create a new toxy proxy.
For supported options , please see rocky documentation
var toxy = require('toxy')

toxy({ forward: 'http://server.net', timeout: 30000 })

toxy
.get('/foo')
.poison(toxy.poisons.latency(1000))
.withRule(toxy.rules.contentType('json'))
.forward('http://foo.server')

toxy
.post('/bar')
.poison(toxy.poisons.bandwidth({ bps: 1024 }))
.withRule(toxy.rules.probability(50))
.forward('http://bar.server')

toxy
.post('/boo')
.outgoingPoison(toxy.poisons.bandwidth({ bps: 1024 }))
.withRule(toxy.rules.method('GET'))
.forward('http://boo.server')

toxy.all('/*')

toxy.listen(3000)

toxy#get(path, [ middleware... ])
Return: ToxyRoute
Register a new route for GET method.

toxy#post(path, [ middleware... ])
Return: ToxyRoute
Register a new route for POST method.

toxy#put(path, [ middleware... ])
Return: ToxyRoute
Register a new route for PUT method.

toxy#patch(path, [ middleware... ])
Return: ToxyRoute

toxy#delete(path, [ middleware... ])
Return: ToxyRoute
Register a new route for DELETE method.

toxy#head(path, [ middleware... ])
Return: ToxyRoute
Register a new route for HEAD method.

toxy#all(path, [ middleware... ])
Return: ToxyRoute
Register a new route for any method.

toxy#poisons => Object
Exposes a map with the built-in poisons. Prototype alias to toxy.poisons

toxy#rules => Object
Exposes a map with the built-in poisons. Prototype alias to toxy.rules

toxy#forward(url)
Define a URL to forward the incoming traffic received by the proxy.

toxy#balance(urls)
Forward to multiple servers balancing among them.
For more information, see the rocky docs

toxy#replay(url)
Define a new replay server. You can call this method multiple times to define multiple replay servers.
For more information, see the rocky docs

toxy#use(middleware)
Plug in a custom middleware.
For more information, see the rocky docs .

toxy#useResponse(middleware)
Plug in a response outgoing traffic middleware.
For more information, see the rocky docs .

toxy#useReplay(middleware)
Plug in a replay traffic middleware.
For more information, see the rocky docs

toxy#requestBody(middleware)
Intercept incoming request body. Useful to modify it on the fly.
For more information, see the rocky docs

toxy#responseBody(middleware)
Intercept outgoing response body. Useful to modify it on the fly.
For more information, see the rocky docs

toxy#middleware()
Return a standard middleware to use with connect/express.

toxy#host(host)
Overwrite the Host header with a custom value. Similar to forwardHost option.

toxy#redirect(url)
Redirect traffic to the given URL.

toxy#findRoute(routeIdOrPath, [ method ])
Find a route by ID or path and method.

toxy#listen(port)
Starts the built-in HTTP server, listening on a specific TCP port.

toxy#close([ callback ])
Closes the HTTP server.

toxy#poison(poison)
Alias: usePoison , useIncomingPoison
Register a new poison to infect incoming traffic.

toxy#outgoingPoison(poison)
Alias: useOutgoingPoison , responsePoison
Register a new poison to infect outgoing traffic.

toxy#rule(rule)
Alias: useRule
Register a new rule.

toxy#withRule(rule)
Aliases: poisonRule , poisonFilter
Apply a new rule for the latest registered poison.

toxy#enable(poison)
Enable a poison by name identifier

toxy#disable(poison)
Disable a poison by name identifier

toxy#remove(poison)
Return: boolean
Remove poison by name identifier.

toxy#isEnabled(poison)
Return: boolean
Checks if a poison is enabled by name identifier.

toxy#disableAll()
Alias: disablePoisons
Disable all the registered poisons.

toxy#getPoison(name)
Return: Directive|null
Searchs and retrieves a registered poison in the stack by name identifier.

toxy#getIncomingPoison(name)
Return: Directive|null
Searchs and retrieves a registered incoming poison in the stack by name identifier.

toxy#getOutgoingPoison(name)
Return: Directive|null
Searchs and retrieves a registered outgoing poison in the stack by name identifier.

toxy#getPoisons()
Return: array<Directive>
Return an array of registered poisons.

toxy#getIncomingPoisons()
Return: array<Directive>
Return an array of registered incoming poisons.

toxy#getOutgoingPoisons()
Return: array<Directive>
Return an array of registered outgoing poisons.

toxy#flush()
Alias: flushPoisons
Remove all the registered poisons.

toxy#enableRule(rule)
Enable a rule by name identifier.

toxy#disableRule(rule)
Disable a rule by name identifier.

toxy#removeRule(rule)
Return: boolean
Remove a rule by name identifier.

toxy#disableRules()
Disable all the registered rules.

toxy#isRuleEnabled(rule)
Return: boolean
Checks if the given rule is enabled by name identifier.

toxy#getRule(rule)
Return: Directive|null
Searchs and retrieves a registered rule in the stack by name identifier.

toxy#getRules()
Return: array<Directive>
Returns and array with the registered rules wrapped as Directive .

toxy#flushRules()
Remove all the rules.

toxy.addPoison(name, fn)
Extend built-in poisons.

toxy.addRule(name, fn)
Extend built-in rules.

toxy.poisons => Object
Exposes a map with the built-in poisons.

toxy.rules => Object
Exposes a map with the built-in rules.

toxy.VERSION => String
Current toxy semantic version.

ToxyRoute
ToxyRoute exposes the same interface as Toxy global interface, it just adds some route level additional methods .
Further actions you perform againts the ToxyRoute API will only be applicable at route-level (nested). In other words: you already know the API.
This example will probably clarify possible doubts:
var toxy = require('toxy')
var proxy = toxy()

// Now using the global API
proxy
.forward('http://server.net')
.poison(toxy.poisons.bandwidth({ bps: 1024 }))
.rule(toxy.rules.method('GET'))

// Now create a route
var route = proxy
.get('/foo')
.toPath('/bar') // Route-level API method
.host('server.net') // Route-level API method
.forward('http://new.server.net')

// Now using the ToxyRoute interface
route
.poison(toxy.poisons.bandwidth({ bps: 512 }))
.rule(toxy.rules.contentType('json'))

Directive(middlewareFn)
A convenient wrapper internally used for poisons and rules.
Normally you don't need to know this interface, but for hacking purposes or more low-level actions might be useful.

Directive#enable()
Return: boolean

Directive#disable()
Return: boolean

Directive#isEnabled()
Return: boolean

Directive#rule(rule)
Alias: filter

Directive#handler()
Return: function(req, res, next)

HTTP API
The toxy HTTP API follows the JSON API conventions, including resource based hypermedia linking.

Usage
For a featured use case, see the admin server example.
const toxy = require('toxy')

// Create the toxy admin server
var admin = toxy.admin({ cors: true })
admin.listen(9000)

// Create the toxy proxy
var proxy = toxy()
proxy.listen(3000)

// Add the toxy instance to be managed by the admin server
admin.manage(proxy)

// Then configure the proxy
proxy
.forward('http://my.target.net')

proxy
.get('/slow')
.poison(toxy.poisons.bandwidth({ bps: 1024 }))

// Handle the rest of the traffic
proxy
.all('/*')
.poison(toxy.poisons.bandwidth({ bps: 1024 * 5 }))

console.log('toxy proxy listening on port:', 3000)
console.log('toxy admin server listening on port:', 9000)
For more details about the admin programmatic API, see below .

Authorization
The HTTP API can be protected to unauthorized clients. Authorized clients must define the API key token via API-Key or Authorization HTTP headers.
To enable it, you should simple pass the following options to toxy admin server:
const toxy = require('toxy')

const opts = { apiKey: 's3cr3t' }
var admin = toxy.admin(opts)

admin.listen(9000)
console.log('protected toxy admin server listening on port:', 9000)

API
Hierarchy :
  • Servers - Managed toxy instances
    • Rules - Globally applied rules
    • Poisons - Globally applied poisons
      • Rules - Poison-specific rules
    • Routes - List of configured routes
      • Route - Object for each specific route
        • Rules - Route-level registered rules
        • Poisons - Route-level registered poisons
          • Rules - Route-level poison-specific rules

GET /

Servers

GET /servers

GET /servers/:id

Rules

GET /servers/:id/rules

POST /servers/:id/rules
Accepts: application/json
Example payload:
{
"name": "method",
"options": "GET"
}

DELETE /servers/:id/rules

GET /servers/:id/rules/:id

DELETE /servers/:id/rules/:id

Poisons

GET /servers/:id/poison

POST /servers/:id/poisons
Accepts: application/json
Example payload:
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}

DELETE /servers/:id/poisons

GET /servers/:id/poisons/:id

DELETE /servers/:id/poisons/:id

GET /servers/:id/poisons/:id/rules

POST /servers/:id/poisons/:id/rules
Accepts: application/json
Example payload:
{
"name": "method",
"options": "GET"
}

DELETE /servers/:id/poisons/:id/rules

GET /servers/:id/poisons/:id/rules/:id

DELETE /servers/:id/poisons/:id/rules/:id

Routes

GET /servers/:id/routes

POST /servers/:id/routes
Accepts: application/json
Example payload:
{
"path": "/foo", // Required
"method": "GET", // use ALL for all the methods
"forward": "http://my.server", // Optional custom forward server URL
}

DELETE /servers/:id/routes

GET /servers/:id/routes/:id

DELETE /servers/:id/routes/:id

Route rules

GET /servers/:id/routes/:id/rules

POST /servers/:id/routes/:id/rules
Accepts: application/json
Example payload:
{
"name": "method",
"options": "GET"
}

DELETE /servers/:id/routes/:id/rules

GET /servers/:id/routes/:id/rules/:id

DELETE /servers/:id/routes/:id/rules/:id

Route poisons

GET /servers/:id/routes/:id/poisons

POST /servers/:id/routes/:id/poisons
Accepts: application/json
Example payload:
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}

DELETE /servers/:id/routes/:id/poisons

GET /servers/:id/routes/:id/poisons/:id

DELETE /servers/:id/routes/:id/poisons/:id

GET /servers/:id/routes/:id/poisons/:id/rules

POST /servers/:id/routes/:id/poisons/:id/rules
Accepts: application/json
Example payload:
{
"name": "method",
"options": "GET"
}

DELETE /servers/:id/routes/:id/poisons/:id/rules

GET /servers/:id/routes/:id/poisons/:id/rules/:id

DELETE /servers/:id/routes/:id/poisons/:id/rules/:id

Programmatic API
The built-in HTTP admin server also provides a simple interface open to extensibility and hacking purposes. For instance, you can plug in additional middleware to the admin server, or register new routes.

toxy.admin([ opts ])
Returns: Admin
Supported options :
  • apiKey string - Optional API key to protect the server
  • port number - Optional. TCP port to listen
  • cors boolean - Enable CORS for web browser access
  • middleware array<function> - Plug in additional middleware
  • ssl object - Node.js HTTPS server TLS options .

Admin#listen([ port, host ])
Start listening on the network.

Admin#manage(toxy)
Manage a toxy server instance.

Admin#find(toxy)
Find a toxy instance. Accepts toxy server ID or toxy instance.

Admin#remove(toxy)
Stop managing a toxy instance.

Admin#use(...middleware)
Register a middleware.

Admin#param(...middleware)
Register a param middleware.

Admin#get(path, [ ...middleware ])
Register a GET route.

Admin#post(path, [ ...middleware ])
Register a POST route.

Admin#put(path, [ ...middleware ])
Register a PUT route.

Admin#delete(path, [ ...middleware ])
Register a DELETE route.

Admin#patch(path, [ ...middleware ])
Register a PATCH route.

Admin#all(path, [ ...middleware ])
Register a route accepting any HTTP method.

Admin#middleware(req, res, next)
Middleware to plug in with connect/express.

Admin#close(cb)
Stop the server.


Share:
Established in 2015. Offensive Sec Blog has been sharing security research, hacking tools, threat intelligence, and offensive security content since 2015.
Copyright © OffSec Blog | Powered by OffensiveSec
Design by OffSec | Built for the security community