[Oisf-devel] RFC: lua scripting flowvar access

Vincent Fang vincent.y.fang at gmail.com
Sat May 18 15:49:46 UTC 2013


So in the init function I have this one key line for the flow var:

needs["flowvar"] = {"var"}

and in the match function, the lines related to the flowvar are:

local var = ScFlowvarGet(0)
if(var == nil) then

         io.write("\n var was nil \n")
         var = "mew"

end
ScFlowvarSet(0, var, #var)

and the result I get is that message var was nil everytime as if the
ScFlowvarSet doesn't do anything for a string.


Vince


On Fri, May 17, 2013 at 2:37 PM, Victor Julien <victor at inliniac.net> wrote:

> 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
> ---------------------------------------------
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openinfosecfoundation.org/pipermail/oisf-devel/attachments/20130518/e032413b/attachment-0002.html>


More information about the Oisf-devel mailing list