[Oisf-devel] RFC: lua scripting flowvar access

Chris Wakelin c.d.wakelin at reading.ac.uk
Thu Apr 18 18:02:08 UTC 2013


Sounds very useful!

My first thoughts are

1) We can return specific messages for particular hits in a suspicious
.jar, (possibly costing some performance to have rules to check the
flowvar and display the appropriate messages)

2) Blackhole/Cool/SofosFO encrypt their payloads with a base integer
that is specified in the URI. We could set a flowvar using pcre on the
URI, then check whether it decodes the payload in Lua (though actually,
the ET Luajit XOR script deduces the base from the first two bytes being
"MZ" in an executable).

I'm sure we'll come up with other uses :)

Best Wishes,
Chris

On 18/04/13 17:01, 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.
> 


-- 
--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-
Christopher Wakelin,                           c.d.wakelin at reading.ac.uk
IT Services Centre, The University of Reading,  Tel: +44 (0)118 378 2908
Whiteknights, Reading, RG6 6AF, UK              Fax: +44 (0)118 975 3094



More information about the Oisf-devel mailing list