diff --git a/cmd/fmount/main.go b/cmd/fmount/main.go index c9f1bca..921c878 100644 --- a/cmd/fmount/main.go +++ b/cmd/fmount/main.go @@ -2,7 +2,7 @@ // // Usage: // -// fmount [-suzhv] [-T RAW|DD] [-D DIRECTORY] IMAGE +// fmount [-suzhv] [-H CRC32|MD5|SHA1|SHA256|SHA512] [-V SUM] [-T RAW|DD] [-D DIRECTORY] IMAGE // // The flags are: // @@ -10,6 +10,10 @@ // The mount point directory. // -T type // The disk image type. +// -H algorithm +// The hash algorithm to use. +// -V sum +// The hash sum to verify. // -s // System partition only. // -u @@ -42,6 +46,8 @@ var Version string = "dev" func main() { D := flag.String("D", "", "Mount point") T := flag.String("T", "", "Image type") + H := flag.String("H", "", "Hash algorithm") + V := flag.String("V", "", "Hash sum") s := flag.Bool("s", false, "System partition only") u := flag.Bool("u", false, "Unmount image") z := flag.Bool("z", false, "Unzip image") @@ -58,7 +64,7 @@ func main() { } if *h || len(img) == 0 { - sys.Usage("fmount [-suzhv] [-T RAW|DD] [-D DIRECTORY] IMAGE") + sys.Usage("fmount [-suzhv] [-H CRC32|MD5|SHA1|SHA256|SHA512] [-V SUM] [-T RAW|DD] [-D DIRECTORY] IMAGE") } it, err := fmount.DetectType(img, *T) @@ -73,6 +79,14 @@ func main() { args = append(args, "-D", *D) } + if len(*H) > 0 { + args = append(args, "-H", *H) + } + + if len(*V) > 0 { + args = append(args, "-V", *V) + } + if *s { args = append(args, "-s") } diff --git a/docs/fmount.dd.md b/docs/fmount.dd.md index e3459a7..e53497e 100644 --- a/docs/fmount.dd.md +++ b/docs/fmount.dd.md @@ -2,12 +2,14 @@ Mount forensic raw or dd disk images for read-only processing. ```sh -$ fmount.dd [-fsuzhv] [-D DIRECTORY] IMAGE +$ fmount.dd [-fsuzhv] [-H CRC32|MD5|SHA1|SHA256|SHA512] [-V SUM] [-D DIRECTORY] IMAGE ``` Available options: - `-D` Mount point +- `-H` Hash algorithm +- `-V` Verify hash sum - `-f` Force type - `-s` System partition only - `-u` Unmount image diff --git a/docs/fmount.md b/docs/fmount.md index ed14fa4..e6fc52d 100644 --- a/docs/fmount.md +++ b/docs/fmount.md @@ -2,13 +2,15 @@ Mount forensic disk images for read-only processing. ```sh -$ fmount [-suzhv] [-T RAW|DD] [-D DIRECTORY] IMAGE +$ fmount [-suzhv] [-H CRC32|MD5|SHA1|SHA256|SHA512] [-V SUM] [-T RAW|DD] [-D DIRECTORY] IMAGE ``` Available options: - `-D` Mount point - `-T` Image type +- `-H` Hash algorithm +- `-V` Verify hash sum - `-s` System partition only - `-u` Unmount image - `-z` Unzip image diff --git a/pkg/ffind/ffind.go b/pkg/ffind/ffind.go index 2a29c3f..a5c0b3a 100644 --- a/pkg/ffind/ffind.go +++ b/pkg/ffind/ffind.go @@ -3,29 +3,18 @@ package ffind import ( "archive/zip" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" "fmt" - "hash" - "hash/crc32" "io" "os" - "strings" "sync" "time" + "github.com/cuhsat/fact/internal/hash" "github.com/cuhsat/fact/internal/sys" "github.com/cuhsat/fact/pkg/windows" ) const ( - CRC32 = "crc32" - MD5 = "md5" - SHA1 = "sha1" - SHA256 = "sha256" - SHA512 = "sha512" rLimit = 1024 ) @@ -34,15 +23,15 @@ type ffind struct { sysroot string archive string - hash string + algo string rp bool so bool uo bool } -func Find(sysroot, archive, hash string, rp, so, uo bool) (lines []string) { +func Find(sysroot, archive, algo string, rp, so, uo bool) (lines []string) { // Going into live mode - if len(sysroot)+len(archive)+len(hash) == 0 { + if len(sysroot)+len(archive)+len(algo) == 0 { host, err := os.Hostname() if err != nil { @@ -51,13 +40,13 @@ func Find(sysroot, archive, hash string, rp, so, uo bool) (lines []string) { } archive = host + ".zip" - hash = SHA256 + algo = hash.SHA256 } ff := &ffind{ sysroot: sysroot, archive: archive, - hash: hash, + algo: algo, rp: rp, so: so, uo: uo, @@ -128,6 +117,7 @@ func (ff *ffind) zip(in, out chan string) { defer a.Close() + // TODO: move to internal/zip w := zip.NewWriter(a) defer w.Close() @@ -168,53 +158,21 @@ func (ff *ffind) log(in, out chan string) { defer close(out) defer ff.wg.Done() - var h hash.Hash - - switch strings.ToLower(ff.hash) { - case CRC32: - h = crc32.NewIEEE() - case MD5: - h = md5.New() - case SHA1: - h = sha1.New() - case SHA256: - h = sha256.New() - case SHA512: - h = sha512.New() - default: - if len(ff.hash) > 0 { - sys.Error("hash not supported:", ff.hash) - } - } - - if h == nil { - for artifact := range in { - out <- ff.path(artifact) - } - - return - } - for artifact := range in { - h.Reset() - - src, err := os.Open(artifact) + p := ff.path(artifact) - if err != nil { - sys.Error(err) - continue - } - - _, err = io.Copy(h, src) + if len(ff.algo) > 0 { + s, err := hash.Sum(artifact, ff.algo) - src.Close() + if err != nil { + sys.Error(err) + continue + } - if err != nil { - sys.Error(err) - continue + out <- fmt.Sprintf("%x %s", s, p) + } else { + out <- p } - - out <- fmt.Sprintf("%x %s", h.Sum(nil), ff.path(artifact)) } } diff --git a/pkg/fmount/fmount.go b/pkg/fmount/fmount.go index 0aa3776..b8a7058 100644 --- a/pkg/fmount/fmount.go +++ b/pkg/fmount/fmount.go @@ -3,11 +3,13 @@ package fmount import ( "errors" + "fmt" "os" "path" "path/filepath" "strings" + "github.com/cuhsat/fact/internal/hash" "github.com/cuhsat/fact/internal/sys" "github.com/cuhsat/fact/internal/zip" "github.com/cuhsat/fact/pkg/fmount/dd" @@ -55,6 +57,18 @@ func Extract(img string) (p string, err error) { return } +func Verify(img, algo, sum string) (ok bool, err error) { + b, err := hash.Sum(img, algo) + + if err != nil { + return + } + + ok = fmt.Sprintf("%x", b) == strings.ToLower(sum) + + return +} + func Forward(name string, arg ...string) { sys.ExitCall(name, arg...) }