Exemplo n.º 1
0
Arquivo: yara.c Projeto: Amelos/moloch
void moloch_yara_exit()
{
    if (yRules)
        yr_rules_destroy(yRules);
    if (yEmailRules)
        yr_rules_destroy(yEmailRules);

    if (yCompiler)
        yr_compiler_destroy(yCompiler);
    if (yEmailCompiler)
        yr_compiler_destroy(yEmailCompiler);
    yr_finalize();
}
Exemplo n.º 2
0
  Row scanFile(const std::string& ruleContent) {
    YR_RULES* rules = nullptr;
    int result = yr_initialize();
    EXPECT_TRUE(result == ERROR_SUCCESS);

    writeTextFile(ruleFile, ruleContent);

    Status status = compileSingleFile(ruleFile, &rules);
    EXPECT_TRUE(status.ok());

    Row r;
    r["count"] = "0";
    r["matches"] = "";

    result = yr_rules_scan_file(rules,
                                ls.c_str(),
                                SCAN_FLAGS_FAST_MODE,
                                YARACallback,
                                (void*)&r,
                                0);
    EXPECT_TRUE(result == ERROR_SUCCESS);

    yr_rules_destroy(rules);

    return r;
  }
Exemplo n.º 3
0
Arquivo: util.c Projeto: nsxz/yara
int matches_blob(
    char* rule,
    uint8_t* blob,
    size_t len)
{
  if (blob == NULL)
  {
    blob = (uint8_t*) "dummy";
    len = 5;
  }

  YR_RULES* rules = compile_rule(rule);

  if (rules == NULL)
  {
    fprintf(stderr, "failed to compile rule << %s >>: %s\n", rule, compile_error);
    exit(EXIT_FAILURE);
  }

  int matches = 0;
  int scan_result = yr_rules_scan_mem(
      rules, blob, len, 0, count_matches, &matches, 0);

  if (scan_result != ERROR_SUCCESS)
  {
    fprintf(stderr, "yr_rules_scan_mem: error\n");
    exit(EXIT_FAILURE);
  }

  yr_rules_destroy(rules);

  return matches;
}
Exemplo n.º 4
0
void Yara::_clean_compiler_and_rules() const
{
	if (_compiler != nullptr) {
		yr_compiler_destroy(_compiler);
	}
	if (_rules != nullptr) {
		yr_rules_destroy(_rules);
	}
}
Exemplo n.º 5
0
static void Rules_dealloc(PyObject *self)
{
  Rules *object = (Rules *) self;

  Py_XDECREF(object->externals);
  yr_rules_destroy(object->rules);

  PyObject_Del(self);
}
Exemplo n.º 6
0
RBOOL
    collector_16_cleanup
    (
        HbsState* hbsState,
        rSequence config
    )
{
    RBOOL isSuccess = FALSE;

    UNREFERENCED_PARAMETER( config );

    if( NULL != hbsState )
    {
        notifications_unsubscribe( RP_TAGS_NOTIFICATION_YARA_RULES_UPDATE, NULL, updateSignatures );
        notifications_unsubscribe( RP_TAGS_NOTIFICATION_YARA_SCAN, NULL, doScan );
        notifications_unsubscribe( RP_TAGS_NOTIFICATION_MODULE_LOAD, g_async_files_to_scan, NULL );

        if( rMutex_lock( g_global_rules_mutex ) )
        {
            if( NULL != g_global_rules )
            {
                yr_rules_destroy( g_global_rules );
                g_global_rules = NULL;
            }

            rMutex_unlock( g_global_rules_mutex );
        }

        rQueue_free( g_async_files_to_scan );
        g_async_files_to_scan = NULL;

        rMutex_free( g_global_rules_mutex );
        g_global_rules_mutex = NULL;

        yr_finalize();

        isSuccess = TRUE;
    }

    return isSuccess;
}
Exemplo n.º 7
0
static
RVOID
    updateSignatures
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RPU8 buffer = NULL;
    RU32 bufferSize = 0;
    YR_RULES* rules = NULL;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        if( rSequence_getBUFFER( event, RP_TAGS_RULES, &buffer, &bufferSize ) )
        {
            if( NULL != ( rules = loadYaraRules( buffer, bufferSize ) ) )
            {
                if( rMutex_lock( g_global_rules_mutex ) )
                {
                    g_global_rules = rules;

                    rMutex_unlock( g_global_rules_mutex );
                }
                else
                {
                    yr_rules_destroy( rules );
                }
            }
        }
    }

    yr_finalize_thread();
}
Exemplo n.º 8
0
static void Rules_dealloc(PyObject *self)
{
  yr_rules_destroy(((Rules*) self)->rules);
  PyObject_Del(self);
}
Exemplo n.º 9
0
static
RVOID
    doScan
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    RPWCHAR fileW = NULL;
    RPCHAR fileA = NULL;
    RPWCHAR procW = NULL;
    RPCHAR procA = NULL;
    RPU8 rulesBuffer = NULL;
    RU32 rulesBufferSize = 0;
    YR_RULES* rules = NULL;
    YaraMatchContext matchContext = { 0 };
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    RU32 scanError = 0;
    rSequence processInfo = NULL;
    RPWCHAR tmpW = NULL;
    RPCHAR tmpA = NULL;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid );
        rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &fileW );
        rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &fileA );
        rSequence_getSTRINGW( event, RP_TAGS_PROCESS, &procW );
        rSequence_getSTRINGA( event, RP_TAGS_PROCESS, &procA );

        if( rSequence_getBUFFER( event, RP_TAGS_RULES, &rulesBuffer, &rulesBufferSize ) )
        {
            rules = loadYaraRules( rulesBuffer, rulesBufferSize );
        }

        if( NULL != rules )
        {
            if( NULL != fileW )
            {
                fileA = rpal_string_wtoa( fileW );
            }

            if( NULL != procW )
            {
                procA = rpal_string_wtoa( procW );
            }

            if( NULL != fileA )
            {
                rpal_debug_info( "scanning file with yara" );
                matchContext.fileInfo = event;

                // Scan this file
                if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( rules,
                                                                       fileA,
                                                                       SCAN_FLAGS_FAST_MODE,
                                                                       _yaraFileMatchCallback,
                                                                       &matchContext,
                                                                       60 ) ) )
                {
                    rpal_debug_warning( "Yara file scan error: %d", scanError );
                }
            }
            else if( NULL != procA )
            {
                // Scan processes matching
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        if( NULL != ( processInfo = processLib_getProcessInfo( curProc->pid, NULL ) ) )
                        {
                            if( rSequence_getSTRINGW( processInfo, RP_TAGS_FILE_PATH, &tmpW ) ||
                                rSequence_getSTRINGA( processInfo, RP_TAGS_FILE_PATH, &tmpA ) )
                            {
                                if( NULL != tmpW )
                                {
                                    tmpA = rpal_string_wtoa( tmpW );
                                }

                                if( NULL != tmpA )
                                {
                                    if( rpal_string_match( procA, tmpA, RPAL_PLATFORM_FS_CASE_SENSITIVITY ) )
                                    {
                                        matchContext.pid = curProc->pid;
                                        matchContext.processInfo = processInfo;

                                        scanError = _scanProcessWith( curProc->pid,
                                                                      &matchContext,
                                                                      rules,
                                                                      NULL );
                                    }
                                }

                                if( NULL != tmpW && NULL != tmpA )
                                {
                                    // If both are allocated it means we got a strW and converted to A
                                    // so we must free the strA version.
                                    rpal_memory_free( tmpA );
                                }
                            }

                            rSequence_free( processInfo );
                        }

                        curProc++;
                    }

                    rpal_memory_free( processes );
                }
            }
            else if( 0 != pid )
            {
                // Scan this process
                matchContext.pid = pid;
                scanError = _scanProcessWith( pid, &matchContext, rules, NULL );
                rSequence_free( matchContext.processInfo );
            }
            else
            {
                // Scan all processes
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        matchContext.pid = curProc->pid;

                        scanError = _scanProcessWith( curProc->pid, &matchContext, rules, NULL );
                        rSequence_free( matchContext.processInfo );

                        curProc++;
                    }
                        
                    rpal_memory_free( processes );
                }
            }


            if( NULL != fileW && NULL != fileA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( fileA );
            }

            if( NULL != procW && NULL != procA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( procA );
            }

            yr_rules_destroy( rules );
        }
        else
        {
            rpal_debug_warning( "no rules in yara scan request" );
            reportError( event, RPAL_ERROR_NOT_SUPPORTED, "yara rules do not parse" );
        }
    }

    rpal_debug_info( "finished on demand yara scan" );
    reportError( event, scanError, "done" );

    yr_finalize_thread();
}
Exemplo n.º 10
0
/**
 * Given a vector of strings, attempt to compile them and store the result
 * in the map under the given category.
 */
Status handleRuleFiles(const std::string& category,
                       const pt::ptree& rule_files,
                       std::map<std::string, YR_RULES*>* rules) {
  YR_COMPILER *compiler = nullptr;
  int result = yr_compiler_create(&compiler);
  if (result != ERROR_SUCCESS) {
    VLOG(1) << "Could not create compiler: " + std::to_string(result);
    return Status(1, "Could not create compiler: " + std::to_string(result));
  }

  yr_compiler_set_callback(compiler, YARACompilerCallback, nullptr);

  bool compiled = false;
  for (const auto& item : rule_files) {
    YR_RULES *tmp_rules;
    const auto rule = item.second.get("", "");
    VLOG(1) << "Loading " << rule;

    std::string full_path;
    if (rule[0] != '/') {
      full_path = std::string("/etc/osquery/yara/") + rule;
    } else {
      full_path = rule;
    }

    // First attempt to load the file, in case it is saved (pre-compiled)
    // rules. Sadly there is no way to load multiple compiled rules in
    // succession. This means that:
    //
    // saved1, saved2
    // results in saved2 being the only file used.
    //
    // Also, mixing source and saved rules results in the saved rules being
    // overridden by the combination of the source rules once compiled, e.g.:
    //
    // file1, saved1
    // result in file1 being the only file used.
    //
    // If you want to use saved rule files you must have them all in a single
    // file. This is easy to accomplish with yarac(1).
    result = yr_rules_load(full_path.c_str(), &tmp_rules);
    if (result != ERROR_SUCCESS && result != ERROR_INVALID_FILE) {
      yr_compiler_destroy(compiler);
      return Status(1, "Error loading YARA rules: " + std::to_string(result));
    } else if (result == ERROR_SUCCESS) {
      // If there are already rules there, destroy them and put new ones in.
      if (rules->count(category) > 0) {
        yr_rules_destroy((*rules)[category]);
      }
      (*rules)[category] = tmp_rules;
    } else {
      compiled = true;
      // Try to compile the rules.
      FILE *rule_file = fopen(full_path.c_str(), "r");

      if (rule_file == nullptr) {
        yr_compiler_destroy(compiler);
        return Status(1, "Could not open file: " + full_path);
      }

      int errors =
          yr_compiler_add_file(compiler, rule_file, nullptr, full_path.c_str());

      fclose(rule_file);
      rule_file = nullptr;

      if (errors > 0) {
        yr_compiler_destroy(compiler);
        // Errors printed via callback.
        return Status(1, "Compilation errors");
      }
    }
  }

  if (compiled) {
    // All the rules for this category have been compiled, save them in the map.
    result = yr_compiler_get_rules(compiler, &((*rules)[category]));

    if (result != ERROR_SUCCESS) {
      yr_compiler_destroy(compiler);
      return Status(1, "Insufficient memory to get YARA rules");
    }
  }

  if (compiler != nullptr) {
    yr_compiler_destroy(compiler);
    compiler = nullptr;
  }

  return Status(0, "OK");
}
Exemplo n.º 11
0
Arquivo: yarac.c Projeto: elmelik/yara
int main(
    int argc,
    const char** argv)
{
  COMPILER_RESULTS cr;

  YR_COMPILER* compiler = NULL;
  YR_RULES* rules = NULL;

  int result;

  argc = args_parse(options, argc, argv);

  if (show_version)
  {
    printf("%s\n", YR_VERSION);
    return EXIT_SUCCESS;
  }

  if (show_help)
  {
    printf("%s\n\n", USAGE_STRING);

    args_print_usage(options, 35);
    printf("\nSend bug reports and suggestions to: [email protected]\n");

    return EXIT_SUCCESS;
  }

  if (argc < 2)
  {
    fprintf(stderr, "yarac: wrong number of arguments\n");
    fprintf(stderr, "%s\n\n", USAGE_STRING);
    fprintf(stderr, "Try `--help` for more options\n");

    exit_with_code(EXIT_FAILURE);
  }

  result = yr_initialize();

  if (result != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (!define_external_variables(compiler))
    exit_with_code(EXIT_FAILURE);

  cr.errors = 0;
  cr.warnings = 0;

  yr_set_configuration(YR_CONFIG_MAX_STRINGS_PER_RULE, &max_strings_per_rule);
  yr_compiler_set_callback(compiler, report_error, &cr);

  if (!compile_files(compiler, argc, argv))
    exit_with_code(EXIT_FAILURE);

  if (cr.errors > 0)
    exit_with_code(EXIT_FAILURE);

  if (fail_on_warnings && cr.warnings > 0)
    exit_with_code(EXIT_FAILURE);

  result = yr_compiler_get_rules(compiler, &rules);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = yr_rules_save(rules, argv[argc - 1]);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = EXIT_SUCCESS;

_exit:

  if (compiler != NULL)
    yr_compiler_destroy(compiler);

  if (rules != NULL)
    yr_rules_destroy(rules);

  yr_finalize();

  return result;
}
Exemplo n.º 12
0
int main(
    int argc,
    char const* argv[])
{
  YR_COMPILER* compiler;
  YR_RULES* rules;
  FILE* rule_file;
  EXTERNAL* external;

  int pid;
  int i;
  int errors;
  int result;

  THREAD thread[MAX_THREADS];

  if (!process_cmd_line(argc, argv))
    return 0;

  if (argc == 1 || optind == argc)
  {
    show_help();
    return 0;
  }

  yr_initialize();

  result = yr_rules_load(argv[optind], &rules);

  if (result == ERROR_UNSUPPORTED_FILE_VERSION ||
      result == ERROR_CORRUPT_FILE)
  {
    print_scanning_error(result);
    return;
  }

  if (result == ERROR_SUCCESS)
  {
    external = externals_list;

    while (external != NULL)
    {
      switch (external->type)
      {
        case EXTERNAL_TYPE_INTEGER:
          yr_rules_define_integer_variable(
              rules,
              external->name,
              external->integer);
          break;

        case EXTERNAL_TYPE_BOOLEAN:
          yr_rules_define_boolean_variable(
              rules,
              external->name,
              external->boolean);
          break;

        case EXTERNAL_TYPE_STRING:
          yr_rules_define_string_variable(
              rules,
              external->name,
              external->string);
          break;
      }
      external = external->next;
    }
  }
  else
  {
    if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
      return 0;

    external = externals_list;

    while (external != NULL)
    {
      switch (external->type)
      {
        case EXTERNAL_TYPE_INTEGER:
          yr_compiler_define_integer_variable(
              compiler,
              external->name,
              external->integer);
          break;

        case EXTERNAL_TYPE_BOOLEAN:
          yr_compiler_define_boolean_variable(
              compiler,
              external->name,
              external->boolean);
          break;

        case EXTERNAL_TYPE_STRING:
          yr_compiler_define_string_variable(
              compiler,
              external->name,
              external->string);
          break;
      }
      external = external->next;
    }

    compiler->error_report_function = print_compiler_error;
    rule_file = fopen(argv[optind], "r");

    if (rule_file != NULL)
    {
      yr_compiler_push_file_name(compiler, argv[optind]);

      errors = yr_compiler_add_file(compiler, rule_file, NULL);

      fclose(rule_file);

      if (errors == 0)
        yr_compiler_get_rules(compiler, &rules);

      yr_compiler_destroy(compiler);

      if (errors > 0)
      {
        yr_finalize();
        return 0;
      }
    }
    else
    {
      fprintf(stderr, "could not open file: %s\n", argv[optind]);
      return 0;
    }
  }

  mutex_init(&output_mutex);

  if (is_numeric(argv[argc - 1]))
  {
    pid = atoi(argv[argc - 1]);
    result = yr_rules_scan_proc(
        rules,
        pid,
        callback,
        (void*) argv[argc - 1],
        fast_scan,
        timeout);

    if (result != ERROR_SUCCESS)
      print_scanning_error(result);
  }
  else if (is_directory(argv[argc - 1]))
  {
    file_queue_init();

    for (i = 0; i < threads; i++)
    {
      if (create_thread(&thread[i], scanning_thread, (void*) rules) != 0)
        return ERROR_COULD_NOT_CREATE_THREAD;
    }

    scan_dir(
        argv[argc - 1],
        recursive_search,
        rules,
        callback);

    file_queue_finish();

    // Wait for scan threads to finish
    for (i = 0; i < threads; i++)
      thread_join(&thread[i]);

    file_queue_destroy();
  }
  else
  {
    result = yr_rules_scan_file(
        rules,
        argv[argc - 1],
        callback,
        (void*) argv[argc - 1],
        fast_scan,
        timeout);
 
    if (result != ERROR_SUCCESS)
    {
      fprintf(stderr, "Error scanning %s: ", argv[argc - 1]);
      print_scanning_error(result);
    }
  }

  yr_rules_destroy(rules);
  yr_finalize();

  mutex_destroy(&output_mutex);
  cleanup();

  return 1;
}
Exemplo n.º 13
0
int main(
    int argc,
    const char** argv)
{
  YR_COMPILER* compiler = NULL;
  YR_RULES* rules = NULL;

  int result;

  argc = args_parse(options, argc, argv);

  if (show_version)
  {
    printf("%s\n", PACKAGE_STRING);
    printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);

    return EXIT_FAILURE;
  }

  if (show_help)
  {
    printf("%s\n\n", USAGE_STRING);

    args_print_usage(options, 25);
    printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);

    return EXIT_FAILURE;
  }

  if (argc < 2)
  {
    fprintf(stderr, "yarac: wrong number of arguments\n");
    fprintf(stderr, "%s\n\n", USAGE_STRING);
    fprintf(stderr, "Try `--help` for more options\n");

    exit_with_code(EXIT_FAILURE);
  }

  result = yr_initialize();

  if (result != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (!define_external_variables(compiler))
    exit_with_code(EXIT_FAILURE);

  yr_compiler_set_callback(compiler, report_error, NULL);

  for (int i = 0; i < argc - 1; i++)
  {
    const char* ns;
    const char* file_name;
    char* colon = (char*) strchr(argv[i], ':');

    if (colon)
    {
      file_name = colon + 1;
      *colon = '\0';
      ns = argv[i];
    }
    else
    {
      file_name = argv[i];
      ns = NULL;
    }

    FILE* rule_file = fopen(file_name, "r");

    if (rule_file != NULL)
    {
      int errors = yr_compiler_add_file(
          compiler, rule_file, ns, file_name);

      fclose(rule_file);

      if (errors) // errors during compilation
        exit_with_code(EXIT_FAILURE);
    }
    else
    {
      fprintf(stderr, "error: could not open file: %s\n", file_name);
    }
  }

  result = yr_compiler_get_rules(compiler, &rules);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = yr_rules_save(rules, argv[argc - 1]);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = EXIT_SUCCESS;

_exit:

  if (compiler != NULL)
    yr_compiler_destroy(compiler);

  if (rules != NULL)
    yr_rules_destroy(rules);

  yr_finalize();

  return result;
}
Exemplo n.º 14
0
int main(
    int argc,
    char const* argv[])
{
  int i, result, errors;

  YR_COMPILER* compiler;
  YR_RULES* rules;
  FILE* rule_file;

  yr_initialize();

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
  {
    yr_finalize();
    return EXIT_FAILURE;
  }

  if (!process_cmd_line(compiler, argc, argv))
  {
    yr_compiler_destroy(compiler);
    yr_finalize();
    return EXIT_FAILURE;
  }

  if (argc == 1 || optind == argc)
  {
    show_help();
    yr_compiler_destroy(compiler);
    yr_finalize();
    return EXIT_FAILURE;
  }

  compiler->error_report_function = report_error;

  for (i = optind; i < argc - 1; i++)
  {
    rule_file = fopen(argv[i], "r");

    if (rule_file != NULL)
    {
      yr_compiler_push_file_name(compiler, argv[i]);

      errors = yr_compiler_add_file(compiler, rule_file, NULL);

      fclose(rule_file);

      if (errors) // errors during compilation
      {
        yr_compiler_destroy(compiler);
        yr_finalize();
        return EXIT_FAILURE;
      }
    }
    else
    {
      fprintf(stderr, "could not open file: %s\n", argv[i]);
    }
  }

  result = yr_compiler_get_rules(compiler, &rules);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    return EXIT_FAILURE;
  }

  result = yr_rules_save(rules, argv[argc - 1]);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    return EXIT_FAILURE;
  }

  yr_rules_destroy(rules);
  yr_compiler_destroy(compiler);

  yr_finalize();

  return EXIT_SUCCESS;
}
Exemplo n.º 15
0
QueryData genYara(QueryContext& context) {
  QueryData results;
  Status status;

  auto paths = context.constraints["path"].getAll(EQUALS);
  auto patterns = context.constraints["pattern"].getAll(EQUALS);
  auto groups = context.constraints["sig_group"].getAll(EQUALS);
  auto sigfiles = context.constraints["sigfile"].getAll(EQUALS);

  // Must specify a path constraint and at least one of sig_group or sigfile.
  if (groups.size() == 0 && sigfiles.size() == 0) {
    return results;
  }

  // XXX: Abstract this into a common "get rules for group" function.
  ConfigDataInstance config;
  const auto& parser = config.getParser("yara");
  if (parser == nullptr) {
    return results;
  }
  const auto& yaraParser = std::static_pointer_cast<YARAConfigParserPlugin>(parser);
  if (yaraParser == nullptr) {
    return results;
  }
  auto rules = yaraParser->rules();

  // Store resolved paths in a vector of pairs.
  // Each pair has the first element as the path to scan and the second
  // element as the pattern which generated it.
  std::vector<std::pair<std::string, std::string> > path_pairs;

  // Expand patterns and push onto path_pairs.
  for (const auto& pattern : patterns) {
    std::vector<std::string> expanded_patterns;
    auto status = resolveFilePattern(pattern, expanded_patterns);
    if (!status.ok()) {
      VLOG(1) << "Could not expand pattern properly: " << status.toString();
      return results;
    }

    for (const auto& resolved : expanded_patterns) {
      if (!isReadable(resolved)) {
        continue;
      }
      path_pairs.push_back(make_pair(resolved, pattern));
    }
  }

  // Collect all paths specified too.
  for (const auto& path_string : paths) {
    if (!isReadable(path_string)) {
      continue;
    }
    path_pairs.push_back(make_pair(path_string, ""));
  }

  // Compile all sigfiles into a map.
  std::map<std::string, YR_RULES*> compiled_rules;
  for (const auto& file : sigfiles) {
    YR_RULES *rules = nullptr;

    std::string full_path;
    if (file[0] != '/') {
      full_path = std::string("/etc/osquery/yara/") + file;
    } else {
      full_path = file;
    }

    status = compileSingleFile(full_path, &rules);
    if (!status.ok()) {
      VLOG(1) << "YARA error: " << status.toString();
    } else {
      compiled_rules[file] = rules;
    }
  }

  // Scan every path pair.
  for (const auto& path_pair : path_pairs) {
    // Scan using siggroups.
    for (const auto& group : groups) {
      if (rules.count(group) == 0) {
        continue;
      }

      VLOG(1) << "Scanning with group: " << group;
      status = doYARAScan(rules[group],
                          path_pair.first.c_str(),
                          path_pair.second,
                          results,
                          group,
                          "");
      if (!status.ok()) {
        VLOG(1) << "YARA error: " << status.toString();
      }
    }

    // Scan using files.
    for (const auto& element : compiled_rules) {
      VLOG(1) << "Scanning with file: " << element.first;
      status = doYARAScan(element.second,
                          path_pair.first.c_str(),
                          path_pair.second,
                          results,
                          "",
                          element.first);
      if (!status.ok()) {
        VLOG(1) << "YARA error: " << status.toString();
      }
    }
  }

  // Cleanup compiled rules
  for (const auto& element : compiled_rules) {
    yr_rules_destroy(element.second);
  }

  return results;
}
Exemplo n.º 16
0
int main(int argc, char* argv[])
{

	if (argc != 3) {
		std::cout << std::endl << "usage: ./yextend RULES_FILE [FILE|DIR]" << std::endl << std::endl;
		exit(0);
	}
	
	// get yara runtime version
	double yara_version = get_yara_version();
	// version checks
	if (YEXTEND_VERSION >= 1.2 && yara_version < 3.4) {
		std::cout << std::endl << "Version issue: yextend version " << YEXTEND_VERSION << "+ will not run with yara versions below 3.4" << std::endl << std::endl;
		std::cout << "Your env has yextend version ";
		printf("%.1f\n", YEXTEND_VERSION);
		std::cout << "Your env has yara version ";
		printf("%.1f", yara_version);
		std::cout << std::endl << std::endl;
		exit(0);
	}
	const char *yara_ruleset_file_name = argv[1];
	const char *target_resource = argv[2];
	char fs[300];
	
	/*
	 * pre-process yara rules and then we can use the
	 * pointer to "rules" as an optimized entity.
	 * this is a requirement so that performance
	 * is optimal
	 */
	YR_RULES* rules = NULL;
	rules = bayshore_yara_preprocess_rules(yara_ruleset_file_name);
	if (!rules) {
		if (!does_this_file_exist(yara_ruleset_file_name)) {
			std::cout << std::endl << "Yara Ruleset file: \"" << yara_ruleset_file_name << "\" does not exist, exiting ..." << std::endl << std::endl;
			exit(0);
		}
		std::cout << std::endl << "Problem compiling Yara Ruleset file: \"" << yara_ruleset_file_name << "\", continuing with regular ruleset file ..." << std::endl << std::endl;
	}

	if (is_directory(target_resource)) {

		DIR *dpdf;
		struct dirent *epdf;

		dpdf = opendir(target_resource);
		if (dpdf != NULL) {
			while (epdf = readdir(dpdf)){

				uint8_t *c;
				FILE *file = NULL;

				strncpy (fs, target_resource, strlen(target_resource));
				fs[strlen(target_resource)] = '\0';

				if (epdf->d_name[0] != '.') {

					strncat (fs, epdf->d_name, strlen(epdf->d_name));
					fs[strlen(fs)] = '\0';

					if ((file = fopen(fs, "rb")) != NULL) {
						// Get the size of the file in bytes
						long fileSize = get_file_size(file);

						// Allocate space in the buffer for the whole file
						c = new uint8_t[fileSize];
						// Read the file in to the buffer
						fread(c, fileSize, 1, file);

						std::cout << std::endl << alpha << std::endl;
						std::cout << output_labels[0] << fs << std::endl;
						std::cout << output_labels[1] << fileSize << std::endl;

						char *output = str_to_md5((const char *)c, fileSize);
						if (output) {
							std::cout << output_labels[4] << output << std::endl;
							free(output);
						}

						std::list<security_scan_results_t> ssr_list;

						if (rules) {
							
							scan_content (
									c,
									fileSize,
									rules,
									&ssr_list,
									fs,
									yara_cb,
									1);
							
						} else {
							scan_content (
									c,
									fileSize,
									yara_ruleset_file_name,
									&ssr_list,
									fs,
									yara_cb,
									1);
						}

						if (!ssr_list.empty()) {

							std::cout << std::endl << midline << std::endl;
							for (std::list<security_scan_results_t>::const_iterator v = ssr_list.begin();
									v != ssr_list.end();
									v++)
							{
								std::cout << std::endl;
								std::cout << output_labels[2] << v->file_scan_result << std::endl;
								std::cout << output_labels[3] << v->file_scan_type << std::endl;
								if (v->parent_file_name.size()) {
									if (v->child_file_name.size())
										std::cout << output_labels[6] << v->parent_file_name << std::endl << output_labels[7] << v->child_file_name << std::endl;
									else
										std::cout << output_labels[5] << v->parent_file_name << std::endl;
								}
								std::cout << output_labels[4] << v->file_signature_md5 << std::endl;
								std::cout << std::endl;
							}
							std::cout << std::endl << omega << std::endl;
						} else {
							std::cout << std::endl << omega << std::endl;
						}


						delete[] c;
						fclose(file);
					}
				}
			}
			closedir(dpdf);
		}
	} else if(does_this_file_exist(target_resource)) {

		uint8_t *c;
		FILE *file = NULL;
		strncpy (fs, target_resource, strlen(target_resource));
		fs[strlen(target_resource)] = '\0';

		if (fs[0] != '.') {

			if ((file = fopen(fs, "rb")) != NULL) {
				// Get the size of the file in bytes
				long fileSize = get_file_size(file);

				// Allocate space in the buffer for the whole file
				c = new uint8_t[fileSize];

				// Read the file in to the buffer
				fread(c, fileSize, 1, file);

				std::cout << std::endl << alpha << std::endl;
				std::cout << output_labels[0] << fs << std::endl;
				std::cout << output_labels[1] << fileSize << std::endl;
				
				char *output = str_to_md5((const char *)c, fileSize);
				if (output) {
					// XXX fixme
					std::cout << output_labels[4] << output << std::endl;
					free(output);
				}
				
				std::list<security_scan_results_t> ssr_list;

				if (rules) {
					
					scan_content (
							c,
							fileSize,
							rules,
							&ssr_list,
							fs,
							yara_cb,
							1);
				} else {
					scan_content (
							c,
							fileSize,
							yara_ruleset_file_name,
							&ssr_list,
							fs,
							yara_cb,
							1);
				}

				if (!ssr_list.empty()) {
					std::cout << std::endl << midline << std::endl;
					for (std::list<security_scan_results_t>::const_iterator v = ssr_list.begin();
							v != ssr_list.end();
							v++)
					{
						std::cout << std::endl;
						std::cout << output_labels[2] << v->file_scan_result << std::endl;
						std::cout << output_labels[3] << v->file_scan_type << std::endl;
						if (v->parent_file_name.size()) {
							if (v->child_file_name.size())
								std::cout << output_labels[6] << v->parent_file_name << std::endl << output_labels[7] << v->child_file_name << std::endl;
							else
								std::cout << output_labels[5] << v->parent_file_name << std::endl;
						}
						std::cout << output_labels[4] << v->file_signature_md5 << std::endl;
						std::cout << std::endl;
					}
					std::cout << std::endl << omega << std::endl;
				} else {
					std::cout << std::endl << omega << std::endl;
				}

				delete[] c;
				fclose(file);
			}
		}

	} else {
		std::cout << std::endl << "Could not read resource: \"" << target_resource << "\", exiting ..." << std::endl << std::endl;
	}
	
	if (rules != NULL)
		yr_rules_destroy(rules);
	return 0;
}