ec_filter.c (ettercap-0.8.3) | : | ec_filter.c (ettercap-0.8.3.1) | ||
---|---|---|---|---|
skipping to change at line 61 | skipping to change at line 61 | |||
static int execute_assign(struct filter_op *fop, struct packet_object *po); | static int execute_assign(struct filter_op *fop, struct packet_object *po); | |||
static int execute_incdec(struct filter_op *fop, struct packet_object *po); | static int execute_incdec(struct filter_op *fop, struct packet_object *po); | |||
static int execute_func(struct filter_op *fop, struct packet_object *po); | static int execute_func(struct filter_op *fop, struct packet_object *po); | |||
static int func_search(struct filter_op *fop, struct packet_object *po); | static int func_search(struct filter_op *fop, struct packet_object *po); | |||
static int func_regex(struct filter_op *fop, struct packet_object *po); | static int func_regex(struct filter_op *fop, struct packet_object *po); | |||
static int func_pcre(struct filter_op *fop, struct packet_object *po); | static int func_pcre(struct filter_op *fop, struct packet_object *po); | |||
static int func_replace(struct filter_op *fop, struct packet_object *po); | static int func_replace(struct filter_op *fop, struct packet_object *po); | |||
static int func_inject(struct filter_op *fop, struct packet_object *po); | static int func_inject(struct filter_op *fop, struct packet_object *po); | |||
static int func_execinject(struct filter_op *fop, struct packet_object *po); | static int func_execinject(struct filter_op *fop, struct packet_object *po); | |||
static int func_execreplace(struct filter_op *fop, struct packet_object *po); | ||||
static int func_log(struct filter_op *fop, struct packet_object *po); | static int func_log(struct filter_op *fop, struct packet_object *po); | |||
static int func_drop(struct packet_object *po); | static int func_drop(struct packet_object *po); | |||
static int func_kill(struct packet_object *po); | static int func_kill(struct packet_object *po); | |||
static int func_exec(struct filter_op *fop); | static int func_exec(struct filter_op *fop); | |||
static int cmp_eq(u_int32 a, u_int32 b); | static int cmp_eq(u_int32 a, u_int32 b); | |||
static int cmp_neq(u_int32 a, u_int32 b); | static int cmp_neq(u_int32 a, u_int32 b); | |||
static int cmp_lt(u_int32 a, u_int32 b); | static int cmp_lt(u_int32 a, u_int32 b); | |||
static int cmp_gt(u_int32 a, u_int32 b); | static int cmp_gt(u_int32 a, u_int32 b); | |||
static int cmp_leq(u_int32 a, u_int32 b); | static int cmp_leq(u_int32 a, u_int32 b); | |||
static int cmp_geq(u_int32 a, u_int32 b); | static int cmp_geq(u_int32 a, u_int32 b); | |||
/*******************************************/ | /*******************************************/ | |||
/* initialize the filter mutex */ | /* initialize the filter mutex */ | |||
void filter_init_mutex(void) { | void filter_init_mutex(void) { | |||
pthread_mutexattr_t at; | pthread_mutexattr_t at; | |||
pthread_mutexattr_init(&at); | pthread_mutexattr_init(&at); | |||
/* we want an recursive mutex, so we can re-aquire it in the same thread */ | /* we want an recursive mutex, so we can re-acquire it in the same thread */ | |||
pthread_mutexattr_settype(&at, PTHREAD_MUTEX_RECURSIVE_NP); | pthread_mutexattr_settype(&at, PTHREAD_MUTEX_RECURSIVE_NP); | |||
pthread_mutex_init(&filters_mutex, &at); | pthread_mutex_init(&filters_mutex, &at); | |||
} | } | |||
/* | /* | |||
* JIT interpreter for binary filters. | * JIT interpreter for binary filters. | |||
* it process the filter_ops and apply the instructions | * it process the filter_ops and apply the instructions | |||
* on the given packet object | * on the given packet object | |||
*/ | */ | |||
static int filter_engine(struct filter_op *fop, struct packet_object *po) | static int filter_engine(struct filter_op *fop, struct packet_object *po) | |||
skipping to change at line 231 | skipping to change at line 232 | |||
if (func_inject(fop, po) == E_SUCCESS) | if (func_inject(fop, po) == E_SUCCESS) | |||
return FLAG_TRUE; | return FLAG_TRUE; | |||
break; | break; | |||
case FFUNC_EXECINJECT: | case FFUNC_EXECINJECT: | |||
/* replace the string through output of a executable */ | /* replace the string through output of a executable */ | |||
if (func_execinject(fop, po) == E_SUCCESS) | if (func_execinject(fop, po) == E_SUCCESS) | |||
return FLAG_TRUE; | return FLAG_TRUE; | |||
break; | break; | |||
case FFUNC_EXECREPLACE: | ||||
/* replace the string through output of a executable */ | ||||
if (func_execreplace(fop, po) == E_SUCCESS) | ||||
return FLAG_TRUE; | ||||
break; | ||||
case FFUNC_LOG: | case FFUNC_LOG: | |||
/* log the packet */ | /* log the packet */ | |||
if (func_log(fop, po) == E_SUCCESS) | if (func_log(fop, po) == E_SUCCESS) | |||
return FLAG_TRUE; | return FLAG_TRUE; | |||
break; | break; | |||
case FFUNC_DROP: | case FFUNC_DROP: | |||
/* drop the packet */ | /* drop the packet */ | |||
func_drop(po); | func_drop(po); | |||
return FLAG_TRUE; | return FLAG_TRUE; | |||
skipping to change at line 883 | skipping to change at line 890 | |||
if (po->flags & PO_DROPPED) | if (po->flags & PO_DROPPED) | |||
po->flags ^= PO_DROPPED; | po->flags ^= PO_DROPPED; | |||
/* free memory */ | /* free memory */ | |||
SAFE_FREE(output); | SAFE_FREE(output); | |||
return E_SUCCESS; | return E_SUCCESS; | |||
} | } | |||
/* | /* | |||
* replace output of a executable into the communication | ||||
* executable takes communication before any change in input | ||||
*/ | ||||
static int func_execreplace(struct filter_op *fop, struct packet_object *po) | ||||
{ | ||||
int child_stdout[2], child_stdin[2]; | ||||
pid_t child_pid; | ||||
unsigned char *output = NULL; | ||||
size_t n = 0, offset = 0, size = 128; | ||||
unsigned char buf[size]; | ||||
/* check the offensiveness */ | ||||
if (EC_GBL_OPTIONS->unoffensive) | ||||
JIT_FAULT("Cannot replace packets in unoffensive mode"); | ||||
DEBUG_MSG("filter engine: func_execreplace %s", fop->op.func.string); | ||||
/* open the pipe */ | ||||
if (pipe(child_stdin) != 0 || pipe(child_stdout) != 0) { | ||||
USER_MSG("filter engine: execreplace(): failed to create pipes\n"); | ||||
return -E_FATAL; | ||||
} | ||||
if ((child_pid = fork()) < 0) { | ||||
USER_MSG("filter engine: execreplace(): failed to fork\n"); | ||||
return -E_FATAL; | ||||
} | ||||
if (child_pid == 0) { | ||||
char *const argv[] = { "/bin/sh", "-c", fop->op.func.string, NULL }; | ||||
if (dup2(child_stdin[0], STDIN_FILENO) == -1 || dup2(child_stdout[1], STD | ||||
OUT_FILENO) == -1) { | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
close(child_stdin[1]); | ||||
close(child_stdout[0]); | ||||
execv(argv[0], argv); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
close(child_stdin[0]); | ||||
close(child_stdout[1]); | ||||
/* fill child STDIN with DATA */ | ||||
while (offset < po->DATA.len) { | ||||
n = write(child_stdin[1], po->DATA.data + offset, po->DATA.len - offset); | ||||
if (n == (size_t)-1) { | ||||
break; | ||||
} | ||||
offset += n; | ||||
} | ||||
close(child_stdin[1]); | ||||
/* Fill child STDIN with DATA */ | ||||
offset = 0; | ||||
while ((n = read(child_stdout[0], buf, size)) != 0) { | ||||
if (output == NULL) { | ||||
SAFE_CALLOC(output, offset+n, sizeof(unsigned char)); | ||||
} | ||||
else { | ||||
SAFE_REALLOC(output, sizeof(unsigned char)*(offset+n)); | ||||
} | ||||
memcpy(output+offset, buf, n); | ||||
offset += n; | ||||
} | ||||
/* close pipe stream */ | ||||
close(child_stdout[0]); | ||||
/* check if we are overflowing pcap buffer */ | ||||
if(EC_GBL_PCAP->snaplen - (po->L4.header - (po->packet + po->L2.len) + po->L4 | ||||
.len) <= po->DATA.len + (unsigned)offset) | ||||
JIT_FAULT("replaced output too long"); | ||||
/* copy the output into the buffer */ | ||||
memcpy(po->DATA.data, output, offset); | ||||
/* Adjust packet len and delta */ | ||||
if ((u_int)offset > po->DATA.len) { | ||||
po->DATA.delta += (int)((u_int)offset - po->DATA.len); | ||||
} else { | ||||
po->DATA.delta -= (int)(po->DATA.len - (u_int)offset); | ||||
} | ||||
po->DATA.len = offset; | ||||
/* mark the packet as modified */ | ||||
po->flags |= PO_MODIFIED; | ||||
/* unset the flag to be dropped */ | ||||
if (po->flags & PO_DROPPED) | ||||
po->flags ^= PO_DROPPED; | ||||
/* free memory */ | ||||
SAFE_FREE(output); | ||||
return E_SUCCESS; | ||||
} | ||||
/* | ||||
* log the packet to a file | * log the packet to a file | |||
*/ | */ | |||
static int func_log(struct filter_op *fop, struct packet_object *po) | static int func_log(struct filter_op *fop, struct packet_object *po) | |||
{ | { | |||
int fd; | int fd; | |||
DEBUG_MSG("filter engine: func_log"); | DEBUG_MSG("filter engine: func_log"); | |||
/* open the file */ | /* open the file */ | |||
fd = open((const char*)fop->op.func.string, O_CREAT | O_APPEND | O_RDWR | O_B INARY, 0600); | fd = open((const char*)fop->op.func.string, O_CREAT | O_APPEND | O_RDWR | O_B INARY, 0600); | |||
skipping to change at line 976 | skipping to change at line 1078 | |||
DEBUG_MSG("filter engine: func_exec: %s", fop->op.func.string); | DEBUG_MSG("filter engine: func_exec: %s", fop->op.func.string); | |||
/* | /* | |||
* the command must be executed by a child. | * the command must be executed by a child. | |||
* we are forwding packets, and we cannot wait | * we are forwding packets, and we cannot wait | |||
* for the execution of the command | * for the execution of the command | |||
*/ | */ | |||
pid = fork(); | pid = fork(); | |||
/* check if the fork was successfull */ | /* check if the fork was successful */ | |||
if (pid == -1) | if (pid == -1) | |||
SEMIFATAL_ERROR("filter engine: fork() failed, cannot execute %s", fop->op .func.string); | SEMIFATAL_ERROR("filter engine: fork() failed, cannot execute %s", fop->op .func.string); | |||
/* differentiate between the parent and the child */ | /* differentiate between the parent and the child */ | |||
if (!pid) { | if (!pid) { | |||
int k, param_length; | int k, param_length; | |||
char **param = NULL; | char **param = NULL; | |||
char *q = (char*)fop->op.func.string; | char *q = (char*)fop->op.func.string; | |||
char *p; | char *p; | |||
int i = 0; | int i = 0; | |||
End of changes. 5 change blocks. | ||||
2 lines changed or deleted | 106 lines changed or added |