mozilla / mig

Distributed & real time digital forensics at the speed of the cloud

Home Page:http://mig.mozilla.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot use C:\\ as search path

Leejdie opened this issue · comments

When investigating a Windows machine, using C:\ as the search path does not work. Using multiple C:<folder-name> does.

The search failed on "C:\Documents and settings" which is a link. This need a fix in function pathWalk from module file.
"C:\System Volume Information" seems like an other special directory and it's not a link.

After some investigations ... there are errors with EvalSymlinks from windows which now return an access denied error but there are other access denied errors from usual mysterious Windows reasons.

So here is a patch proposal (without formating):

diff --git a/modules/file/file.go b/modules/file/file.go

index 4598a50..47efe66 100644
--- a/modules/file/file.go
+++ b/modules/file/file.go
@@ -26,6 +26,7 @@ import (
        "path"
        "path/filepath"
        "regexp"
+       "runtime"
        "sort"
        "strconv"
        "strings"
@@ -902,7 +903,7 @@ func (r *run) pathWalk(path string, roots []string) (traversed []string, err err
        for _, dir := range subdirs {
                traversed, err = r.pathWalk(dir, roots)
                if err != nil {
-                       panic(err)
+                       if runtime.GOOS != "windows" { panic(err) } // don't panic with windows ;-)
                }
        }

What do you think about this ?

I compiled a version of the mig cmdline for windows and tested a local searched, it failed with the error:

C:\>C:\Users\ulfr\Downloads\mig.exe file -t local -name "mig.exe" -path "." -verbose
validating label 's1'
validating name 'mig.exe'
validating label 's1'
validating name 'mig.exe'
making checks for label s1
adding path . to list of locations to traverse
entering root .

[.... snip ... bunch of directories get processes ...]

pathWalk: walking into '.\Documents and Settings\'
comparing current path '.\Documents and Settings\' with candidate search '.'
pathWalk: 1 searches are currently active
decreasing search depth for 's1' to '1'
pathWalk failed with error 'pathWalk() -> open .\Documents and Settings\: The system cannot find the path specified.'
Tested files:     44
Open Failed:      1
Total hits:       0
Execution time:   62.4001ms
---- results ----0 match found in search 's1'evaluateFile() -> GetFileAttributesEx .\hiberfil.sys: The process cannot access the file because it is being used by another process.evaluateFile() -> GetFileAttributesEx .\pagefile.sys: The process cannot access the file because it is being used by another process.ERROR: open .\Documents and Settings\: The system cannot find the path specified.ERROR: pathWalk() -> open .\Documents and Settings\: The system cannot find the path specified.Statistics: 44 files checked, 1 failed to open, 0 matched, ran in 62.4001ms.

@yvesago : I think we need something a little more robust in this case, simply ignoring errors from pathWalk on windows will lead to sadness down the road.

@jvehent agree, ignoring errors is not the good way.

A workaround for the EvalSymlinks bug could be to Lstat content before open and before append the path separator (your current error on .\Documents and Settings). If you try to evaluate 'C:\Documents and Settings' (without ending ), there's a 'access denied' error instead of 'cannot find path'.
But I don't know how to manage access denied errors for other directories like 'C:\System Volume Information', 'C:\Windows\CSC\v2.0.6' (Win7) or some antivirus directories. They come from restricted ACLs for system account only. This kind of silly ACLs could also be used on Linux.
Maybe the good way is to not panic but only warn on access denied errors ? I don't know how to catch an error number instead of the translated string.
Edit: os.IsPermission(err) catch access denied error

The lstat approach seems like a good idea, assuming it doesn't destroy performances. We already run filepath.Clean() on the base paths, which removes trailing slashes, so we could also call filepath.Clean() in pathWalk and append the trailing slash for directories.

The panic(err) on line 905 is recovered on line 761 and returned to the loop on line 725. The panic error is added to walkingErrors which lets the module continue and build the results to exit normally.

I think this patch would take care of the issue with exiting too early:

diff --git a/modules/file/file.go b/modules/file/file.go
index 4598a50..3c7e068 100644
--- a/modules/file/file.go
+++ b/modules/file/file.go
@@ -902,7 +902,8 @@ func (r *run) pathWalk(path string, roots []string) (traversed []string, err err
        for _, dir := range subdirs {
                traversed, err = r.pathWalk(dir, roots)
                if err != nil {
-                       panic(err)
+                       walkingErrors = append(walkingErrors, err.Error())
+                       continue
                }
        }
 finish:

On the access denied, I think those are due to running mig-agent as a non-system user, but I don't have a good understanding of permission models on Windows.