Fingerprinting module

deadc0de edited this page Apr 23, 2018 · 14 revisions


Implement a fingerprinting module

All fingerprinting modules are based on the fp_module behavior. Therefore any fingerprinting module must implement the following functions:

  • get_default_args/0: is called by the broker to retrieve the different arguments of the module in the form of a args record. Especially the following elements should be provided:
    • module: name of the module
    • type: type of the module (tcp, udp or ssl)
    • port: the port (can be overwritten with the -p switch)
    • timeout: the timeout in milli-seconds (can be overwritten with the -t switch)
    • maxpkt: max number of packets to handle (can be overwritten with the -j switch)
    • fsmopts for an ssl module: provides the option to the socket, especially related to sslcheck and sni
  • get_description/0: is called when the -l switch is provided to show a short description of the modules.
  • get_arguments/0: is called when the -l switch is provided to get the arguments.
  • callback_next_step/1: is explained below

Skeletons are available in this folder to get started.


This function is the callback of your module. Scannerl will handle the entire transport layer communication (connecting, sending data, receiving responses, ...) and will call the fingerprinting module after each of these steps in order to know what to do next.

The argument provided to callback_next_step is a record of type args containing all information on the target and more.

The return value gives information to scannerl on what to do next. The different return values are available in the fp_module file:

  • continue instructs scannerl to keep interacting with the remote host. Its format is {continue, Nbpacket, Payload, ModData}.
    • Nbpacket defines the maximum number of packet to receive before calling the callback again
    • Payload defines the payload to send to the remote host
    • ModData is the data that will be provided back to callback_next_step through Args#args.moddata next time it is called. It's up to the module to store whatever is needed in there.
  • restart instructs scannerl to entirely restart the communication with the remote host. Its format is {restart, {Target, Port}, ModData}.
    • {Target, Port} defines the target and the port to communicate with
    • ModData is user data as for continue
  • results instructs scannerl that the fingerprinting is done and some results need to be forwarded to output. Its format is {result, Result}. See readme for more info on the result format.

A typical implementation:

callback_next_step(Args) when Args#args.moddata == undefined ->
  % TODO
  {continue, Args#args.maxpkt, "TODO", true};
callback_next_step(Args) when Args#args.packetrcv < 1 ->
  {result, {{error,up}, timeout}};
callback_next_step(Args) ->
  % TODO parse
  {result, {ok, result}, ok}.

Different elements from the args record can be used within a fingerprinting module:

  • Args#args.moddata is the user data. It is especially used to detect the first call as it will be set to undefined (see the first function above).
  • Args#args.packetrcv is a counter that is set before each callback to the number of packets received.
  • is the target.
  • Args#args.datarcv is the payload received from the remote host.
  • Args#args.tgtarg is the target specific argument (see usage).
  • Args#args.ipaddr will contain the IP address of the target (is equal to in case of IP and equal to the looked up IP in case of a domain).

See the args record for more info on the available fields.

Certificate check and SNI

For modules of type ssl, the following additional options are available:

  • {sslcheck, true}: check the certificate validity.
  • {sslcheck, full}: the above plus the domain check.
  • {sslcheck, false}: disable ssl checking.
  • {sslcheck, retry}: starts with {sslcheck,full} and retry with {sslcheck,false} in case of error.
  • {sni, disable}: disable SNI.
  • {sni, enable}: enable SNI.
  • {sni, retry}: starts with {sni,enable} and retry with {sni,disable} in case of error.

These can be provided through the get_default_args function in the fsmopts fields, for example:

-define(SSLOPTS, [{sslcheck,false}, {sni,retry}]).
get_default_args() ->
  #args{module=?MODULE, type=?TYPE, port=?PORT,
    timeout=?TIMEOUT, maxpkt=?MAXPKT, fsmopts=?SSLOPTS}.

Overwrite socket arguments

It might be useful sometimes to be able to overwrite the socket argument used by scannerl to communicate with remote hosts. This can be done using the -K switch from the command line. -K expects a comma separated list of element in one of the below format

  • key:value
  • key

The provided arguments will complete (or replace if it exists) the arguments provided to the socket.

This is especially useful for the ssl fsm, to have a different behavior with sslcheck or sni.

Let for example take an SSL related module that have the following option: -define(SSLOPTS, [{sslcheck,false}])... You might want however to activate sslcheck and make sure the SNI extensions is provided.

You would thus call scannerl with -K sslcheck:full,sni:enable.

Here are the lists of options:


See the existing modules under

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.