[Oisf-devel] RFC: lua scripting flowvar access

Victor Julien victor at inliniac.net
Fri May 17 18:37:47 UTC 2013


On 05/17/2013 07:53 PM, Vincent Fang wrote:
> Tested out this feature and was wondering if it's possible for it to
> store a string into the flowvar? I attempted to test that out and kept
> getting nil values from the ScFlowvarGet. The main goal is to find out
> and keep track not only what portion of the flow the lua script is
> examining but which flow it is for the administrator to see with that
> unique string var.

That should be possible, ya. Can you share (part of) your script?

Cheers,
Victor

> On Tue, Apr 23, 2013 at 6:07 AM, Victor Julien <victor at inliniac.net
> <mailto:victor at inliniac.net>> wrote:
> 
>     On 04/22/2013 06:05 PM, Victor Julien wrote:
>     > On 04/18/2013 06:01 PM, Victor Julien wrote:
>     >> Funded by Emerging Threats, I've been working on giving the lua
>     scripts
>     >> access to flowvars.
>     >>
>     >> Currently only "flowvars" are done, "flowints" will be next. Please
>     >> review the code at:
>     >> https://github.com/inliniac/suricata/tree/dev-lua-flowvar
>     >>
>     >> Pcre based flowvar capturing is done in a post-match fashion. If the
>     >> rule containing the "capture" matches, the var is stored in the flow.
>     >>
>     >> For lua scripting, this wasn't what the rule writers wanted. In this
>     >> case, the flowvars are stored in the flow regardless of a rule match.
>     >>
>     >> The way a script can start using flowvars is by first registering
>     which
>     >> one it needs access to:
>     >>
>     >> function init (args)
>     >>     local needs = {}
>     >>     needs["http.request_headers.raw"] = tostring(true)
>     >>     needs["flowvar"] = {"cnt"}
>     >>     return needs
>     >> end
>     >>
>     >> More than one can be registered, e.g.:
>     >>
>     >>     needs["flowvar"] = {"cnt", "somevar", "anothervar" }
>     >>
>     >> The maximum is 15 per script. The order of the vars matters. As
>     Suricata
>     >> uses id's internally, to use the vars you have to use id's as
>     well. The
>     >> first registered var has id 0, 2nd 1 and so on:
>     >>
>     >> function match(args)
>     >>     a = ScFlowvarGet(0);
>     >>     if a then
>     >>         print ("We have an A: " .. (a))
>     >>         a = tostring(tonumber(a)+1)
>     >>         print ("A incremented to: " .. (a))
>     >>         ScFlowvarSet(0, a, #a)
>     >>     else
>     >>         print "Init A to 1"
>     >>         a = tostring(1)
>     >>         ScFlowvarSet(0, a, #a)
>     >>     end
>     >>
>     >>     print ("A is " .. (a))
>     >>     if tonumber(a) == 23 then
>     >>         print "Match!"
>     >>         return 1
>     >>     end
>     >>
>     >>     return 0
>     >> end
>     >>
>     >> You can also use a var:
>     >>
>     >> function init (args)
>     >>     local needs = {}
>     >>     needs["http.request_headers.raw"] = tostring(true)
>     >>     needs["flowvar"] = {"blah", "cnt"}
>     >>     return needs
>     >> end
>     >>
>     >> local var_cnt = 1
>     >>
>     >> function match(args)
>     >>     a = ScFlowvarGet(var_cnt);
>     >>     if a then
>     >>         print ("We have an A: " .. (a))
>     >>         a = tostring(tonumber(a)+1)
>     >>         print ("A incremented to: " .. (a))
>     >>         ScFlowvarSet(var_cnt, a, #a)
>     >>     else
>     >>         print "Init A to 1"
>     >>         a = tostring(1)
>     >>         ScFlowvarSet(var_cnt, a, #a)
>     >>     end
>     >>
>     >>     print ("A is " .. (a))
>     >>     if tonumber(a) == 23 then
>     >>         print "Match!"
>     >>         return 1
>     >>     end
>     >>
>     >>     return 0
>     >> end
>     >>
>     >> Flowvars are set at the end of the rule's inspection, so after the
>     >> script has run.
>     >>
>     >> When multiple stores are done from the script and/or pcre, the last
>     >> match will win. So if order matters, rule priority can be used to
>     >> control inspection order.
>     >>
>     >> Thoughts, comments, and code review highly welcomed.
>     >>
>     >
>     > Updated branch:
>     > https://github.com/inliniac/suricata/tree/dev-lua-flowvar-v1.1
>     >
>     > - Adds flowint support:
>     >
>     > function init (args)
>     >     local needs = {}
>     >     needs["http.request_headers"] = tostring(true)
>     >     needs["flowint"] = {"cnt"}
>     >     return needs
>     > end
>     >
>     > function match(args)
>     >     a = ScFlowintGet(0);
>     >     if a then
>     >         ScFlowintSet(0, a + 1)
>     >     else
>     >         ScFlowintSet(0, 1)
>     >     end
>     >
>     >     a = ScFlowintGet(0);
>     >     if a == 23 then
>     >         return 1
>     >     end
>     >
>     >     return 0
>     > end
>     >
>     > return 0
>     >
>     > Sets are real time, so are done regardless of script match or rule
>     match.
>     >
>     > - Converts flowvar sets to real time, to fix some var overwrite issues
>     > in HTTP header inspection.
>     >
> 
>     https://github.com/inliniac/suricata/tree/dev-lua-flowvar-v1.2
> 
>     Adds in ScFlowintIncr & ScFlowintDecr. From the commit:
> 
>     "Add flowint lua functions for incrementing and decrementing flowints.
> 
>     First use creates the var and inits to 0. So a call:
> 
>         a = ScFlowintIncr(0)
> 
>     Results in a == 1.
> 
>     If the var reached UINT_MAX (2^32), it's not further incremented. If the
>     var reaches 0 it's not decremented further.
> 
>     Calling ScFlowintDecr on a uninitialized var will init it to 0.
> 
>     Example script:
> 
>         function init (args)
>             local needs = {}
>             needs["http.request_headers"] = tostring(true)
>             needs["flowint"] = {"cnt_incr"}
>             return needs
>         end
> 
>         function match(args)
>             a = ScFlowintIncr(0);
>             if a == 23 then
>                 return 1
>             end
> 
>             return 0
>         end
>         return 0
> 
>     This script matches the 23rd time it's invoked on a flow."
> 
>     --
>     ---------------------------------------------
>     Victor Julien
>     http://www.inliniac.net/
>     PGP: http://www.inliniac.net/victorjulien.asc
>     ---------------------------------------------
> 
>     _______________________________________________
>     Suricata IDS Devel mailing list:
>     oisf-devel at openinfosecfoundation.org
>     <mailto:oisf-devel at openinfosecfoundation.org>
>     Site: http://suricata-ids.org | Participate:
>     http://suricata-ids.org/participate/
>     List:
>     https://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel
>     Redmine: https://redmine.openinfosecfoundation.org/
> 
> 


-- 
---------------------------------------------
Victor Julien
http://www.inliniac.net/
PGP: http://www.inliniac.net/victorjulien.asc
---------------------------------------------




More information about the Oisf-devel mailing list