Skip to content

Commit

Permalink
Added a parse_mft() plugin and artifact. (#160)
Browse files Browse the repository at this point in the history
This can be used to dump all files from the MFT on an endpoint.
  • Loading branch information
scudette authored Nov 12, 2019
1 parent d292de0 commit 0ef3a36
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 80 deletions.
2 changes: 1 addition & 1 deletion api/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ func GetClientPath(vfs_path string) (client_path string, accessor string) {
}

if strings.HasPrefix(vfs_path, "/registry") {
return strings.TrimPrefix(vfs_path, "/registry"), "reg"
return strings.TrimPrefix(vfs_path, "/registry"), "registry"
}

if strings.HasPrefix(vfs_path, "/ntfs/") {
Expand Down
177 changes: 107 additions & 70 deletions artifacts/assets/ab0x.go

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions artifacts/definitions/Windows/NTFS/MFT.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Windows.NTFS.MFT
description: |
This artifact scans the $MFT file on the host showing all files
within the MFT. This is useful in order to try and recover deleted
files. Take the MFT ID of a file of interest and provide it to the
Windows.NTFS.Recover artifact.
parameters:
- name: MFTFilename
default: "C:/$MFT"

- name: Accessor
default: ntfs

sources:
- queries:
- SELECT * FROM parse_mft(filename=MFTFilename, accessor=Accessor)
4 changes: 2 additions & 2 deletions config/ab0x.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 9 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,24 @@ require (
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/mattn/go-pointer v0.0.0-20180825124634-49522c3f3791
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/mattn/go-runewidth v0.0.6 // indirect
github.com/mattn/go-sqlite3 v1.11.0
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 // indirect
github.com/microcosm-cc/bluemonday v1.0.2
github.com/olekukonko/tablewriter v0.0.1
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/olekukonko/tablewriter v0.0.2
github.com/pkg/errors v0.8.1
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // indirect
github.com/prometheus/client_golang v1.2.1
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d
github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7 // indirect
github.com/sebdah/goldie v0.0.0-20190531093107-d313ffb52c77
github.com/sebdah/goldie v1.0.0
github.com/sergi/go-diff v1.0.0
github.com/shirou/gopsutil v0.0.0-20190627142359-4c8b404ee5c5
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.4.0
github.com/tebeka/strftime v0.1.3 // indirect
github.com/tink-ab/tempfile v0.0.0-20180226111222-33beb0518f1a
Expand All @@ -86,7 +89,7 @@ require (
golang.org/x/net v0.0.0-20191021144547-ec77196f6094
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd
golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4
golang.org/x/tools v0.0.0-20191022074931-774d2ec196ee // indirect
google.golang.org/api v0.11.0
google.golang.org/appengine v1.6.5 // indirect
Expand All @@ -98,9 +101,9 @@ require (
gopkg.in/gomail.v2 v2.0.0-20150902115704-41f357289737
gopkg.in/russross/blackfriday.v2 v2.0.1
gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v2 v2.2.4 // indirect
gopkg.in/yaml.v2 v2.2.5 // indirect
www.velocidex.com/golang/evtx v0.0.0-20191106094253-bdccd0816780
www.velocidex.com/golang/go-ntfs v0.0.0-20191007011621-167c7fa020db
www.velocidex.com/golang/go-ntfs v0.0.0-20191111130957-a40c0d1ab536
www.velocidex.com/golang/go-pe v0.1.1-0.20191103232346-ac12e8190bb6
www.velocidex.com/golang/go-prefetch v0.0.0-20190703150313-0469fa2f85cf
www.velocidex.com/golang/oleparse v0.0.0-20190327031422-34195d413196
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFi
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
Expand Down Expand Up @@ -257,6 +259,8 @@ github.com/mattn/go-pointer v0.0.0-20180825124634-49522c3f3791/go.mod h1:2zXcozF
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
Expand All @@ -279,6 +283,8 @@ github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYX
github.com/olekukonko/tablewriter v0.0.0-20180912035003-be2c049b30cc/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o=
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -316,6 +322,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/sebdah/goldie v0.0.0-20180424091453-8784dd1ab561/go.mod h1:lvjGftC8oe7XPtyrOidaMi0rp5B9+XY/ZRUynGnuaxQ=
github.com/sebdah/goldie v0.0.0-20190531093107-d313ffb52c77 h1:Msb6XRY62jQOueNNlB5LGin1rljK7c49NLniGwJG2bg=
github.com/sebdah/goldie v0.0.0-20190531093107-d313ffb52c77/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v0.0.0-20190627142359-4c8b404ee5c5 h1:t5PgljoKFvOqjzOAooGmvWIzXP9y10yTmWJZS5xZgww=
Expand All @@ -329,6 +336,7 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
Expand Down Expand Up @@ -430,6 +438,8 @@ golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c h1:S/FtSvpNLtFBgjTqcKsRpsa6a
golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd h1:3x5uuvBgE6oaXJjCOvpCC1IpgJogqQ+PqGGU3ZxAgII=
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4 h1:Hynbrlo6LbYI3H1IqXpkVDOcX/3HiPdhVEuyj5a59RM=
golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
Expand Down Expand Up @@ -507,6 +517,8 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand All @@ -522,6 +534,8 @@ www.velocidex.com/golang/evtx v0.0.0-20191106094253-bdccd0816780 h1:3lxyxSiGhnkU
www.velocidex.com/golang/evtx v0.0.0-20191106094253-bdccd0816780/go.mod h1:+u26IeGeVIwL9j5V0I/UafWFaMV61pQNwXZK/VQksLQ=
www.velocidex.com/golang/go-ntfs v0.0.0-20191007011621-167c7fa020db h1:KxrG77cDNesk56zDxYFAYt4o32nwx6xNjj19omdI5sU=
www.velocidex.com/golang/go-ntfs v0.0.0-20191007011621-167c7fa020db/go.mod h1:RURmuGxhf8w3yTlERqW1rpYZXgHQH5N2T8FQYkPYJUY=
www.velocidex.com/golang/go-ntfs v0.0.0-20191111130957-a40c0d1ab536 h1:dBIkTiYLTsbeMR2L8VN3IxXZFbFYU951oRl6xYas4Ig=
www.velocidex.com/golang/go-ntfs v0.0.0-20191111130957-a40c0d1ab536/go.mod h1:dhcNkYlQGhX+HIPSAL2+1yVHZfHq+P/0qhNfHBg7RfI=
www.velocidex.com/golang/go-pe v0.1.1-0.20191103232346-ac12e8190bb6 h1:t+4cuel1gs9H854UvXSVwL/Ph7wAhGUq8xNEiEuG7x4=
www.velocidex.com/golang/go-pe v0.1.1-0.20191103232346-ac12e8190bb6/go.mod h1:vpdQNvh2GfQT5NNhtpyGirOSYGTy2IJheePUBpP/zHs=
www.velocidex.com/golang/go-prefetch v0.0.0-20190703150313-0469fa2f85cf h1:MhCevuCZJLBXoiYjL2W7qy7OugVZm/LBB11D6iKYUMY=
Expand Down
2 changes: 1 addition & 1 deletion services/vfs_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func (self *VFSService) flush_state(scope *vfilter.Scope,
func getVfsPath(client_path string, accessor string) string {
prefix := "/file"
switch accessor {
case "reg":
case "reg", "registry":
prefix = "/registry"
case "ntfs":
prefix = "/ntfs"
Expand Down
12 changes: 12 additions & 0 deletions utils/readers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package utils

import "io"

type ReaderAtter struct {
Reader io.ReadSeeker
}

func (self ReaderAtter) ReadAt(buf []byte, offset int64) (int, error) {
self.Reader.Seek(offset, 0)
return self.Reader.Read(buf)
}
71 changes: 71 additions & 0 deletions vql/parsers/ntfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (

"github.com/Velocidex/ordereddict"
ntfs "www.velocidex.com/golang/go-ntfs/parser"
"www.velocidex.com/golang/velociraptor/glob"
utils "www.velocidex.com/golang/velociraptor/utils"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
vfilter "www.velocidex.com/golang/vfilter"
)
Expand Down Expand Up @@ -173,6 +175,74 @@ func (self NTFSFunction) Call(
return &NTFSModel{NTFSFileInformation: result, Device: device}
}

type MFTScanPluginArgs struct {
Filename string `vfilter:"required,field=filename,doc=A list of event log files to parse."`
Accessor string `vfilter:"optional,field=accessor,doc=The accessor to use."`
}

type MFTScanPlugin struct{}

func (self MFTScanPlugin) Call(
ctx context.Context,
scope *vfilter.Scope,
args *ordereddict.Dict) <-chan vfilter.Row {
output_chan := make(chan vfilter.Row)

go func() {
defer close(output_chan)

arg := &MFTScanPluginArgs{}
err := vfilter.ExtractArgs(scope, args, arg)
if err != nil {
scope.Log("parse_mft: %v", err)
return
}

accessor, err := glob.GetAccessor(arg.Accessor, ctx)
if err != nil {
scope.Log("parse_mft: %v", err)
return
}
fd, err := accessor.Open(arg.Filename)
if err != nil {
scope.Log("parse_mft: Unable to open file %s: %v",
arg.Filename, err)
return
}
defer fd.Close()

reader, err := ntfs.NewPagedReader(
utils.ReaderAtter{fd}, 1024, 10000)
if err != nil {
scope.Log("parse_mft: Unable to open file %s: %v",
arg.Filename, err)
return
}

st, err := fd.Stat()
if err != nil {
scope.Log("parse_mft: Unable to open file %s: %v",
arg.Filename, err)
return
}

for item := range ntfs.ParseMFTFile(
reader, st.Size(), 0x1000, 0x400) {
output_chan <- item
}
}()

return output_chan
}

func (self MFTScanPlugin) Info(scope *vfilter.Scope, type_map *vfilter.TypeMap) *vfilter.PluginInfo {
return &vfilter.PluginInfo{
Name: "parse_mft",
Doc: "Scan the $MFT from an NTFS volume.",
ArgType: type_map.AddType(scope, &MFTScanPluginArgs{}),
}
}

type NTFSI30ScanPlugin struct{}

func (self NTFSI30ScanPlugin) Call(
Expand Down Expand Up @@ -235,4 +305,5 @@ func (self NTFSI30ScanPlugin) Info(scope *vfilter.Scope, type_map *vfilter.TypeM
func init() {
vql_subsystem.RegisterFunction(&NTFSFunction{})
vql_subsystem.RegisterPlugin(&NTFSI30ScanPlugin{})
vql_subsystem.RegisterPlugin(&MFTScanPlugin{})
}

0 comments on commit 0ef3a36

Please sign in to comment.