YaraStream

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2023 License: MIT Imports: 8 Imported by: 0

README

Yara scanner for Golang

Yara scanner library compatible with io.Reader for streaming

Features

  • Read multiple rules for multiple directories
  • Scan inside archives with maximum depth

Requirements

All requirements from github.com/hillu/go-yara apply

Example

package main

import (
	"crypto/sha1"
	"crypto/sha256"
	"flag"
	"github.com/LeakIX/YaraStream"
	"io"
	"io/fs"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"sync"
)

var yaraScanner *YaraStream.YaraScanner
var fileChan = make(chan string)
var wg sync.WaitGroup

func main() {
	var err error
	flag.Parse()
	if len(flag.Args()) != 1 {
		log.Fatal("You must provide a file to scan")
	}
	yaraScanner, err = YaraStream.NewYaraScanner(
		YaraStream.RuleDirectory{Namespace: "AbuseCH", Path: "./rules/abusech"},
		YaraStream.RuleDirectory{Namespace: "ReversingLabs", Path: "./rules/reversinglabs"},
		YaraStream.RuleDirectory{Namespace: "ESET", Path: "./rules/eset"},
		YaraStream.RuleDirectory{Namespace: "AlienVault", Path: "./rules/otx"},
	)
	if err != nil {
		panic(err)
	}

	for w := 1; w <= runtime.NumCPU(); w++ {
		go worker()
	}
	err = filepath.Walk(flag.Arg(0), func(path string, info fs.FileInfo, err error) error {
		if err != nil {
			return nil
		}
		if info.IsDir() || !info.Mode().IsRegular() {
			return nil
		}
		wg.Add(1)
		fileChan <- path
		return nil
	})

	if err != nil {
		panic(err)
	}
	wg.Wait()
}

func worker() {
	for filePath := range fileChan {
		scanFile(filePath)
		wg.Done()
	}
}

func scanFile(path string) error {
	log.Printf("Scanning %s", path)
	file, err := os.Open(path)
	if err != nil {
		log.Println(err)
		return nil
	}
	sha256Hasher := sha256.New()
	sha1Hasher := sha1.New()
	sha256Tee := io.TeeReader(file, sha256Hasher)
	sha1Tee := io.TeeReader(sha256Tee, sha1Hasher)
	matches, err := yaraScanner.ScanReader(sha1Tee, YaraStream.WithFilenameTip(path), YaraStream.WithMaxLevel(3))
	for _, scanResult := range matches {
		log.Printf("[YARA] Infection found: %s/%s in %s\n", scanResult.Namespace(), scanResult.Identifier(), path)
	}
	return nil
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithBlockSize

func WithBlockSize(size int) func(writer *YaraReader)

WithBlockSize Sets the default buffer and block size for in-memory scanning

func WithFilenameTip

func WithFilenameTip(filename string) func(writer *YaraReader)

WithFilenameTip Will tip the Decoder on possible archive types

func WithMaxLevel

func WithMaxLevel(level int) func(writer *YaraReader)

WithMaxLevel Will prevent the Reader to inspect archives under and given level

Types

type RuleDirectory

type RuleDirectory struct {
	Namespace string
	Path      string
}

type YaraReader

type YaraReader struct {
	Infected bool
	// contains filtered or unexported fields
}

func (*YaraReader) First

func (s *YaraReader) First() *yara.MemoryBlock

First Will fetch the first block and cache it in our reader for further calls

func (*YaraReader) Next

func (s *YaraReader) Next() *yara.MemoryBlock

Next Will fetch the next block for scanning

func (*YaraReader) RuleMatching

func (y *YaraReader) RuleMatching(_ *yara.ScanContext, rule *yara.Rule) (bool, error)

RuleMatching will be called by the engine when a rule is matched

type YaraScanner

type YaraScanner struct {
	// contains filtered or unexported fields
}

func NewYaraScanner

func NewYaraScanner(ruleDirectories ...RuleDirectory) (*YaraScanner, error)

NewYaraScanner Will return a new scanner with rules compiled

func (*YaraScanner) ScanReader

func (s *YaraScanner) ScanReader(reader io.Reader, opts ...func(writer *YaraReader)) ([]*yara.Rule, error)

ScanReader Will scan a given reader until EOF or an error happens. It will scan archives.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL