Lua bindings to an opaque Yara wrapper
This library provides an opaque wrapper and Lua FFI bindings to the Yara malware scanning library. Yara's C API provides an event-based model to examine the result of scanning files or memory buffers against a set of compiled rules, using a callback to examine the result of each rule's execution. This push- style design is detrimentally slow in Lua FFI environments, and is explicitly warned against (see http://luajit.org/ext_ffi_semantics.html). For this reason, a simple wrapper that does not rely in a Lua-land callback is provided; this can be loaded via FFI and integrated in Lua FFI/LuaJIT environments.
A Makefile is provided to build the C wrapper:
~/lua-ffi-yara$ make
The build produces a single shared object, libyawrap.so
, that can be loaded
dynamically into an OpenResty environment.
The Yara library must be built and installed on the target system. Compile Yara
from source using the configure flag --with-pic
. The static archive
libyara.a
must be available as part of the source.
Integration into OpenResty environments is straightforward through the included
lib/yara.lua
library. Two functions are exported to inspect either a file path
(useful for buffered request or response bodies), or strings (converted to
memory buffers by the library).
init_by_lua_block {
local yara = require "yara"
yara.load("/path/to/libyawrap.so") -- this is built in the "src" dir
}
access_by_lua_block {
local yara = require "yara"
local messages = {} -- table to hold matched rule data
local rulepath = "/path/to/compiled/yara.rules" -- compiled yara rules
ngx.req.read_body()
local body = ngx.req.get_body_file()
local matched = yara.inspect_file(body, rulepath, messages)
if matched then
for i, rule_name in ipairs(matches) do
ngx.say(rule_name)
end
end
}
For performance reasons, Yara rules should be precompiled and saved on-disk to
pass into the wrapper. Rules can be precompiled with the yarac
utility.
syntax: yara.load(path)
Load the yawrap.so
library. This must be called before accessing any wrapper
functions.
syntax: matched = yara.inspect_file(path, ruleset, matches?)
Scan the file located at path
using the precompiled Yara ruleset found at
the path ruleset
. Returns true if any matches are found, or false otherwise.
Additionally, an optional table matches
can be provided to hold names of each
rule that matched the target path.
syntax: matched = yara.inspect_string(str, ruleset, matches?)
Similar to inspect_file
, but accepts a Lua string to examine as a memory
buffer instead of a file path.
This program is free software: you can redistribute it and/or modify it under the terms of the MIT License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details.
You should have received a copy of the MIT License along with this program. See COPYING.
Please report bugs by creating a ticket with the GitHub issue tracker.