Skip to content

Commit

Permalink
added artifact for parsing FreeBSD utx files (Velocidex#903)
Browse files Browse the repository at this point in the history
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
Herbert-Karl authored Sep 8, 2024
1 parent add1203 commit 3f872fd
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions content/exchange/artifacts/FreeBSD.Sys.Utx.yaml
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)

0 comments on commit 3f872fd

Please sign in to comment.