Velociraptor priviledge escalation via UpdateConfig artifact
Description
Velociraptor allows collection of VQL queries packaged into Artifacts from endpoints. These artifacts can be used to do anything and usually run with elevated permissions. To limit access to some dangerous artifact, Velociraptor allows for those to require high permissions like EXECVE to launch.
The Admin.Client.UpdateClientConfig is an artifact used to update the client's configuration. This artifact did not enforce an additional required permission, allowing users with COLLECT_CLIENT permissions (normally given by the "Investigator" role) to collect it from endpoints and update the configuration.
This can lead to arbitrary command execution and endpoint takeover.
To successfully exploit this vulnerability the user must already have access to collect artifacts from the endpoint (i.e. have the COLLECT_CLIENT given typically by the "Investigator' role).
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
www.velocidex.com/golang/velociraptorGo | < 0.74.3 | 0.74.3 |
Affected products
1- Range: 0
Patches
121e7fd7138ddImplemented static analysis for client side permissions (#4246)
46 files changed · +646 −360
accessors/pst/cache.go+2 −2 modified@@ -1,5 +1,5 @@ -//go:build !linux && !386 -// +build !linux,!386 +//go:build !386 +// +build !386 package pst
accessors/pst/pst_accessor.go+2 −2 modified@@ -1,5 +1,5 @@ -//go:build !linux && !386 -// +build !linux,!386 +//go:build !386 +// +build !386 package pst
artifacts/definitions/Admin/Client/UpdateClientConfig.yaml+4 −0 modified@@ -25,6 +25,10 @@ parameters: default: Y description: Should the client rekey its client ID. +required_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - query: |
artifacts/definitions/Admin/Client/Upgrade/Debian.yaml+4 −0 modified@@ -24,6 +24,10 @@ parameters: description: | The name of the service to restart after the upgrade. +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - precondition: SELECT OS From info() where OS =~ 'linux'
artifacts/definitions/Admin/Client/Upgrade/RedHat.yaml+3 −0 modified@@ -24,6 +24,9 @@ parameters: description: | The name of the service to restart after the upgrade. +implied_permissions: + - EXECVE + sources: - precondition: SELECT OS From info() where OS =~ 'linux'
artifacts/definitions/Admin/Client/Upgrade/Windows.yaml+4 −0 modified@@ -22,6 +22,10 @@ parameters: overwhelm the server so we stagger the download over this many seconds. +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - precondition: SELECT OS From info() where OS = 'windows'
artifacts/definitions/Generic/Client/CleanupTemp.yaml+2 −0 modified@@ -13,6 +13,8 @@ parameters: - name: ReadllyDoIt type: bool +required_permissions: + - FILESYSTEM_WRITE sources: - query: |
artifacts/definitions/Generic/Client/DiskSpace.yaml+3 −0 modified@@ -6,6 +6,9 @@ description: | 1. On Linux and MacOS we call `df -h`. 2. On Windows we use WMI +implied_permissions: + - EXECVE + sources: - query: | LET NonWindows = SELECT * FROM foreach(row={
artifacts/definitions/Generic/Client/VQL.yaml+1 −1 modified@@ -3,7 +3,7 @@ description: | Run arbitrary VQL on the endpoint. required_permissions: - - EXECVE + - IMPERSONATION parameters: - name: Command
artifacts/definitions/Generic/Forensic/LocalHashes/Init.yaml+3 −0 modified@@ -8,6 +8,9 @@ parameters: description: Name of the local hash database default: hashdb.sqlite +implied_permissions: + - FILESYSTEM_WRITE + sources: - query: | LET SQL = "
artifacts/definitions/Generic/Utils/FetchBinary.yaml+4 −0 modified@@ -42,6 +42,10 @@ parameters: - name: Version description: The version of the tool to fetch +implied_permissions: + - SERVER_ADMIN + - FILESYSTEM_WRITE + sources: - query: | -- The following VQL is particularly ancient because it is
artifacts/definitions/Linux/Network/PacketCapture.yaml+6 −3 modified@@ -6,26 +6,29 @@ description: | The `Duration` parameter is used to define how long (in seconds) the capture should be. Specific interfaces can be defined using the `Interface` parameter, otherwise the artifact defaults to an interface assignment of `any`. A `BPF` (Berkeley Packet Filter) expression can also be supplied to filter the captured traffic as desired. - + Read more about BPF expressions here: https://biot.com/capstats/bpf.html required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + parameters: - name: Duration type: integer description: Duration (in seconds) of PCAP to be recorded. default: 10 - + - name: Interface type: string default: any - name: BPF type: string default: - + precondition: SELECT * FROM info() where OS = 'linux'
artifacts/definitions/Linux/RHEL/Packages.yaml+4 −0 modified@@ -1,6 +1,10 @@ name: Linux.RHEL.Packages description: | Parse packages installed from dnf or yum + +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS From info() where OS = 'linux'
artifacts/definitions/Linux/SuSE/Packages.yaml+5 −2 modified@@ -3,6 +3,9 @@ author: Hilko Bengen <bengen@hilluzination.de> description: | Parse list of installed packages from zypper output +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS From info() WHERE OS = 'linux' @@ -12,11 +15,11 @@ sources: FROM execve( length=1000000, argv=["zypper", "--xmlout", "search", "--installed-only", "--details", "--type=package"]) - + LET xml = parse_xml( file=str(str=zypper_output.Stdout), accessor="data") - + SELECT * FROM foreach( row=xml.stream.`search-result`.`solvable-list`.solvable,
artifacts/definitions/Linux/Sys/Services.yaml+6 −5 modified@@ -1,16 +1,17 @@ name: Linux.Sys.Services -description: Parse services from systemctl +description: Parse services from systemctl + +implied_permissions: + - EXECVE sources: - precondition: | SELECT OS From info() where OS = 'linux' queries: - | LET services = SELECT Stdout FROM execve(argv=['systemctl', 'list-units', '--type=service']) - + LET all_services = SELECT grok(grok="%{NOTSPACE:Unit}%{SPACE}%{NOTSPACE:Load}%{SPACE}%{NOTSPACE:Active}%{SPACE}%{NOTSPACE:Sub}%{SPACE}%{GREEDYDATA:Description}", data=Line) AS Parsed FROM parse_lines(accessor="data", filename=services.Stdout) - + SELECT * FROM foreach(row=all_services, column="Parsed") WHERE Unit =~ ".service" - - \ No newline at end of file
artifacts/definitions/Linux/Users/RootUsers.yaml+3 −0 modified@@ -7,6 +7,9 @@ author: George-Andrei Iosif (@iosifache) type: CLIENT +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS
artifacts/definitions/Linux/Utils/InstallDeb.yaml+1 −0 modified@@ -31,6 +31,7 @@ type: CLIENT required_permissions: - EXECVE + - FILESYSTEM_WRITE reference: - https://manpages.debian.org/bookworm/debconf-doc/debconf-devel.7.en.html#Type
artifacts/definitions/MacOS/Network/PacketCapture.yaml+6 −3 modified@@ -6,26 +6,29 @@ description: | The `Duration` parameter is used to define how long (in seconds) the capture should be. Specific interfaces can be defined using the `Interface` parameter, otherwise the artifact defaults to an interface assignment of `any`. A `BPF` (Berkeley Packet Filter) expression can also be supplied to filter the captured traffic as desired. - + Read more about BPF expressions here: https://biot.com/capstats/bpf.html required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + parameters: - name: Duration type: integer description: Duration (in seconds) of PCAP to be recorded. default: 10 - + - name: Interface type: string default: any - name: BPF type: string default: - + precondition: SELECT * FROM info() where OS = 'darwin'
artifacts/definitions/MacOS/System/Packages.yaml+9 −4 modified@@ -1,24 +1,29 @@ name: MacOS.System.Packages description: | Parse packages installed on Macs + parameters: - name: Length description: Size (in bytes) of output that will be returned type: int default: "100000000" + +implied_permissions: + - EXECVE + sources: - precondition: | SELECT OS From info() where OS = 'darwin' query: | - LET packages = SELECT parse_json(data=Stdout) AS Json + LET packages = SELECT parse_json(data=Stdout) AS Json FROM execve(argv=[ "system_profiler", "-json", "SPApplicationsDataType" ], length=Length) SELECT _name AS Name, - get(field="version") AS Version, - path AS Path, - lastModified AS LastModified, + get(field="version") AS Version, + path AS Path, + lastModified AS LastModified, obtained_from AS ObtainedFrom, get(field="signed_by") AS SignedBy, arch_kind AS _Architecture
artifacts/definitions/Windows/ActiveDirectory/BloodHound.yaml+3 −0 modified@@ -23,6 +23,9 @@ reference: required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + tools: - name: SharpHound url: https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe
artifacts/definitions/Windows/Applications/NirsoftBrowserViewer.yaml+4 −0 modified@@ -38,6 +38,10 @@ parameters: default: LOCAL description: Default timezone for parsing timestamps +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + sources: - precondition: SELECT OS From info() where OS = 'windows'
artifacts/definitions/Windows/Applications/SBECmd.yaml+4 −0 modified@@ -34,6 +34,10 @@ tools: precondition: SELECT OS From info() where OS = 'windows' +implied_permissions: + - EXECVE + - FILESYSTEM_WRITE + parameters: - name: userRegex default: .
artifacts/definitions/Windows/Forensics/BulkExtractor.yaml+3 −0 modified@@ -45,6 +45,9 @@ author: Matt Green - @mgreen27 required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + tools: - name: Bulk_Extractor_Binary url: https://github.com/Velocidex/Tools/raw/main/BulkExtractor/bulk_extractor.exe
artifacts/definitions/Windows/Memory/Acquisition.yaml+3 −0 modified@@ -20,6 +20,9 @@ description: | go-winpmem.exe expand image.compressed image.raw ``` +implied_permissions: + - FILESYSTEM_WRITE + precondition: | SELECT OS FROM info() WHERE OS = 'windows'
artifacts/definitions/Windows/Network/PacketCapture.yaml+4 −0 modified@@ -15,6 +15,10 @@ tools: - name: etl2pcapng url: https://github.com/microsoft/etl2pcapng/releases/download/v1.4.0/etl2pcapng.zip +implied_permissions: + - FILESYSTEM_WRITE + - EXECVE + parameters: - name: StartTrace type: bool
artifacts/definitions/Windows/Remediation/Sinkhole.yaml+3 −0 modified@@ -20,6 +20,9 @@ author: Matt Green - @mgreen27 required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + type: CLIENT parameters:
artifacts/definitions/Windows/Sys/Interfaces.yaml+3 −0 modified@@ -3,6 +3,9 @@ description: | Report information about the systems interfaces. This artifact simply parses the output from ipconfig /all. +implied_permissions: + - EXECVE + sources: - precondition: SELECT OS from info() where OS = "windows"
artifacts/definitions/Windows/Sysinternals/Autoruns.yaml+3 −0 modified@@ -15,6 +15,9 @@ tools: precondition: SELECT OS From info() where OS = 'windows' +implied_permissions: + - EXECVE + parameters: - name: All type: bool
artifacts/definitions/Windows/System/AuditPolicy.yaml+6 −3 modified@@ -1,24 +1,27 @@ name: Windows.System.AuditPolicy description: | - Artifact using auditpol to retrieve the logging settings + Artifact using auditpol to retrieve the logging settings defined in the Windows Audit Policy. - + Use this artifact to determine what Windows event logs are audited and if there are any discrepancies across the environment. type: CLIENT author: Zach Stanford - @svch0st +implied_permissions: + - EXECVE + sources: - precondition: SELECT OS From info() where OS = 'windows' query: | LET output = SELECT * FROM execve( argv=["auditpol.exe","/get","/category:*","/r"]) - + SELECT * FROM foreach( row=output, query={
artifacts/definitions/Windows/System/VBScript.yaml+16 −13 modified@@ -2,30 +2,33 @@ name: Windows.System.VBScript author: Matt Green - @mgreen27 description: | This artifact allows running VBScript through cscript.exe. - - This is a very powerful artifact since it allows for arbitrary command execution - on the endpoints as SYSTEM. Therefore this artifact requires elevated permissions - (specifically the EXECVE permission). Typically it is only available with the + + This is a very powerful artifact since it allows for arbitrary command execution + on the endpoints as SYSTEM. Therefore this artifact requires elevated permissions + (specifically the EXECVE permission). Typically it is only available with the administrator role. - - Note: Output is formatted to 1 row per line of Stdout. Ensure appropriately - formatted scripts. Pasting scripts direct from word or webpages may lead to - formatting issues when unicode characters are substituted. Copy script into + + Note: Output is formatted to 1 row per line of Stdout. Ensure appropriately + formatted scripts. Pasting scripts direct from word or webpages may lead to + formatting issues when unicode characters are substituted. Copy script into a notepad, save as ASCII then try again. - + required_permissions: - EXECVE +implied_permissions: + - FILESYSTEM_WRITE + precondition: SELECT OS From info() where OS = 'windows' parameters: - name: Script default: Wscript.Echo "Hello world!" - + sources: - query: | LET temp_script <= tempfile(extension='.vbs', data=str(str=Script)) - - SELECT Stdout - FROM execve(argv=['cscript.exe','//NoLogo','/E:vbs',temp_script], sep='\n') \ No newline at end of file + + SELECT Stdout + FROM execve(argv=['cscript.exe','//NoLogo','/E:vbs',temp_script], sep='\n')
artifacts/proto/artifact.pb.go+200 −169 modified@@ -515,6 +515,27 @@ type Artifact struct { Reference []string `protobuf:"bytes,5,rep,name=reference,proto3" json:"reference,omitempty"` References []string `protobuf:"bytes,23,rep,name=references,proto3" json:"references,omitempty"` RequiredPermissions []string `protobuf:"bytes,13,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"` + // A list of permissions implied by this artifact. This is used by + // the artifact writer to declare what additional permissions the + // artifact provides over the permissions provided by the user. + // + // On the client, artifacts do not run with ACL enforced, + // therefore they can do anything, including actions which the + // user launching the artifact does not have. For example, the + // user may have the investigator role which does not have + // EXECVE. However, when launching this artifact on the client, + // the artifact will be able to run actions requiring the EXEVE + // permission (because there is no ACL enforcement on the client). + // + // Therefore we say this artifact implies the user has EXECVE - + // this is safe if the aritfact takes steps to ensure the user + // does not have arbitrary control over what to execute (for + // example, if the artifact launches a tool with restricted + // command line args). + // + // This field is only used to ensure the static analysis engine + // that the implied permission is properly controlled. + ImpliedPermissions []string `protobuf:"bytes,28,rep,name=implied_permissions,json=impliedPermissions,proto3" json:"implied_permissions,omitempty"` // If this is specified, we run this artifact as the named user, // with that user's ACL token. This is similar to the Unix suid // mechanism or the Windows impersonation mechanism in that it @@ -640,6 +661,13 @@ func (x *Artifact) GetRequiredPermissions() []string { return nil } +func (x *Artifact) GetImpliedPermissions() []string { + if x != nil { + return x.ImpliedPermissions + } + return nil +} + func (x *Artifact) GetImpersonate() string { if x != nil { return x.Impersonate @@ -1427,7 +1455,7 @@ var file_artifact_proto_rawDesc = []byte{ 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x2e, 0x22, 0x94, 0x0f, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x78, 0x74, 0x2e, 0x22, 0xc5, 0x0f, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0xb1, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x9c, 0x01, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x95, 0x01, 0x12, 0x92, 0x01, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, @@ -1465,174 +1493,177 @@ var file_artifact_proto_rawDesc = []byte{ 0x65, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a, - 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12, - 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x13, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, - 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f, - 0x6c, 0x73, 0x12, 0x68, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, - 0x12, 0x3c, 0x41, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x65, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x69, 0x6e, - 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x0c, - 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, 0x0a, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x32, 0xe2, 0xfc, 0xe3, 0xc4, - 0x01, 0x2c, 0x12, 0x2a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x0a, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x54, - 0x12, 0x52, 0x54, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, - 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x45, - 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x2c, 0x20, 0x53, 0x45, - 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x49, 0x4e, 0x54, 0x45, - 0x52, 0x4e, 0x41, 0x4c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x5a, 0x0a, 0x07, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x42, 0x29, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x23, 0x12, 0x21, 0x57, 0x68, 0x65, 0x72, - 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x67, - 0x65, 0x74, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x07, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x42, 0x50, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4a, 0x12, - 0x48, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, - 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x27, 0x20, 0x65, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x63, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5d, 0x12, 0x5b, 0x56, 0x51, 0x4c, 0x20, - 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x77, - 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, - 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, - 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x73, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x6d, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, - 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, - 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x34, - 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x10, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, 0x72, - 0x61, 0x77, 0x20, 0x59, 0x41, 0x4d, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, 0x1a, - 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, - 0x69, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x75, - 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x64, 0x5f, 0x69, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x6c, 0x69, - 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, - 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x68, 0x65, 0x72, - 0x69, 0x74, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x7f, 0xda, 0xfc, 0xe3, 0xc4, 0x01, - 0x79, 0x0a, 0x77, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, 0x77, - 0x72, 0x61, 0x70, 0x73, 0x20, 0x61, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, - 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, - 0x7a, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x22, 0x3c, 0x0a, 0x13, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x17, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x1a, 0x54, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, 0x04, 0x0a, 0x04, 0x54, 0x6f, 0x6f, 0x6c, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2c, 0x0a, 0x12, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x67, - 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x12, - 0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f, 0x76, - 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, - 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x65, - 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x08, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, - 0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, - 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcb, - 0x02, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, - 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0c, - 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, 0x70, - 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x69, - 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, - 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, - 0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, - 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, - 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, - 0x61, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, - 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x42, 0x37, 0x5a, 0x35, - 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, - 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, + 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x1c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, + 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, + 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, + 0x6f, 0x6c, 0x73, 0x12, 0x68, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, + 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, + 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x32, 0xe2, 0xfc, 0xe3, + 0xc4, 0x01, 0x2c, 0x12, 0x2a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, + 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5a, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, + 0x54, 0x12, 0x52, 0x54, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x2c, 0x20, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x49, 0x4e, 0x54, + 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x5a, 0x0a, 0x07, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x42, 0x29, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x23, 0x12, 0x21, 0x57, 0x68, 0x65, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, + 0x67, 0x65, 0x74, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x07, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x6a, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x42, 0x50, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x4a, + 0x12, 0x48, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x27, 0x20, 0x65, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x63, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x5d, 0x12, 0x5b, 0x56, 0x51, 0x4c, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, + 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x6d, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x42, 0x44, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x3e, 0x12, 0x3c, 0x41, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, + 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, + 0x34, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x26, 0xe2, 0xfc, 0xe3, 0xc4, 0x01, 0x20, 0x12, 0x1e, 0x54, 0x68, 0x65, 0x20, + 0x72, 0x61, 0x77, 0x20, 0x59, 0x41, 0x4d, 0x4c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, + 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, + 0x65, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x68, 0x65, + 0x72, 0x69, 0x74, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x7f, 0xda, 0xfc, 0xe3, 0xc4, + 0x01, 0x79, 0x0a, 0x77, 0x41, 0x6e, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x20, + 0x77, 0x72, 0x61, 0x70, 0x73, 0x20, 0x61, 0x20, 0x56, 0x51, 0x4c, 0x20, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x61, 0x6c, + 0x79, 0x7a, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x2e, 0x22, 0x3c, 0x0a, 0x13, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x61, 0x73, 0x69, 0x63, 0x22, 0xb9, 0x01, 0x0a, 0x17, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x54, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, 0x04, 0x0a, 0x04, 0x54, 0x6f, 0x6f, 0x6c, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2c, 0x0a, + 0x12, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, + 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x08, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, + 0x74, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, + 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0xcb, 0x02, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, + 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, + 0x0c, 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, + 0x52, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, + 0x70, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, + 0x69, 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, + 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x52, 0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, + 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, + 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x61, 0x69, 0x74, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x57, 0x61, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, + 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, + 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x6f, 0x77, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x42, 0x37, 0x5a, + 0x35, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, + 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var (
artifacts/proto/artifact.proto+22 −0 modified@@ -150,6 +150,28 @@ message Artifact { description: "A list of required permissions to collect this artifact." }]; + // A list of permissions implied by this artifact. This is used by + // the artifact writer to declare what additional permissions the + // artifact provides over the permissions provided by the user. + // + // On the client, artifacts do not run with ACL enforced, + // therefore they can do anything, including actions which the + // user launching the artifact does not have. For example, the + // user may have the investigator role which does not have + // EXECVE. However, when launching this artifact on the client, + // the artifact will be able to run actions requiring the EXEVE + // permission (because there is no ACL enforcement on the client). + // + // Therefore we say this artifact implies the user has EXECVE - + // this is safe if the aritfact takes steps to ensure the user + // does not have arbitrary control over what to execute (for + // example, if the artifact launches a tool with restricted + // command line args). + // + // This field is only used to ensure the static analysis engine + // that the implied permission is properly controlled. + repeated string implied_permissions = 28; + // If this is specified, we run this artifact as the named user, // with that user's ACL token. This is similar to the Unix suid // mechanism or the Windows impersonation mechanism in that it
artifacts/testdata/server/testcases/verify.in.yaml+5 −0 added@@ -0,0 +1,5 @@ +Queries: + - SELECT count() AS Count , + verify(artifact=name) AS V + FROM artifact_definitions() + WHERE type=~'client' AND built_in AND V.Warnings
artifacts/testdata/server/testcases/verify.out.yaml+1 −0 added@@ -0,0 +1 @@ +SELECT count() AS Count , verify(artifact=name) AS V FROM artifact_definitions() WHERE type=~'client' AND built_in AND V.Warnings[] \ No newline at end of file
bin/verify.go+18 −12 modified@@ -47,26 +47,27 @@ func doVerify() error { logger := logging.GetLogger(config_obj, &logging.ToolComponent) // Report all errors and keep going as much as possible. - returned_errs := make(map[string]error) - artifacts := make(map[string]*artifacts_proto.Artifact) + states := make(map[string]*launcher.AnalysisState) repository, err := manager.GetGlobalRepository(config_obj) if err != nil { return err } + for _, artifact_path := range *verify_args { - returned_errs[artifact_path] = nil + state := launcher.NewAnalysisState(artifact_path) + states[artifact_path] = state fd, err := os.Open(artifact_path) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } data, err := ioutil.ReadAll(fd) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } @@ -76,24 +77,29 @@ func doVerify() error { AllowOverridingAlias: true, }) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } artifacts[artifact_path] = a } - for artifact_path, a := range artifacts { + for artifact_path, artifact := range artifacts { + state, _ := states[artifact_path] launcher.VerifyArtifact(ctx, config_obj, - artifact_path, a, returned_errs) + repository, artifact, state) } var ret error - for artifact_path, err := range returned_errs { - if err != nil { + for artifact_path, state := range states { + if len(state.Errors) == 0 { + logger.Info("Verified %v: <green>OK</>", artifact_path) + } + for _, err := range state.Errors { logger.Error("%v: <red>%v</>", artifact_path, err) ret = err - } else { - logger.Info("Verified %v: <green>OK</>", artifact_path) + } + for _, msg := range state.Warnings { + logger.Info("%v: %v", artifact_path, msg) } }
docs/references/vql.yaml+1 −1 modified@@ -8868,7 +8868,7 @@ 2. The `enrichment` field specifies a VQL lambda which will be used to build an enrichment object after a match is made. This - is used to additional infomation for the analyst to assess. + is used to additional information for the analyst to assess. 3. The `vql` modifier can be used to specify a VQL lambda that will be used in a detection clause. The lambda will receive the
go.mod+3 −3 modified@@ -74,7 +74,7 @@ require ( golang.org/x/mod v0.21.0 golang.org/x/net v0.38.0 golang.org/x/sys v0.32.0 - golang.org/x/text v0.24.0 + golang.org/x/text v0.25.0 golang.org/x/time v0.5.0 google.golang.org/api v0.169.0 google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect @@ -92,7 +92,7 @@ require ( www.velocidex.com/golang/go-prefetch v0.0.0-20240910051453-2385582c1c22 www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7 - www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048 + www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709 ) require ( @@ -281,7 +281,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect - golang.org/x/sync v0.13.0 // indirect + golang.org/x/sync v0.14.0 // indirect golang.org/x/term v0.30.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect kernel.org/pub/linux/libs/security/libcap/cap v1.2.71 // indirect
go.sum+6 −6 modified@@ -818,8 +818,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -877,8 +877,8 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= @@ -1007,7 +1007,7 @@ www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959 h1:qJlm0T61 www.velocidex.com/golang/oleparse v0.0.0-20250312121321-f7c2b4ec0959/go.mod h1:wjOPwI3Vy6TP0AhF6NjjXV/to93E5A1tjA04liHvf5E= www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7 h1:BMX/37sYwX+8JhHt+YNbPfbx7dXG1w1L1mXonNBtjt0= www.velocidex.com/golang/regparser v0.0.0-20250203141505-31e704a67ef7/go.mod h1:pxSECT5mWM3goJ4sxB4HCJNKnKqiAlpyT8XnvBwkLGU= -www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048 h1:EEtilwfOb8pfaZ2cbavThTZVXQ1lbPABVjXwaQHb3lM= -www.velocidex.com/golang/vfilter v0.0.0-20250506071806-b4ce88fa0048/go.mod h1:P50KPQr2LpWVAu7ilGH8CBLBASGtOJ2971yA9YhR8rY= +www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709 h1:FD1zc0go4SJW/FFkYV5LvYNs2nNJ9YHoLRpq+YXT9uQ= +www.velocidex.com/golang/vfilter v0.0.0-20250520023105-e30ee3b29709/go.mod h1:P50KPQr2LpWVAu7ilGH8CBLBASGtOJ2971yA9YhR8rY= www.velocidex.com/golang/vtypes v0.0.0-20240123105603-069d4a7f435c h1:rL/It+Ig+mvIhmy9vl5gg5b6CX2J12x0v2SXIT2RoWE= www.velocidex.com/golang/vtypes v0.0.0-20240123105603-069d4a7f435c/go.mod h1:tjaJNlBWbvH4cEMrEu678CFR2hrtcdyPINIpRxrOh4U=
gui/velociraptor/package.json+7 −2 modified@@ -10,8 +10,13 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", - "axios": ">=1.8.4", +<<<<<<< HEAD + "axios": ">=1.9.0", "ace-builds": "1.40.0", +======= + "axios": ">=1.8.4", + "ace-builds": "1.40.1", +>>>>>>> a977a6e22 (fix: upgrade ace-builds from 1.40.0 to 1.40.1) "axios-retry": "3.9.1", "bootstrap": "5.3.5", "classnames": "^2.5.1", @@ -49,7 +54,7 @@ "recharts": "^2.15.3", "sprintf-js": "1.1.3", "url-parse": "^1.5.10", - "webpack": "5.99.6" + "webpack": "5.99.7" }, "homepage": ".", "scripts": {
gui/velociraptor/package-lock.json+32 −30 modified@@ -15,10 +15,10 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "0.2.2", "@popperjs/core": "^2.11.8", - "ace-builds": "^1.40.0", - "axios": ">=1.8.4", + "ace-builds": "1.40.1", + "axios": "^1.9.0", "axios-retry": "3.9.1", - "bootstrap": "^5.3.5", + "bootstrap": "5.3.5", "classnames": "^2.5.1", "csv-parse": "4.16.3", "csv-stringify": "5.6.5", @@ -54,7 +54,7 @@ "recharts": "^2.15.3", "sprintf-js": "1.1.3", "url-parse": "^1.5.10", - "webpack": "^5.99.6" + "webpack": "^5.99.7" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -3736,9 +3736,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/ace-builds": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz", - "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.1.tgz", + "integrity": "sha512-32uwJNwmhqpnYtr6oq8RoO1D6F6tnxisv5f9w2XPX3vi4QruuHNikadHUiHvnxLAV1n5Azv4LFtpItQ5dD1eRw==", "license": "BSD-3-Clause" }, "node_modules/acorn": { @@ -3982,9 +3982,9 @@ } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -8581,9 +8581,9 @@ } }, "node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -9535,13 +9535,14 @@ } }, "node_modules/webpack": { - "version": "5.99.6", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.6.tgz", - "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==", + "version": "5.99.7", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz", + "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==", "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", @@ -9558,7 +9559,7 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", @@ -12201,9 +12202,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "ace-builds": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz", - "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA==" + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.1.tgz", + "integrity": "sha512-32uwJNwmhqpnYtr6oq8RoO1D6F6tnxisv5f9w2XPX3vi4QruuHNikadHUiHvnxLAV1n5Azv4LFtpItQ5dD1eRw==" }, "acorn": { "version": "8.14.0", @@ -12377,9 +12378,9 @@ "dev": true }, "axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -15734,9 +15735,9 @@ } }, "schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "requires": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -16415,12 +16416,13 @@ } }, "webpack": { - "version": "5.99.6", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.6.tgz", - "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==", + "version": "5.99.7", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz", + "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==", "requires": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", @@ -16437,7 +16439,7 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1",
services/launcher/verifier.go+122 −36 modified@@ -5,6 +5,7 @@ import ( "fmt" "strings" + api_proto "www.velocidex.com/golang/velociraptor/api/proto" artifacts_proto "www.velocidex.com/golang/velociraptor/artifacts/proto" config_proto "www.velocidex.com/golang/velociraptor/config/proto" "www.velocidex.com/golang/velociraptor/services" @@ -17,18 +18,102 @@ var ( api_description = &ApiDescription{} ) +// Contains the result of the static analysis. +type AnalysisState struct { + Artifact string + Permissions []string + Errors []error + Warnings []string +} + +func (self *AnalysisState) SetError(err error) { + self.Errors = append(self.Errors, err) +} + +func (self *AnalysisState) AnalyseCall( + callsite vfilter.CallSite, desc CallDesciptor) { + self.Permissions = utils.Sort(utils.DeduplicateStringSlice( + append(self.Permissions, desc.Permissions...))) +} + +func (self *AnalysisState) AnalyseArtifactRequiredPermissions( + artifact *artifacts_proto.Artifact) { + switch strings.ToUpper(artifact.Type) { + case "", "CLIENT": + default: + return + } + + // When a user runs an artifact on a client they implicitly have + // these permissions. + implied_permissions := []string{ + "FILESYSTEM_READ", "MACHINE_STATE", + + // Used by http_client on the client side. + "COLLECT_SERVER", + } + + // They also receive permissins required by the artifact because + // this will be enforced on the server. + implied_permissions = append(implied_permissions, + artifact.RequiredPermissions...) + + // The artifact writer can also declare which permission are + // safely controlled. + implied_permissions = append(implied_permissions, + artifact.ImpliedPermissions...) + + // Now go over all the permissions used by the artifact an warn + // about all permissions that are not required + for _, perm := range self.Permissions { + if !utils.InString(implied_permissions, perm) { + self.Warnings = append(self.Warnings, + fmt.Sprintf("<yellow>Suggestion</>: Add %v to artifact's required_permissions or implied_permissions fields", perm)) + } + } +} + +func NewAnalysisState(artifact string) *AnalysisState { + return &AnalysisState{ + Artifact: artifact, + } +} + type Required bool +type CallDesciptor struct { + ArgsRequired map[string]Required + Permissions []string +} + +func (self *CallDesciptor) SetPermissions(api *api_proto.Completion) { + if api.Metadata != nil { + perms, pres := api.Metadata["permissions"] + if pres { + self.Permissions = strings.Split(perms, ",") + } + } +} + +func NewCallDesciptor(api *api_proto.Completion) CallDesciptor { + res := &CallDesciptor{ + ArgsRequired: make(map[string]Required), + } + + res.SetPermissions(api) + return *res +} + type ApiDescription struct { - functions map[string]map[string]Required - plugins map[string]map[string]Required + functions map[string]CallDesciptor + plugins map[string]CallDesciptor } func (self *ApiDescription) init() error { // Initialize if needed if self.functions == nil || self.plugins == nil { - self.functions = make(map[string]map[string]Required) - self.plugins = make(map[string]map[string]Required) + self.functions = make(map[string]CallDesciptor) + self.plugins = make(map[string]CallDesciptor) apis, err := utils.LoadApiDescription() if err != nil { @@ -37,21 +122,24 @@ func (self *ApiDescription) init() error { for _, api := range apis { if api.Type == "Function" { - desc := make(map[string]Required) + desc := NewCallDesciptor(api) + // Ignore ** kwargs type of call. - desc["**"] = Required(false) + desc.ArgsRequired["**"] = Required(false) for _, arg := range api.Args { - desc[arg.Name] = Required(arg.Required) + desc.ArgsRequired[arg.Name] = Required(arg.Required) } if !api.FreeFormArgs { self.functions[api.Name] = desc } } if api.Type == "Plugin" { - desc := make(map[string]Required) - desc["**"] = Required(false) + desc := NewCallDesciptor(api) + + // Ignore ** kwargs type of call. + desc.ArgsRequired["**"] = Required(false) for _, arg := range api.Args { - desc[arg.Name] = Required(arg.Required) + desc.ArgsRequired[arg.Name] = Required(arg.Required) } if !api.FreeFormArgs { self.plugins[api.Name] = desc @@ -96,7 +184,8 @@ func (self *ApiDescription) verifyArtifact( func (self *ApiDescription) VerifyCallSite( ctx context.Context, config_obj *config_proto.Config, repository services.Repository, - callsite vfilter.CallSite) (res []error) { + callsite vfilter.CallSite, + state *AnalysisState) (res []error) { err := self.init() if err != nil { @@ -112,8 +201,10 @@ func (self *ApiDescription) VerifyCallSite( if callsite.Type == "plugin" { desc, pres := self.plugins[callsite.Name] if pres { + state.AnalyseCall(callsite, desc) + for _, arg := range callsite.Args { - _, pres := desc[arg] + _, pres := desc.ArgsRequired[arg] if !pres { res = append(res, fmt.Errorf( "Invalid arg %v for plugin %v()", @@ -122,7 +213,7 @@ func (self *ApiDescription) VerifyCallSite( } // Now check if any of the required args are missing - for arg, required := range desc { + for arg, required := range desc.ArgsRequired { if bool(required) && !utils.InString(callsite.Args, arg) { res = append(res, fmt.Errorf( "While calling plugin %v(), required arg %v is not provided", @@ -135,8 +226,10 @@ func (self *ApiDescription) VerifyCallSite( if callsite.Type == "function" { desc, pres := self.functions[callsite.Name] if pres { + state.AnalyseCall(callsite, desc) + for _, arg := range callsite.Args { - _, pres := desc[arg] + _, pres := desc.ArgsRequired[arg] if !pres { res = append(res, fmt.Errorf( "Invalid arg %v for function %v()", @@ -145,7 +238,7 @@ func (self *ApiDescription) VerifyCallSite( } // Now check if any of the required args are missing - for arg, required := range desc { + for arg, required := range desc.ArgsRequired { if bool(required) && !utils.InString(callsite.Args, arg) { res = append(res, fmt.Errorf( "While calling vql function %v(), required arg %v is not called", @@ -161,7 +254,8 @@ func (self *ApiDescription) VerifyCallSite( // Run additional validation on the VQL to ensure it is valid. func VerifyVQL(ctx context.Context, config_obj *config_proto.Config, - query string, repository services.Repository) (res []error) { + query string, repository services.Repository, + state *AnalysisState) (res []error) { scope := vql_subsystem.MakeScope() @@ -177,7 +271,7 @@ func VerifyVQL(ctx context.Context, config_obj *config_proto.Config, for _, cs := range visitor.CallSites { res = append(res, api_description.VerifyCallSite( - ctx, config_obj, repository, cs)...) + ctx, config_obj, repository, cs, state)...) } } @@ -186,24 +280,14 @@ func VerifyVQL(ctx context.Context, config_obj *config_proto.Config, func VerifyArtifact( ctx context.Context, config_obj *config_proto.Config, - artifact_path string, + repository services.Repository, artifact *artifacts_proto.Artifact, - returned_errs map[string]error) { - - manager, err := services.GetRepositoryManager(config_obj) - if err != nil { - return - } - - repository, err := manager.GetGlobalRepository(config_obj) - if err != nil { - return - } + state *AnalysisState) { if artifact.Precondition != "" { for _, err := range VerifyVQL(ctx, config_obj, - artifact.Precondition, repository) { - returned_errs[artifact_path] = err + artifact.Precondition, repository, state) { + state.SetError(err) } } @@ -214,21 +298,23 @@ func VerifyArtifact( err := GetQueryDependencies(ctx, config_obj, repository, s.Query, 0, dependency) if err != nil { - returned_errs[artifact_path] = err + state.SetError(err) continue } // Now check for broken callsites for _, err := range VerifyVQL(ctx, config_obj, - s.Query, repository) { - returned_errs[artifact_path] = err + s.Query, repository, state) { + state.SetError(err) } } if s.Precondition != "" { for _, err := range VerifyVQL(ctx, config_obj, - s.Precondition, repository) { - returned_errs[artifact_path] = err + s.Precondition, repository, state) { + state.SetError(err) } } } + + state.AnalyseArtifactRequiredPermissions(artifact) }
services/launcher/verifier_test.go+2 −1 modified@@ -43,8 +43,9 @@ func (self *LauncherTestSuite) TestVerifyVQL() { assert.NoError(self.T(), err) for _, tc := range verifier_test_cases { + state := launcher.NewAnalysisState("") errs := launcher.VerifyVQL(self.Ctx, - self.ConfigObj, tc.query, repository) + self.ConfigObj, tc.query, repository, state) if len(errs) > 0 { if tc.error_regex == "" { self.T().Fatalf("%v: Expected no error but got %v",
services/repository/plugin_test.go+8 −59 modified@@ -70,14 +70,13 @@ func (self *PluginTestSuite) TestArtifactsSyntax() { assert.NoError(self.T(), err) new_repository := manager.NewRepository() + new_repository.SetParent(repository, ConfigObj) names, err := repository.List(self.Ctx, ConfigObj) assert.NoError(self.T(), err) - // Additinal verifications - returned_errs := make(map[string]error) - for _, artifact_name := range names { + state := launcher.NewAnalysisState(artifact_name) artifact, pres := repository.Get(self.Ctx, ConfigObj, artifact_name) assert.True(self.T(), pres) @@ -87,15 +86,14 @@ func (self *PluginTestSuite) TestArtifactsSyntax() { assert.NoError(self.T(), err, "Error compiling "+artifact_name) launcher.VerifyArtifact( - self.Ctx, self.ConfigObj, artifact_name, artifact, returned_errs) - } - } + self.Ctx, self.ConfigObj, new_repository, artifact, state) - for artifact_name, err := range returned_errs { - fmt.Printf("Error with %v: %v\n", artifact_name, err) + for _, err := range state.Errors { + fmt.Printf("Error with %v: %v\n", artifact_name, err) + } + assert.True(self.T(), len(state.Errors) == 0) + } } - - assert.True(self.T(), len(returned_errs) == 0) } var ( @@ -347,55 +345,6 @@ func (self *PluginTestSuite) TestClientPluginMultipleSourcesAndPrecondtionsEvent } -var ( - memory_leak_test = ` -name: ArtifactWithMemoryLeak -sources: -- query: | - LET X <= "Hello World" * 1000000 - - SELECT X FROM scope() -` -) - -func (self *PluginTestSuite) TestPluginMemoryLeak() { - repository := self.LoadArtifacts(memory_leak_test) - builder := services.ScopeBuilder{ - Config: self.ConfigObj, - ACLManager: acl_managers.NullACLManager{}, - Repository: repository, - Logger: logging.NewPlainLogger( - self.ConfigObj, &logging.FrontendComponent), - Env: ordereddict.NewDict(), - } - - manager, _ := services.GetRepositoryManager(self.ConfigObj) - scope := manager.BuildScope(builder) - defer scope.Close() - - queries := []string{ - `SELECT * FROM foreach( - row={ - SELECT * FROM range(end=10000) - }, query={ - SELECT * FROM Artifact.ArtifactWithMemoryLeak() - WHERE FALSE - })`, - } - - results := ordereddict.NewDict() - for _, query := range queries { - rows := []vfilter.Row{} - vql, err := vfilter.Parse(query) - assert.NoError(self.T(), err) - - for row := range vql.Eval(self.Ctx, scope) { - rows = append(rows, row) - } - results.Set(query, rows) - } -} - func TestArtifactPlugin(t *testing.T) { suite.Run(t, &PluginTestSuite{}) }
services/sanity/lockdown.go+9 −1 modified@@ -17,7 +17,12 @@ func (self SanityChecks) CheckForLockdown( } lockdown_token := &acl_proto.ApiClientACL{ - ArtifactWriter: true, + ArtifactWriter: true, + + // Labeling clients can move them between label groups which + // may cause new artifacts to be collected automatically + // (e.g. Quarantine). + LabelClients: true, ServerArtifactWriter: true, CollectClient: true, CollectServer: true, @@ -28,6 +33,9 @@ func (self SanityChecks) CheckForLockdown( FilesystemRead: true, MachineState: true, CollectBasic: true, + + Impersonation: true, + OrgAdmin: true, } if config_obj.Defaults != nil &&
vql/golang/verify.go+84 −0 added@@ -0,0 +1,84 @@ +package golang + +import ( + "context" + + "github.com/Velocidex/ordereddict" + "www.velocidex.com/golang/velociraptor/services" + "www.velocidex.com/golang/velociraptor/services/launcher" + vql_subsystem "www.velocidex.com/golang/velociraptor/vql" + "www.velocidex.com/golang/vfilter" + "www.velocidex.com/golang/vfilter/arg_parser" +) + +type VerifyFunctionArgs struct { + Artifact string `vfilter:"required,field=artifact,doc=The artifact to verify. This can be an artifact source in yaml or json or the name of an artifact"` +} + +func init() { + vql_subsystem.RegisterFunction( + vfilter.GenericFunction{ + FunctionName: "verify", + Doc: `verify an artifact + +This function will verify the artifact and flag any potential errors or warnings. +`, + Metadata: vql_subsystem.VQLMetadata().Build(), + ArgType: &VerifyFunctionArgs{}, + Function: func( + ctx context.Context, + scope vfilter.Scope, + args *ordereddict.Dict) vfilter.Any { + + arg := &VerifyFunctionArgs{} + err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg) + if err != nil { + scope.Log("verify: %v", err) + return vfilter.Null{} + } + + config_obj, ok := vql_subsystem.GetServerConfig(scope) + if !ok { + scope.Log("verify: Must run on the server") + return vfilter.Null{} + } + + manager, err := services.GetRepositoryManager(config_obj) + if err != nil { + return err + } + + repository, err := manager.GetGlobalRepository(config_obj) + if err != nil { + return err + } + + state := launcher.NewAnalysisState(arg.Artifact) + + artifact, pres := repository.Get(ctx, config_obj, arg.Artifact) + if !pres { + local_repository := manager.NewRepository() + local_repository.SetParent(repository, config_obj) + + artifact, err = local_repository.LoadYaml(arg.Artifact, + services.ArtifactOptions{ + ValidateArtifact: true, + ArtifactIsBuiltIn: true, + AllowOverridingAlias: true, + }) + if err != nil { + state.SetError(err) + return state + } + + repository = local_repository + } + + // Verify the artifact + launcher.VerifyArtifact( + ctx, config_obj, repository, artifact, state) + + return state + }, + }) +}
vql/parsers/pst_parser.go+2 −2 modified@@ -1,5 +1,5 @@ -//go:build !linux && !386 -// +build !linux,!386 +//go:build !386 +// +build !386 package parsers
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-gpfc-mph4-qm24ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-6264ghsaADVISORY
- blog.talosintelligence.com/velociraptor-leveraged-in-ransomware-attacksghsaWEB
- docs.velociraptor.app/announcements/advisories/cve-2025-6264ghsaWEB
- github.com/Velocidex/velociraptor/commit/21e7fd7138ddaa798cad35fd929864f6bb0c4e9cghsaWEB
- news.sophos.com/en-us/2025/08/26/velociraptor-incident-response-tool-abused-for-remote-accessghsaWEB
- docs.velociraptor.app/announcements/advisories/cve-2025-6264/mitre
News mentions
0No linked articles in our index yet.