Skip to content

Instantly share code, notes, and snippets.

@reyjrar
Last active December 17, 2015 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reyjrar/5663893 to your computer and use it in GitHub Desktop.
Save reyjrar/5663893 to your computer and use it in GitHub Desktop.
commit 47f1803471ec4c8f9c69c42680019bc002ef304b
Author: Brad Lhotsky <brad.lhotsky@booking.com>
Date: Tue May 28 17:59:21 2013 +0200
Active response was not passing the filename in file events, ie,
syscheck. The Eventinfo struct only included file data for builds with
Prelude integration. This prevented the AR from handing filename off
anyways.
* Eventinfo now contains file data always
* Added *expect* option for 'filename'
* Added FILENAME to ar.h
* Filename validation is tricky, so shell escape instead
* Added os_shell_escape() to string_op.h, allocates memory for an
escaped string and passes the pointer back to caller. Caller must
cleanup that memory.
* Call os_shell_escape() before passing to execd.
* Added string_test.c to test the os_shell_escape() function.
diff --git a/src/analysisd/alerts/exec.c b/src/analysisd/alerts/exec.c
index 073ac58..906f68c 100755
--- a/src/analysisd/alerts/exec.c
+++ b/src/analysisd/alerts/exec.c
@@ -33,7 +33,7 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
char exec_msg[OS_SIZE_1024 +1];
char *ip;
char *user;
-
+ char *filename;
/* Cleaning the IP */
if(lf->srcip && (ar->ar_cmd->expect & SRCIP))
@@ -89,6 +89,16 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
user = "-";
}
+ /* Get the filename */
+ if(lf->filename && (ar->ar_cmd->expect & FILENAME))
+ {
+ filename = os_shell_escape(lf->filename);
+ }
+ else
+ {
+ filename = "-";
+ }
+
/* active response on the server.
* The response must be here if the ar->location is set to AS
@@ -102,14 +112,15 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
return;
snprintf(exec_msg, OS_SIZE_1024,
- "%s %s %s %d.%ld %d %s",
+ "%s %s %s %d.%ld %d %s %s",
ar->name,
user,
ip,
lf->time,
__crt_ftell,
lf->generated_rule->sigid,
- lf->location);
+ lf->location,
+ filename);
if(OS_SendUnix(*execq, exec_msg, 0) < 0)
{
@@ -126,7 +137,7 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
if missing then it must of been generated by the local analysisd so prepend a false id tag */
if(lf->location[0] == '(') {
snprintf(exec_msg, OS_SIZE_1024,
- "%s %c%c%c %s %s %s %s %d.%ld %d",
+ "%s %c%c%c %s %s %s %s %d.%ld %d %s",
lf->location,
(ar->location & ALL_AGENTS)?ALL_AGENTS_C:NONE_C,
(ar->location & REMOTE_AGENT)?REMOTE_AGENT_C:NONE_C,
@@ -137,10 +148,11 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
ip,
lf->time,
__crt_ftell,
- lf->generated_rule->sigid);
+ lf->generated_rule->sigid,
+ filename);
} else {
snprintf(exec_msg, OS_SIZE_1024,
- "(local_source) %s %c%c%c %s %s %s %s %d.%ld %d",
+ "(local_source) %s %c%c%c %s %s %s %s %d.%ld %d %s",
lf->location,
(ar->location & ALL_AGENTS)?ALL_AGENTS_C:NONE_C,
(ar->location & REMOTE_AGENT)?REMOTE_AGENT_C:NONE_C,
@@ -151,7 +163,8 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
ip,
lf->time,
__crt_ftell,
- lf->generated_rule->sigid);
+ lf->generated_rule->sigid,
+ filename);
}
if((rc = OS_SendUnix(*arq, exec_msg, 0)) < 0)
@@ -168,6 +181,10 @@ void OS_Exec(int *execq, int *arq, Eventinfo *lf, active_response *ar)
}
}
+ // Clean up Memory
+ if ( filename != NULL )
+ free(filename);
+
return;
}
diff --git a/src/analysisd/analysisd.c b/src/analysisd/analysisd.c
index 59a37b7..82939c7 100755
--- a/src/analysisd/analysisd.c
+++ b/src/analysisd/analysisd.c
@@ -1087,6 +1087,13 @@ void OS_ReadMSG_analysisd(int m_queue)
do_ar = 0;
}
}
+ if((*rule_ar)->ar_cmd->expect & FILENAME)
+ {
+ if(!lf->filename)
+ {
+ do_ar = 0;
+ }
+ }
if(do_ar)
{
diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c
index 8618813..26350f3 100755
--- a/src/analysisd/decoders/syscheck.c
+++ b/src/analysisd/decoders/syscheck.c
@@ -532,10 +532,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
"Size changed from '%s' to '%s'\n",
oldsize, newsize);
- #ifdef PRELUDE
os_strdup(oldsize, lf->size_before);
os_strdup(newsize, lf->size_after);
- #endif
}
/* Permission message */
@@ -588,10 +586,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
(newperm & S_ISVTX)? 't' :
(newperm & S_IXOTH)? 'x' : '-');
- #ifdef PRELUDE
lf->perm_before = oldperm;
lf->perm_after = newperm;
- #endif
}
/* Ownership message */
@@ -606,10 +602,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
olduid, newuid);
- #ifdef PRELUDE
os_strdup(olduid, lf->owner_before);
os_strdup(newuid, lf->owner_after);
- #endif
}
/* group ownership message */
@@ -622,10 +616,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
snprintf(sdb.gowner, OS_FLSIZE,"Group ownership was '%s', "
"now it is '%s'\n",
oldgid, newgid);
- #ifdef PRELUDE
os_strdup(oldgid, lf->gowner_before);
os_strdup(newgid, lf->gowner_after);
- #endif
}
/* md5 message */
@@ -638,10 +630,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
snprintf(sdb.md5, OS_FLSIZE, "Old md5sum was: '%s'\n"
"New md5sum is : '%s'\n",
oldmd5, newmd5);
- #ifdef PRELUDE
os_strdup(oldmd5, lf->md5_before);
os_strdup(newmd5, lf->md5_after);
- #endif
}
/* sha1 */
@@ -654,14 +644,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
snprintf(sdb.sha1, OS_FLSIZE, "Old sha1sum was: '%s'\n"
"New sha1sum is : '%s'\n",
oldsha1, newsha1);
- #ifdef PRELUDE
os_strdup(oldsha1, lf->sha1_before);
os_strdup(newsha1, lf->sha1_after);
- #endif
}
- #ifdef PRELUDE
os_strdup(f_name, lf->filename);
- #endif
/* Provide information about the file */
diff --git a/src/analysisd/eventinfo.c b/src/analysisd/eventinfo.c
index b35fd40..55a347c 100755
--- a/src/analysisd/eventinfo.c
+++ b/src/analysisd/eventinfo.c
@@ -520,7 +520,6 @@ void Zero_Eventinfo(Eventinfo *lf)
lf->sid_node_to_delete = NULL;
lf->decoder_info = NULL_Decoder;
- #ifdef PRELUDE
lf->filename = NULL;
lf->perm_before = 0;
lf->perm_after = 0;
@@ -534,7 +533,6 @@ void Zero_Eventinfo(Eventinfo *lf)
lf->owner_after = NULL;
lf->gowner_before = NULL;
lf->gowner_after = NULL;
- #endif
return;
}
@@ -583,7 +581,6 @@ void Free_Eventinfo(Eventinfo *lf)
if(lf->systemname)
free(lf->systemname);
- #ifdef PRELUDE
if(lf->filename)
free(lf->filename);
if (lf->md5_before)
@@ -606,7 +603,6 @@ void Free_Eventinfo(Eventinfo *lf)
free(lf->gowner_before);
if (lf->gowner_after)
free(lf->gowner_after);
- #endif
/* Freeing node to delete */
if(lf->sid_node_to_delete)
@@ -633,6 +629,6 @@ void Free_Eventinfo(Eventinfo *lf)
lf = NULL;
return;
-}
+}
/* EOF */
diff --git a/src/analysisd/eventinfo.h b/src/analysisd/eventinfo.h
index fb5b4b6..ae9ab9a 100755
--- a/src/analysisd/eventinfo.h
+++ b/src/analysisd/eventinfo.h
@@ -71,8 +71,7 @@ typedef struct _Eventinfo
char hour[10];
char mon[4];
- /* SYSCHECK Results variables -- only used by prelude for now */
- #ifdef PRELUDE
+ /* SYSCHECK Results variables */
char *filename;
int perm_before;
int perm_after;
@@ -86,7 +85,6 @@ typedef struct _Eventinfo
char *owner_after;
char *gowner_before;
char *gowner_after;
- #endif
}Eventinfo;
diff --git a/src/config/active-response.c b/src/config/active-response.c
index ee4937d..4fd0da9 100755
--- a/src/config/active-response.c
+++ b/src/config/active-response.c
@@ -437,6 +437,8 @@ int ReadActiveCommands(XML_NODE node, void *d1, void *d2)
tmp_command->expect |= USERNAME;
if(OS_Regex("srcip", tmp_str))
tmp_command->expect |= SRCIP;
+ if(OS_Regex("filename", tmp_str))
+ tmp_command->expect |= FILENAME;
}
free(tmp_str);
diff --git a/src/headers/ar.h b/src/headers/ar.h
index 699c114..3824fdf 100755
--- a/src/headers/ar.h
+++ b/src/headers/ar.h
@@ -39,6 +39,7 @@
/* Expected values */
+#define FILENAME 0000010
#define SRCIP 0000004
#define DSTIP 0000002
#define USERNAME 0000001
diff --git a/src/headers/string_op.h b/src/headers/string_op.h
index 2df963e..b56f49a 100755
--- a/src/headers/string_op.h
+++ b/src/headers/string_op.h
@@ -29,6 +29,9 @@ int os_substr(char *dest, const char *src, int position, int length);
/* Remove a character from a string */
char *os_strip_char(char *source, char remove);
+/* Escape a list of characters with a backslash */
+char *os_shell_escape(const char *src);
+
#endif
/* EOF */
diff --git a/src/shared/string_op.c b/src/shared/string_op.c
index f458793..b90819e 100755
--- a/src/shared/string_op.c
+++ b/src/shared/string_op.c
@@ -87,5 +87,45 @@ int os_substr(char *dest, const char *src, int position, int length) {
return 0;
}
+/* Escape a set of characters */
+char *os_shell_escape(const char *src) {
+ // Maximum Length of the String is 2xthe current length
+ char shell_escapes[] = { '\\', '"', '\'', ' ', '\t', ';', '`', '>', '<', '|', '#',
+ '*', '[', ']', '{', '}', '&', '$', '!', ':', '(', ')' };
+
+ char *escaped_string;
+ int length = 0;
+ int i = 0;
+
+ if (src == NULL)
+ return NULL;
+
+ // Determine how long the string will be
+ char *iterator = src;
+ for (; *iterator; iterator++) {
+ if( strchr(shell_escapes, *iterator) ) {
+ length++;
+ }
+ length++;
+ }
+ // Allocate the memory
+ if( (escaped_string = calloc(1, length + 1 )) == NULL ) {
+ // Return NULL
+ return NULL;
+ }
+
+ // Escape the escapable characters
+ iterator=src;
+ for( i=0; *iterator; iterator++ ) {
+ if ( strchr(shell_escapes, *iterator) ) {
+ escaped_string[i] = '\\';
+ i++;
+ }
+ escaped_string[i] = *iterator;
+ i++;
+ }
+ // Return Success
+ return escaped_string;
+}
/* EOF */
diff --git a/src/shared/tests/Makefile b/src/shared/tests/Makefile
index ed01595..6374609 100755
--- a/src/shared/tests/Makefile
+++ b/src/shared/tests/Makefile
@@ -1,10 +1,11 @@
# Makefile for misc tests
maketest:
+ $(CC) -g -o string_test string_test.c ../string_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall
$(CC) -g -o prime_test prime_test.c ../math_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall
$(CC) -g -o hash_test hash_test.c ../hash_op.c ../math_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall
$(CC) -g -o merge_test merge_test.c ../file_op.c ../debug_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall
$(CC) -DARGV0=\"ip_test\" -g -o ip_test ip_test.c ../validate_op.c ../debug_op.c ../regex_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall
clean:
- -rm regex regex_str *.core
+ -rm string_test prime_test hash_test merge_test ip_test *.core
diff --git a/src/shared/tests/string_test.c b/src/shared/tests/string_test.c
new file mode 100755
index 0000000..aadd3e4
--- /dev/null
+++ b/src/shared/tests/string_test.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <string.h>
+#include "string_op.h"
+
+
+int main(int argc, char **argv)
+{
+ int i = 0;
+ char *tmp;
+ char buf[] = "/var/www/html/Testing This Interface$%^&*().txt";
+ tmp = os_shell_escape(buf);
+ char clean[] = "/var/www/html/index.html";
+
+ printf("Sent: '%s'\n", buf);
+ printf("Fixed: '%s'\n", tmp);
+ free(tmp);
+
+ tmp = os_shell_escape(clean);
+ printf("Sent: '%s'\n", clean);
+ printf("Fixed: '%s'\n", tmp);
+
+
+ return(0);
+}
+
+
+/* EOF */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment