Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send hard coded labels in periodic client info updates #2935

Merged
merged 2 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions actions/client_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@ func GetClientInfo(
result.BuildTime = config_obj.Version.BuildTime
result.InstallTime = config_obj.Version.InstallTime
}

if config_obj.Client != nil {
result.Labels = config_obj.Client.Labels
}

return result
}
16 changes: 13 additions & 3 deletions artifacts/definitions/Windows/Forensics/SAM.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ export: |
]
'''

sources:
- precondition:
SELECT OS From info() where OS = 'windows'
precondition:
SELECT OS From info() where OS = 'windows'

sources:
- name: Parsed
query: |
SELECT Key.OSPath.Path AS Key,
Key.OSPath.DelegatePath AS Hive,
Expand All @@ -133,6 +134,15 @@ sources:
accessor="raw_reg")
WHERE _F AND _V

- name: CreateTimes
description: "Show the modified times of the \\SAM\\Domains\\Account\\Users\\Names keys"
query: |
SELECT Name AS Username, Mtime AS CreatedTime
FROM glob(globs='SAM\\Domains\\Account\\Users\\Names\\*',
root=pathspec(DelegatePath=SAMPath),
accessor="raw_reg")
WHERE Data.type =~ "Key"

column_types:
- name: F
type: hex
Expand Down
38 changes: 19 additions & 19 deletions artifacts/definitions/Windows/Network/NetstatEnriched.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ description: |

Examples include: Process name and path, authenticode information or
network connection details.
WARNING:
KillProcess - attempts to use Taskill to kill the processes returned.
DumpProcess - dumps the process as a sparse file for post processing.
Please only use these switches after scoping as there are no guardrails on

WARNING:
KillProcess - attempts to use Taskill to kill the processes returned.
DumpProcess - dumps the process as a sparse file for post processing.

Please only use these switches after scoping as there are no guardrails on
shooting yourself in the foot.

required_permissions:
- EXECVE

precondition: SELECT OS From info() where OS = 'windows'

parameters:
Expand Down Expand Up @@ -80,7 +80,7 @@ parameters:

- name: ProcessNameRegex
description: "regex search over source process name"
default: ^malware\.exe$
default: ^(malware\.exe|.*)$
type: regex
- name: ProcessPathRegex
description: "regex search over source process path"
Expand Down Expand Up @@ -129,7 +129,7 @@ parameters:
- name: KillProcess
description: "WARNING: If selected will attempt to kill process from all results."
type: bool

sources:
- name: Netstat
query: |
Expand Down Expand Up @@ -170,13 +170,13 @@ sources:
FamilyString as Family,
TypeString as Type,
Status,
Laddr.IP as SrcIP,
Laddr.IP as SrcIP,
Laddr.Port as SrcPort,
Raddr.IP as DestIP,
Raddr.IP as DestIP,
Raddr.Port as DestPort,
Timestamp
FROM netstat()
WHERE
WHERE
Name =~ ProcessNameRegex
AND Path =~ ProcessPathRegex
and CommandLine =~ CommandLineRegex
Expand All @@ -195,7 +195,7 @@ sources:
or format(format="%v", args=DestIP) =~ IPRegex )
and ( format(format="%v", args=SrcPort) =~ PortRegex
or format(format="%v", args=DestPort) =~ PortRegex )

LET Regions(Pid) = SELECT dict(Offset=Address, Length=Size) AS Sparse
FROM vad(pid=Pid)
WHERE Protection =~ "r"
Expand All @@ -207,19 +207,19 @@ sources:
DelegatePath=format(format="/%d", args=Pid)),
name=pathspec(Path=format(format="%d.dd", args=Pid))) AS ProcessMemory
FROM results
LET kill = SELECT *, pskill(pid=Pid) AS KillProcess
LET kill = SELECT *, pskill(pid=Pid) AS KillProcess
FROM results
LET dumpandkill = SELECT *, pskill(pid=Pid) AS KillProcess
LET dumpandkill = SELECT *, pskill(pid=Pid) AS KillProcess
FROM dump

SELECT * FROM switch(
a = {
a = {
SELECT *, if(condition= KillProcess=Null,then='Success',else=KillProcess) AS KillProcess
FROM if(condition= DumpProcess AND KillProcess, then= dumpandkill )},
b = { SELECT * FROM if(condition= DumpProcess, then= dump )},
c = {
c = {
SELECT *, if(condition= KillProcess=Null,then='Success',else=KillProcess) AS KillProcess
FROM if(condition= KillProcess, then= kill)
FROM if(condition= KillProcess, then= kill)
},
catch = results
)
5 changes: 4 additions & 1 deletion artifacts/testdata/server/testcases/raw_registry.in.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ Queries:

# Test the SAM parsers
- SELECT ParsedF, ParsedV FROM Artifact.Windows.Forensics.SAM(
SAMPath=srcDir+"/artifacts/testdata/files/SAM")
SAMPath=srcDir+"/artifacts/testdata/files/SAM", source="Parsed")

- SELECT * FROM Artifact.Windows.Forensics.SAM(
SAMPath=srcDir+"/artifacts/testdata/files/SAM", source="CreateTimes")

# Check raw reg can read values as files - REG_SZ.
- SELECT utf16(string=read_file(filename=pathspec(
Expand Down
28 changes: 27 additions & 1 deletion artifacts/testdata/server/testcases/raw_registry.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ SELECT mock(plugin='info', results=[dict(OS='windows'), dict(OS='windows')] ) FR
}
}
}
]SELECT ParsedF, ParsedV FROM Artifact.Windows.Forensics.SAM( SAMPath=srcDir+"/artifacts/testdata/files/SAM")[
]SELECT ParsedF, ParsedV FROM Artifact.Windows.Forensics.SAM( SAMPath=srcDir+"/artifacts/testdata/files/SAM", source="Parsed")[
{
"ParsedF": {
"LastLoginDate": "1601-01-01T00:00:00Z",
Expand Down Expand Up @@ -456,6 +456,32 @@ SELECT mock(plugin='info', results=[dict(OS='windows'), dict(OS='windows')] ) FR
"ntpwd_hash": "\u0002\u0002\u0010"
}
}
]SELECT * FROM Artifact.Windows.Forensics.SAM( SAMPath=srcDir+"/artifacts/testdata/files/SAM", source="CreateTimes")[
{
"Username": "Administrator",
"CreatedTime": "2021-10-08T00:54:13Z",
"_Source": "Windows.Forensics.SAM/CreateTimes"
},
{
"Username": "DefaultAccount",
"CreatedTime": "2021-10-08T00:54:13Z",
"_Source": "Windows.Forensics.SAM/CreateTimes"
},
{
"Username": "Guest",
"CreatedTime": "2021-10-08T00:54:13Z",
"_Source": "Windows.Forensics.SAM/CreateTimes"
},
{
"Username": "WDAGUtilityAccount",
"CreatedTime": "2021-10-08T00:54:13Z",
"_Source": "Windows.Forensics.SAM/CreateTimes"
},
{
"Username": "test",
"CreatedTime": "2021-10-07T08:07:32Z",
"_Source": "Windows.Forensics.SAM/CreateTimes"
}
]SELECT utf16(string=read_file(filename=pathspec( Path="\\Root\\DeviceCensus\\Processor\\ProcessorIdentifier", DelegatePath=srcDir+"/artifacts/testdata/files/Amcache.hve", DelegateAccessor='file'), accessor="raw_reg")) FROM scope()[
{
"utf16(string=read_file(filename=pathspec(Path=\"\\\\Root\\\\DeviceCensus\\\\Processor\\\\ProcessorIdentifier\", DelegatePath=srcDir + \"/artifacts/testdata/files/Amcache.hve\", DelegateAccessor='file'), accessor=\"raw_reg\"))": "Intel64 Family 6 Model 62 Stepping 4\u0000"
Expand Down
2 changes: 1 addition & 1 deletion constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
)

var (
VERSION = "0.7.0"
VERSION = "0.7.0-2"
)

const (
Expand Down
64 changes: 40 additions & 24 deletions flows/client_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ import (
// minions rathen than getting sent to event moniroting.
func (self *ClientFlowRunner) maybeProcessClientInfo(
ctx context.Context, client_id string, response *actions_proto.VQLResponse) error {

if response.Query == nil ||
response.Query.Name != "Server.Internal.ClientInfo" {
return nil
}

client_info := services.ClientInfo{}
client_info := &services.ClientInfo{}
err := json.Unmarshal([]byte(response.JSONLResponse), &client_info.ClientInfo)
if err != nil {
return err
Expand All @@ -30,33 +29,50 @@ func (self *ClientFlowRunner) maybeProcessClientInfo(
return err
}

old_client_info, err := client_info_manager.Get(ctx, client_id)
err = client_info_manager.Modify(ctx, client_id,
func(old_client_info *services.ClientInfo) (*services.ClientInfo, error) {
if old_client_info == nil {
return client_info, nil
}

dirty := false
update := func(old, new *string) {
if *old != *new {
*old = *new
dirty = true
}
}

// Now merge the new record with the old
old_client_info.ClientId = client_id
update(&old_client_info.Hostname, &client_info.Hostname)
update(&old_client_info.System, &client_info.System)
update(&old_client_info.Release, &client_info.Release)
update(&old_client_info.Architecture, &client_info.Architecture)
update(&old_client_info.Fqdn, &client_info.Fqdn)
update(&old_client_info.ClientName, &client_info.ClientName)
update(&old_client_info.ClientVersion, &client_info.ClientVersion)
update(&old_client_info.BuildUrl, &client_info.BuildUrl)
update(&old_client_info.BuildTime, &client_info.BuildTime)

// Nothing to do ignore the update.
if !dirty {
return nil, nil
}
return old_client_info, nil
})
if err != nil {
return client_info_manager.Set(ctx, &client_info)
return err
}

dirty := false
update := func(old, new *string) {
if *old != *new {
*old = *new
dirty = true
// Now update any labels baked into the client.
if len(client_info.Labels) > 0 {
labeler := services.GetLabeler(self.config_obj)

for _, label := range client_info.Labels {
labeler.SetClientLabel(ctx, self.config_obj, client_id, label)
}
}

// Now merge the new record with the old
old_client_info.ClientId = client_id
update(&old_client_info.Hostname, &client_info.Hostname)
update(&old_client_info.System, &client_info.System)
update(&old_client_info.Release, &client_info.Release)
update(&old_client_info.Architecture, &client_info.Architecture)
update(&old_client_info.Fqdn, &client_info.Fqdn)
update(&old_client_info.ClientName, &client_info.ClientName)
update(&old_client_info.ClientVersion, &client_info.ClientVersion)
update(&old_client_info.BuildUrl, &client_info.BuildUrl)
update(&old_client_info.BuildTime, &client_info.BuildTime)

if dirty {
return client_info_manager.Set(ctx, old_client_info)
}
return nil
}
4 changes: 0 additions & 4 deletions vql/psutils/process_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"golang.org/x/sys/unix"

"github.com/Velocidex/ordereddict"
"www.velocidex.com/golang/velociraptor/utils"
)

func GetProcess(ctx context.Context, pid int32) (*ordereddict.Dict, error) {
Expand All @@ -33,9 +32,6 @@ func ListProcesses(ctx context.Context) ([]*ordereddict.Dict, error) {
}

for _, item := range processes {
if false {
utils.Debug(item)
}
result = append(result, getProcessData(ctx, &item))
}

Expand Down