New API: internal_yara_scan

The internal_yara_scan runs the Yara engine with the previously loaded
rules against the given file.

For each rule matching against the scanned file, a struct containing
the file name and the rule identifier is returned.

The gathered list of yara_detection structs is serialised into XDR format
and written to a file.

Signed-off-by: Matteo Cafasso <noxdafox@gmail.com>
This commit is contained in:
Matteo Cafasso
2017-04-25 23:03:03 +03:00
committed by Richard W.M. Jones
parent 09bab5d38c
commit d00dc913aa
9 changed files with 110 additions and 1 deletions

View File

@@ -58,6 +58,8 @@ static bool initialized = false;
static int compile_rules_file (const char *);
static void compile_error_callback (int, const char *, int, const char *, void *);
static void cleanup_destroy_yara_compiler (void *ptr);
static int yara_rules_callback (int , void *, void *);
static int send_detection_info (const char *, YR_RULE *);
/* Has one FileIn parameter.
* Takes optional arguments, consult optargs_bitmask.
@@ -125,6 +127,38 @@ do_yara_destroy (void)
return 0;
}
/* Has one FileOut parameter. */
int
do_internal_yara_scan (const char *path)
{
int r;
CLEANUP_CLOSE int fd = -1;
if (rules == NULL) {
reply_with_error ("no yara rules loaded");
return -1;
}
CHROOT_IN;
fd = open (path, O_RDONLY|O_CLOEXEC);
CHROOT_OUT;
if (fd == -1) {
reply_with_perror ("%s", path);
return -1;
}
reply (NULL, NULL); /* Reply message. */
r = yr_rules_scan_fd (rules, fd, 0, yara_rules_callback, (void *) path, 0);
if (r == ERROR_SUCCESS)
r = send_file_end (0); /* File transfer end. */
else
send_file_end (1); /* Cancel file transfer. */
return 0;
}
/* Compile source code rules and load them.
* Return ERROR_SUCCESS on success, Yara error code type on error.
*/
@@ -184,6 +218,58 @@ compile_error_callback (int level, const char *name, int line,
fprintf (stderr, "Yara warning (line %d): %s\n", line, message);
}
/* Yara scan callback, called by yr_rules_scan_file.
* Return 0 on success, -1 on error.
*/
static int
yara_rules_callback (int code, void *message, void *data)
{
int ret = 0;
if (code == CALLBACK_MSG_RULE_MATCHING)
ret = send_detection_info ((const char *)data, (YR_RULE *) message);
return (ret == 0) ? CALLBACK_CONTINUE : CALLBACK_ERROR;
}
/* Serialize file path and rule name and send it out.
* Return 0 on success, -1 on error.
*/
static int
send_detection_info (const char *name, YR_RULE *rule)
{
XDR xdr;
int r;
size_t len;
CLEANUP_FREE char *buf = NULL;
struct guestfs_int_yara_detection detection;
detection.yara_name = (char *) name;
detection.yara_rule = (char *) rule->identifier;
/* Serialize detection struct. */
buf = malloc (GUESTFS_MAX_CHUNK_SIZE);
if (buf == NULL) {
perror ("malloc");
return -1;
}
xdrmem_create (&xdr, buf, GUESTFS_MAX_CHUNK_SIZE, XDR_ENCODE);
r = xdr_guestfs_int_yara_detection (&xdr, &detection);
if (r == 0) {
perror ("xdr_guestfs_int_yara_detection");
return -1;
}
len = xdr_getpos (&xdr);
xdr_destroy (&xdr);
/* Send serialised yara_detection out. */
return send_file_write (buf, len);
}
/* Clean up yara handle on daemon exit. */
void yara_finalize (void) __attribute__((destructor));

View File

@@ -53,4 +53,12 @@ Previously loaded rules will be destroyed." };
longdesc = "\
Destroy previously loaded Yara rules in order to free libguestfs resources." };
{ defaults with
name = "internal_yara_scan"; added = (1, 37, 13);
style = RErr, [Pathname "path"; FileOut "filename"], [];
visibility = VInternal;
optional = Some "libyara";
shortdesc = "scan a file with the loaded yara rules";
longdesc = "Internal function for yara_scan." };
]

View File

@@ -481,6 +481,7 @@ let proc_nr = [
471, "mksquashfs";
472, "yara_load";
473, "yara_destroy";
474, "internal_yara_scan";
]
(* End of list. If adding a new entry, add it at the end of the list

View File

@@ -469,6 +469,15 @@ let structs = [
];
s_camel_name = "TSKDirent" };
(* Yara detection information. *)
{ defaults with
s_name = "yara_detection";
s_cols = [
"yara_name", FString;
"yara_rule", FString;
];
s_camel_name = "YaraDetection" };
] (* end of structs *)
let lookup_struct name =

View File

@@ -49,6 +49,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/struct-version.h \
include/guestfs-gobject/struct-xattr.h \
include/guestfs-gobject/struct-xfsinfo.h \
include/guestfs-gobject/struct-yara_detection.h \
include/guestfs-gobject/optargs-add_domain.h \
include/guestfs-gobject/optargs-add_drive.h \
include/guestfs-gobject/optargs-add_drive_scratch.h \
@@ -141,6 +142,7 @@ guestfs_gobject_sources= \
src/struct-version.c \
src/struct-xattr.c \
src/struct-xfsinfo.c \
src/struct-yara_detection.c \
src/optargs-add_domain.c \
src/optargs-add_drive.c \
src/optargs-add_drive_scratch.c \

View File

@@ -46,4 +46,5 @@ java_built_sources = \
com/redhat/et/libguestfs/Version.java \
com/redhat/et/libguestfs/XAttr.java \
com/redhat/et/libguestfs/XFSInfo.java \
com/redhat/et/libguestfs/YaraDetection.java \
com/redhat/et/libguestfs/GuestFS.java

View File

@@ -23,3 +23,4 @@ VG.java
Version.java
XAttr.java
XFSInfo.java
YaraDetection.java

View File

@@ -1 +1 @@
473
474

View File

@@ -313,6 +313,7 @@ gobject/src/struct-utsname.c
gobject/src/struct-version.c
gobject/src/struct-xattr.c
gobject/src/struct-xfsinfo.c
gobject/src/struct-yara_detection.c
gobject/src/tristate.c
inspector/inspector.c
java/actions-0.c