Home

Awesome

erlamsa

Erlamsa -- "<<smart>> dumb fuzzer" aka erlang port of famous radamsa fuzzer.

TL;DR

$ sudo apt-get install git gcc make erlang erlang-dev erlang-tools erlang-ssl erlang-eunit erlang-mnesia erlang-inets
$ git clone https://github.com/Darkkey/erlamsa && cd erlamsa && make
$ echo 'Hello erlamsa!' | ./erlamsa

Features

Installation:

Prerequisites

Git, Erlang. If you want to use raw IP output, gcc and make are required to build procket.

Installing erlang

Erlamsa requires erlang/OTP 18.0+ to run.

Download erlang from official website http://www.erlang.org, install and put in path to erlc, erl and escript binaries into PATH variable. Or use your system's packet manager to install it.

On OS X (using homebrew):

brew install erlang

On CentOS/RHEL:

yum install erlang

On Debian/Ubuntu/Kali:

apt-get install erlang erlang-dev erlang-tools erlang-ssl erlang-eunit erlang-mnesia erlang-inets

Building erlamsa

Get the latest version of erlamsa:

git clone https://github.com/Darkkey/erlamsa
cd erlamsa

On Linux/OS X/BSD:

make 

On Windows (escript.exe and erlc.exe should be in %PATH%):

make_windows.bat

Docker

Alternatively, you could use erlamsa Docker container: https://github.com/Darkkey/erlamsa-docker-image

Standalone usage:

Under Linux/OS X use ./erlamsa, under Windows -- erlamsa.bat.

Few examples/templates for a quick start:

$ echo 'Hello erlamsa' | ./erlamsa
Hello erlmo erlamsa
$ ./erlamsa <<FILE TO FUZZ>>
$ ./erlamsa <<FILE TO FUZZ>> -o <<FILE TO FUZZ>>.fuzzed
$ ./erlamsa <<FILE TO FUZZ>> -o tcp://:<<LISTEN_ON_PORT>>
$ cat <<BINARY WITH PACKET>> | ./erlamsa -o udp://<<HOST>>:<<PORT>>
$ cat <<FILE WITH POST QUERY>> | ./erlamsa -o https://<<SERVER>>:<<PORT>>/script.jsp?param1=value,POST,<<Header1>>=<<Header1value>>
$ ./erlamsa <<BINARY WITH PACKET>> -o serial:///dev/ttyUSB0,9600
$ echo '<<DATA>>' | ./erlamsa exec://<<APP_TO_FUZZ_FROM_STDIO>>

For help try:

./erlamsa --help

or

escript erlamsa --help

Also try --list option to show all possible inputs, outputs, mutators, patterns, loggers and monitors.

Using as a service

Launch as a service:

./erlamsa -H 127.0.0.1:17771 -L -

Or, in detached mode (erlamsa will go background after launch):

./erlamsa -H 127.0.0.1:17771 -D

HTTP POST your data to http://<Host:Port>/erlamsa/erlamsa_esi:fuzz as application/octet-stream. See examples in clients/ folder (provided for C#, Go, Node.js and python2/3). E.g. for Python 2.7:

import httplib

erlamsa_url = '127.0.0.1:17771'

original_string = "Hello erlamsa!"

httpconn = httplib.HTTPConnection(erlamsa_url)
headers = {"content-type": "application/octet-stream"}
httpconn.request('POST', '/erlamsa/erlamsa_esi:fuzz', original_string, headers)
response = httpconn.getresponse()

fuzzed_string = response.read()

print(original_string + " erlamsed to " + fuzzed_string)

Result:

$ python clients/erlamsa_python_client.py
Hello erlamsa! erlamsed to rlamsa!rlallo eHello e

JSON service endpoint

Erlamsa also provides JSON service extension, which allows to send request in JSON documents. Fuzzing data should be encoded in base64 format and provided inside data field of the document, e.g.:

$ curl -H "Content-Type: application/json" -X POST -d '{"data":"aGVsbG8="}' http://localhost:17771/erlamsa/erlamsa_esi:json
{"data": "bGxvbGxvaA=="}

PyErlamsa module

For Python 3 you could use more handy pyerlamsa (check https://github.com/Darkkey/pyerlamsa/ for more info) module:

Connecting to local erlamsa instance:

$ pip3 install pyerlamsa
$ python3
...
>>> import pyerlamsa
>>> e = pyerlamsa.Erlamsa('http://127.0.0.1:17771')
>>> e.call('Hello erlamsa!');
(True, 'Hell4amsa15i685\x81\x91')

Connecting to erlamsa cloud:

...
>>> e = pyerlamsa.Erlamsa('https://erlamsa.online', token="yourtoken")
>>> e.call('Hello erlamsa!');
(True, '%n erlamsa!')
>>> e.call('Hello erlamsa!');
(True, 'lamsa!lo\x1ferHel')
>>> e.call('Hello erlamsa!');
(True, 'Hello erlamsa!Hello erlamsa!')

Fuzzing options

For standalone Web or JSON fuzzing, along with fuzzing data, you could also provide fuzzing options, including mutations, patterns, seed, blockscale, e.t.c. The format of these options should be the same as in according command line keys. Pass them as HTTP headers (for standalone Web service) or as JSON members (for JSON endpoint). E.g.:

$ curl -H "Content-Type: application/json" -X POST -d '{"data":"aGVsbG8=","seed": "1,2,3"}' http://localhost:17771/erlamsa/erlamsa_esi:json
{"data": "aGVsW2xv"}

Using as fuzzing proxy

Erlamsa could be used a fuzzing "MiTM" proxy for HTTP(s), TCP (also TLS) and UDP protocols. This allow to fuzz the communication between server and client, modifying packets coming from server to client, from client to server, or in both cases.

To use it as fuzzing proxy, run as:

./erlamsa -i proto://lport:[udpclientport:]rhost:rport -P probsc,probcs

where probsc and probcs are floats in range of 0.0 to 1.0, that represents probabilities of fuzzing packets from server to client and client to server.

E.g. erlamsa, that is started as

./erlamsa -i tcp://7777:192.168.0.1:7777 -P 0.1,0.7 -L -

will accept packets on port 7777 (on all network interfaces, basically on 0.0.0.0 interface) and send them to host's 192.168.0.1 port 7777. All packets coming from server to client will be fuzzed with probability of 0.1(10%), from client to server -- with probability of 0.7(70%). In this case, to start fuzzing just point your client application to erlamsa's host and port 7777. -L - options means that all logging will be output to stdout.

Addtionally, erlamsa supports so-called "standalone http-proxy mode", when erlamsa proxifies connections as standard HTTP-proxy and fuzzing requests/replies based on provide probabilities. To use erlamsa in this mode, please use e.g.:

./erlamsa -i http://proxy:7777 -P 0.1,0.7 -L -

Then, specify in the target HTTP proxy settings erlamsa host as a hostname and 7777 as proxy port. If you're planning to fuzz TLS-connections, don't forget to supply correct certificate to erlamsa via --certfile and --keyfile options. If target is using binary connection, please user tcp instead of http in -i option.

Example usage from erlang code

There are two possible ways to call erlamsa from your code: static (same host, library call) and dynamic (query the application on another node)

  1. Static direct usage: see erlamsa_app:fuzz/1 and erlamsa_app:fuzz/2, e.g.:
$ erl -pa ebin -pa deps/*/ebin
...
Eshell V10.0.3  (abort with ^G)

1> erlamsa_app:fuzz(<<"123">>).
<<243,160,128,169,49,50,51>>
2>
  1. Remotely, on another node:

    a) Start and test fuzzing node:

    $ erl -pa ebin -pa deps/*/ebin -sname erlamsa
    ...
    
    (erlamsa@server)1> erlamsa_app:start(direct, maps:new()).
    ok
    (erlamsa@server)2> erlamsa_app:call(erlamsa, <<"123">>).
    <<"12311223123">>
    (erlamsa@server)3>
    

    b) Run on client node:

    $ erl -pa ebin -pa deps/*/ebin -sname client
    ...
    
    (client@user)1> erlamsa_app:start(remote, {erlamsa, 'erlamsa@server'}).
    {test,<0.66.0>}
    (client@user)2> erlamsa_app:call(erlamsa, <<"321">>).
    <<"3321">>
    

External (extension) scripts

Erlamsa could use external scripts for generation-based fuzzing, custom fuzzing, custom post-fuzzing procedures or custom mutation types. Module should be compiled with erlc before using and passed using -e option to erlamsa. Due to internal mechanism of external modules inclusion, you should pass external module ALWAYS as a FIRST argument to erlamsa.

In the following example, erlamsa is run with custom mutation module (see external_muta.erl for details):

$ echo -n 123 | ./erlamsa -e external_muta -m pan=1 -p od
<pancaked>123</pancaked>

Custom fuzzing extension

Could be used in fuzzing proxy mode, to replace standard fuzzing procedure with a custom one. See external_test.erl for example template.

Custom mutation extension

Adds custom mutation to the list of erlamsa mutators. See external_muta.erl for example.

Custom post-processing extension

Adds post-processing procedure that will be applied to fuzzing result just before output. Useful for fixing checksum or form of data to avoid unnessesary noise. See external_nhrp.erl for example.

Monitors

Erlamsa is using monitors, special modules that are intended to detect various events, like application crashes, freezes, SSRFs, backconnects, e.t.c. Monitor is waiting for some event, and, upon receiving it, reports to the logs and execute specified after actions. Each monitor is a separate process, that could be initiated via passing -O name:params in the command line. By default, cm (connect monitor) is run. To disable monitors that are run by default, one could pass -O !monitor_name:off in the command line. E.g., to disable connection monitor, pass -O !cm:off as an command line option to erlamsa.

Monitor parameters

Parameters are passed to monitors in a form of comma-delimeted list, e.g.: -O monitor_name:param1=value1,.... Parameters are split to the generic ones and monitor-specific ones. Generic ones include:

Monitors list

Below, it could be found all currently supported by erlamsa monitors and corresponding parameters:

Platform limitations

Warning

Erlamsa is a tool that tries to generate data that could be used for testing programs against unexpected data. Thus, using erlamsa against software that may contain bugs (especially in a case when it is running with high privileges), can result in crashes, freezes, reboots, kernel panics, bluescreens, loss of data and other stuff. DO NOT use it against production system or under high-privilege user account. Using emulators or disposable systems is highly recommended.

Remember, that THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Code Status

Build Status