forked from Velocidex/velociraptor-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added artifact for parsing FreeBSD utx files (Velocidex#903)
Hi, I wrote an artifact to parse the utx file under FreeBSD. The file is similar to the wtmp file under Linux. It records logins, logouts, boots, shutdowns and system time changes. I appended the results from running the artifact on a test system (freebsd 14.1-RELEASE-p3 amd64) [example_results.json](https://github.com/user-attachments/files/16818996/example_results.json) Im not sure, if this artifact is better of in the Artifact Exchange or shipped by default with Velociraptor. For now, I offer it here. If there is potential to improve the VQL, please comment so :) Kind Regards
- Loading branch information
1 parent
add1203
commit 3f872fd
Showing
1 changed file
with
76 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
name: FreeBSD.Sys.Utx | ||
author: Herbert Bärschneider | ||
description: | | ||
Parse the utx file of the system (similar to wtmp on Linux). This covers user sessions, boots, shutdowns and system time changes. | ||
Because FreeBSD discards fields for the entries of the utx file based on type (see `man getutxent`), no direct parsing of the file using "vtypes" is done (too complicated for me to define a structure for parsing), but rather native tools are used for accessing the data. | ||
Using a value of "time" with the "userRegex" Parameter will give you all entries related to boots, shutdowns and system time changes. | ||
Beware: logout times are given in localtime! Furthermore, that column is not automatically parsed into timestamp values, because the tool output is not consistently a recognizable datetime. | ||
type: CLIENT | ||
|
||
parameters: | ||
- name: utxGlobs | ||
default: /var/log/utx.log* | ||
description: | | ||
glob for covering the files that should be parsed; default covers the usual location of the utx file on FreeBSD | ||
- name: userRegex | ||
type: regex | ||
default: "." | ||
description: | | ||
Regex for filtering the users, showing those you are interested in | ||
- name: DateAfter | ||
type: timestamp | ||
description: | | ||
timestamp used for filtering the login time | ||
- name: DateBefore | ||
type: timestamp | ||
description: | | ||
timestamp used for filtering the login time | ||
sources: | ||
- precondition: | ||
SELECT OS From info() where OS = 'freebsd' | ||
query: | | ||
-- timestamps given by the system command "last" are in local time, so we tell Velociraptor to handle them accordingly when converting with the VQL function "timestamp()" | ||
LET PARSE_TZ <= "local" | ||
-- time test function (taken from Windows.NTFS.MFT) | ||
LET time_test(stamp) = | ||
if(condition= DateBefore AND DateAfter, | ||
then= stamp < DateBefore AND stamp > DateAfter, | ||
else= | ||
if(condition=DateBefore, | ||
then= stamp < DateBefore, | ||
else= | ||
if(condition= DateAfter, | ||
then= stamp > DateAfter, | ||
else= True | ||
))) | ||
-- expand the glob and get all files that are matched by it | ||
LET Files = SELECT OSPath FROM glob(globs=split(string=utxGlobs, sep=",")) | ||
-- for each targeted file, parse the data out of it using system built-in command | ||
LET UtxParsing = SELECT * FROM foreach(row=Files, | ||
query={ | ||
-- TODO: try the command while setting env variable "TZ" to UTC and check, if the timestamps are changed accordingly | ||
SELECT * | ||
FROM execve(argv=["last", "-wy", "--libxo=json", "-f", OSPath]) | ||
WHERE log(message="stderr: " + Stderr) | ||
}) | ||
-- parse the output from each file as json | ||
LET UtxContent = SELECT parse_json(data=Stdout) as Content FROM UtxParsing | ||
-- pull out the interesting information from the nested json content | ||
LET s = scope() -- a little helper to suppress "symbol not found error" for elements of the content that are sometimes missing | ||
LET FormatedContent = SELECT * FROM foreach(row=UtxContent, | ||
query={ | ||
SELECT user, timestamp(string=`login-time`) AS login_time, s.`logout-time` AS logout_time, s.`session-length` AS session_length, s.tty AS tty, s.`from` AS remote, Content.`last-information`.utxdb AS utx_log FROM foreach(row=Content.`last-information`.last) | ||
}) | ||
SELECT * FROM FormatedContent WHERE | ||
user =~ userRegex | ||
AND time_test(stamp=login_time) |