From 79c9bf1a65118e71d2a09cbddd49968da07ceba0 Mon Sep 17 00:00:00 2001 From: Christian Uhsat Date: Sat, 18 May 2024 22:47:59 +0200 Subject: [PATCH] version 0.11 --- cmd/ffind/main.go | 2 +- cmd/fmount/main.go | 2 +- internal/sys/sys.go | 26 +++++++--- internal/zip/zip.go | 71 ++++++++++---------------- internal/zip/zip_utils.go | 78 +++++++++++++++++++++++++++++ pkg/ffind/ffind.go | 102 +++++++++++++++----------------------- pkg/windows/system.go | 2 +- 7 files changed, 165 insertions(+), 118 deletions(-) create mode 100644 internal/zip/zip_utils.go diff --git a/cmd/ffind/main.go b/cmd/ffind/main.go index 7a7a010..dae04a7 100644 --- a/cmd/ffind/main.go +++ b/cmd/ffind/main.go @@ -72,7 +72,7 @@ func main() { sys.Fatal("archive name required") } - files := ffind.Find(sys.Input(), *Z, *H, *r, *s, *u) + files := ffind.Find(sys.Param(), *Z, *H, *r, *s, *u) if len(*F) > 0 { b := []byte(strings.Join(files, "\n")) diff --git a/cmd/fmount/main.go b/cmd/fmount/main.go index 751a93a..47cf366 100644 --- a/cmd/fmount/main.go +++ b/cmd/fmount/main.go @@ -57,7 +57,7 @@ func main() { flag.CommandLine.SetOutput(io.Discard) flag.Parse() - img := sys.Input() + img := sys.Param() if *v { sys.Print("fmount", Version) diff --git a/internal/sys/sys.go b/internal/sys/sys.go index 1ebd661..8e5bbad 100644 --- a/internal/sys/sys.go +++ b/internal/sys/sys.go @@ -30,18 +30,28 @@ func Usage(u string) { os.Exit(2) } -func Input() string { +func Param() (p string) { + l := Params() + + if len(l) > 0 { + p = l[0] + } + + return +} + +func Params() []string { if flag.NArg() > 0 { - return flag.Arg(0) - } else { - stdin, err := Stdin() + return flag.Args() + } - if err != nil { - Fatal(err) - } + stdin, err := Stdin() - return stdin + if err != nil { + Fatal(err) } + + return strings.Split(stdin, "\n") } func Stdin() (in string, err error) { diff --git a/internal/zip/zip.go b/internal/zip/zip.go index e726a1c..d476d91 100644 --- a/internal/zip/zip.go +++ b/internal/zip/zip.go @@ -5,73 +5,56 @@ import ( "archive/zip" "io" "os" - "path" - "path/filepath" - "slices" ) -func Index(name string) (files []string, err error) { - a, err := zip.OpenReader(name) +type Zip struct { + f *os.File + w *zip.Writer +} + +func NewZip(name, meta string) (z *Zip, err error) { + z = &Zip{} + + z.f, err = os.Create(name) if err != nil { return } - defer a.Close() - - for _, f := range a.File { - if !f.FileInfo().IsDir() { - files = append(files, filepath.ToSlash(f.Name)) - } - } + z.w = zip.NewWriter(z.f) - slices.Sort(files) + err = z.w.SetComment(meta) return } -func Unzip(name, dir string) (err error) { - a, err := zip.OpenReader(name) +func (z *Zip) Write(src, dst string) (err error) { + s, err := os.Open(src) if err != nil { return } - defer a.Close() - - for _, f := range a.File { - file := path.Join(dir, f.Name) - - if f.FileInfo().IsDir() { - os.MkdirAll(file, os.ModePerm) - continue - } - - if err = os.MkdirAll(path.Dir(file), os.ModePerm); err != nil { - return err - } - - src, err := f.Open() + defer s.Close() - if err != nil { - return err - } + d, err := z.w.Create(dst) - dst, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + if err != nil { + return + } - if err != nil { - src.Close() - return err - } + _, err = io.Copy(d, s) - _, err = io.Copy(dst, src) + return +} - dst.Close() - src.Close() +func (z *Zip) Close() (err error) { + if err = z.w.Close(); err != nil { + return + } - if err != nil { - return err - } + if err = z.f.Close(); err != nil { + return } return diff --git a/internal/zip/zip_utils.go b/internal/zip/zip_utils.go new file mode 100644 index 0000000..3aaf4c6 --- /dev/null +++ b/internal/zip/zip_utils.go @@ -0,0 +1,78 @@ +// Zip utils functions. +package zip + +import ( + "archive/zip" + "io" + "os" + "path" + "path/filepath" + "slices" +) + +func Index(name string) (files []string, err error) { + a, err := zip.OpenReader(name) + + if err != nil { + return + } + + defer a.Close() + + for _, f := range a.File { + if !f.FileInfo().IsDir() { + files = append(files, filepath.ToSlash(f.Name)) + } + } + + slices.Sort(files) + + return +} + +func Unzip(name, dir string) (err error) { + a, err := zip.OpenReader(name) + + if err != nil { + return + } + + defer a.Close() + + for _, f := range a.File { + file := path.Join(dir, filepath.ToSlash(f.Name)) + + if f.FileInfo().IsDir() { + os.MkdirAll(file, os.ModePerm) + continue + } + + if err = os.MkdirAll(path.Dir(file), os.ModePerm); err != nil { + return err + } + + src, err := f.Open() + + if err != nil { + return err + } + + dst, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + + if err != nil { + src.Close() + return err + } + + _, err = io.Copy(dst, src) + + dst.Close() + src.Close() + + if err != nil { + return err + } + } + + return +} diff --git a/pkg/ffind/ffind.go b/pkg/ffind/ffind.go index a5c0b3a..c3a35a1 100644 --- a/pkg/ffind/ffind.go +++ b/pkg/ffind/ffind.go @@ -2,15 +2,14 @@ package ffind import ( - "archive/zip" "fmt" - "io" "os" "sync" "time" "github.com/cuhsat/fact/internal/hash" "github.com/cuhsat/fact/internal/sys" + "github.com/cuhsat/fact/internal/zip" "github.com/cuhsat/fact/pkg/windows" ) @@ -30,19 +29,6 @@ type ffind struct { } func Find(sysroot, archive, algo string, rp, so, uo bool) (lines []string) { - // Going into live mode - if len(sysroot)+len(archive)+len(algo) == 0 { - host, err := os.Hostname() - - if err != nil { - sys.Error(err) - host = "fact" // fallback - } - - archive = host + ".zip" - algo = hash.SHA256 - } - ff := &ffind{ sysroot: sysroot, archive: archive, @@ -52,22 +38,20 @@ func Find(sysroot, archive, algo string, rp, so, uo bool) (lines []string) { uo: uo, } + // Go into live mode? + if len(ff.sysroot)+len(ff.archive)+len(ff.algo) == 0 { + ff.live() + } + ch1 := make(chan string, rLimit) ch2 := make(chan string, rLimit) ch3 := make(chan string, rLimit) - if len(ff.archive) > 0 { - ff.wg.Add(3) + ff.wg.Add(3) - go ff.find(ch1) - go ff.zip(ch1, ch2) - go ff.log(ch2, ch3) - } else { - ff.wg.Add(2) - - go ff.find(ch1) - go ff.log(ch1, ch3) - } + go ff.find(ch1) + go ff.zip(ch1, ch2) + go ff.log(ch2, ch3) for l := range ch3 { lines = append(lines, l) @@ -103,58 +87,37 @@ func (ff *ffind) find(out chan<- string) { } } -func (ff *ffind) zip(in, out chan string) { +func (ff *ffind) zip(in <-chan string, out chan<- string) { defer close(out) defer ff.wg.Done() - // TODO: file init after something was found - a, err := os.Create(ff.archive) - - if err != nil { - sys.Error(err) - return - } - - defer a.Close() - - // TODO: move to internal/zip - w := zip.NewWriter(a) - - defer w.Close() - - w.SetComment(time.Now().Format(time.RFC3339)) + var z *zip.Zip + var err error for artifact := range in { + if len(ff.archive) > 0 { + if z == nil { + z, err = zip.NewZip(ff.archive, time.Now().Format(time.RFC3339)) - src, err := os.Open(artifact) + if err != nil { + sys.Fatal(err) + } - if err != nil { - sys.Error(err) - continue - } - - dst, err := w.Create(ff.path(artifact)) - - if err != nil { - sys.Error(err) - src.Close() - continue - } - - _, err = io.Copy(dst, src) + defer z.Close() + } - src.Close() + err := z.Write(artifact, ff.path(artifact)) - if err != nil { - sys.Error(err) - continue + if err != nil { + sys.Error(err) + } } out <- artifact } } -func (ff *ffind) log(in, out chan string) { +func (ff *ffind) log(in <-chan string, out chan<- string) { defer close(out) defer ff.wg.Done() @@ -176,6 +139,19 @@ func (ff *ffind) log(in, out chan string) { } } +func (ff *ffind) live() { + host, err := os.Hostname() + + if err != nil { + host = "fact" // fallback + sys.Error(err) + } + + ff.archive = host + ".zip" + ff.algo = hash.SHA256 + // TODO: add file for hash output +} + func (ff *ffind) path(f string) string { if !ff.rp { return f diff --git a/pkg/windows/system.go b/pkg/windows/system.go index 86839df..0078d7e 100644 --- a/pkg/windows/system.go +++ b/pkg/windows/system.go @@ -27,7 +27,7 @@ func EnumSystem(sysroot string, out chan<- string) { "[Ss]ystem32/[Cc]onfig/[Ss][Ee][Cc][Uu][Rr][Ii][Tt][Yy]", "[Ss]ystem32/[Cc]onfig/[Ss][Oo][Ff][Tt][Ww][Aa][Rr][Ee]", "[Ss]ystem32/[Cc]onfig/[Ss][Yy][Ss][Tt][Ee][Mm]", - "[Ss]ystem32/[Ww]inevt/[Ll]ogs/*.evtx", + "[Ss]ystem32/[Ww]inevt/[Ll]ogs/*.evt*", "[Pp]refetch/*.pf", "[Aa]m[Cc]ompat/[Pp]rograms/[Aa]m[Cc]ache.hve", } {