-
Notifications
You must be signed in to change notification settings - Fork 43
Fingerprinting module
Content:
- Implement a fingerprinting module
- callback_next_step
- Certificate check and SNI
- Overwrite socket arguments
- Examples
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,udporssl) -
port: the port (can be overwritten with the-pswitch) -
timeout: the timeout in milli-seconds (can be overwritten with the-tswitch) -
maxpkt: max number of packets to handle (can be overwritten with the-jswitch) -
fsmoptsfor an ssl module: provides the option to the socket, especially related to sslcheck and sni
-
-
get_description/0: is called when the-lswitch is provided to show a short description of the modules. -
get_arguments/0: is called when the-lswitch 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}.-
Nbpacketdefines the maximum number of packet to receive before calling the callback again -
Payloaddefines the payload to send to the remote host -
ModDatais the data that will be provided back tocallback_next_stepthroughArgs#args.moddatanext 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 -
ModDatais user data as forcontinue
-
-
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.moddatais the user data. It is especially used to detect the first call as it will be set toundefined(see the first function above). -
Args#args.packetrcvis a counter that is set before each callback to the number of packets received. -
Args#args.targetis the target. -
Args#args.datarcvis the payload received from the remote host. -
Args#args.tgtargis the target specific argument (see usage). -
Args#args.ipaddrwill contain the IP address of the target (is equal toArgs#args.targetin 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.
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}.
...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:valuekey
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:
- TCP see sockopt: http://erlang.org/doc/man/gen_tcp.html#type-option_name
- UDP see sockopt: http://erlang.org/doc/man/gen_udp.html#type-option_name
- SSL see ssl_option: http://erlang.org/doc/man/ssl.html
- for SSL these additional options are available, see above Certificate check and SNI
See the existing modules under https://github.com/kudelskisecurity/scannerl/tree/master/src/fpmodules