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

check_eventlog generates and parses TimeWritten filter/output not correct in version 0.27. #157

Open
Ysincit opened this issue Sep 19, 2024 · 0 comments

Comments

@Ysincit
Copy link

Ysincit commented Sep 19, 2024

Hi,
the time convert in
pkg/eventlog/eventlog_windows.go
is not as expected.
Go time.Time.Format does not support the WMI query time format, where the time zone offsets are expressed as minutes [+-]mmm.
time.Time.Format always expresses the time zone offsets as [+-]hhmm (or [+-]hhm if you only give -070 instead of -0700), so instead of '+180' minutes time.Time.Format sets '+030', that is also a integer, and the WMI query sees no syntax error, but the time is in fact not the expected time.
I tested the following change that seems to work (with help of ChatGPT):

<       WMIDateFormat = "20060102150405.000000-070"
---
>       WMIDateFormat = "20060102150405.000000"

>         // Format the time without the timezone offset
>         formattedTime := newerThan.Format(WMIDateFormat)
>         // Get the timezone offset in seconds and convert it to minutes
>         _, offsetSeconds := newerThan.Zone()
>         offsetMinutes := offsetSeconds / 60
>
>         // Determine the sign of the offset
>         offsetSign := "+"
>         if offsetMinutes < 0 {
>                offsetSign = "-"
>                offsetMinutes = -offsetMinutes // Make offsetMinutes positive for formatting
>         }
>
>         // Format the offset to ensure it has three digits with leading zeros
>         offsetFormatted := fmt.Sprintf("%s%03d", offsetSign, offsetMinutes)
>
>         // Combine the formatted time with the formatted offset
>         wmiFormattedTime := formattedTime + offsetFormatted

<       `, file, newerThan.Format(WMIDateFormat))
---
>       `, file, wmiFormattedTime)


The interpretation of the received TimeWritten is also not correct, and needs a new parser function:
import (
...
"strconv"
...
)

> // ParseWMIDateTime parses a WMI datetime string into a time.Time object.
> // If parsing fails, it returns the current time.
> func ParseWMIDateTime(wmiDateTime string) time.Time {
>     // Check if the string has at least 22 characters to avoid slicing errors
>     if len(wmiDateTime) < 22 {
>         // Return current time if the string is too short
>         return time.Now()
>     }
>
>     // Extract the date and time components
>     yearStr := wmiDateTime[0:4]
>     monthStr := wmiDateTime[4:6]
>     dayStr := wmiDateTime[6:8]
>     hourStr := wmiDateTime[8:10]
>     minuteStr := wmiDateTime[10:12]
>     secondStr := wmiDateTime[12:14]
>     microsecStr := wmiDateTime[15:21] // Skipping the dot at position 14
>
>     // Extract the time zone offset sign and value
>     offsetSign := wmiDateTime[21:22]
>     offsetStr := wmiDateTime[22:]
>
>     // Parse date and time components
>     year, err := strconv.Atoi(yearStr)
>     if err != nil {
>         return time.Now()
>     }
>     month, err := strconv.Atoi(monthStr)
>     if err != nil || month < 1 || month > 12 {
>         return time.Now()
>     }
>     day, err := strconv.Atoi(dayStr)
>     if err != nil || day < 1 || day > 31 {
>         return time.Now()
>     }
>     hour, err := strconv.Atoi(hourStr)
>     if err != nil || hour < 0 || hour > 23 {
>         return time.Now()
>     }
>     minute, err := strconv.Atoi(minuteStr)
>     if err != nil || minute < 0 || minute > 59 {
>         return time.Now()
>     }
>     second, err := strconv.Atoi(secondStr)
>     if err != nil || second < 0 || second > 59 {
>         return time.Now()
>     }
>     microsec, err := strconv.Atoi(microsecStr)
>     if err != nil {
>         return time.Now()
>     }
>
>     // Parse time zone offset
>     offsetMinutes, err := strconv.Atoi(offsetStr)
>     if err != nil {
>         return time.Now()
>     }
>
>     // Apply the sign to the offset
>     if offsetSign == "-" {
>         offsetMinutes = -offsetMinutes
>     } else if offsetSign != "+" {
>         // Invalid sign, return current time
>         return time.Now()
>     }
>
>     // Convert offset from minutes to seconds
>     offsetSeconds := offsetMinutes * 60
>
>     // Create a fixed time zone based on the offset
>     loc := time.FixedZone("WMI", offsetSeconds)
>
>     // Construct the time.Time object
>     t := time.Date(year, time.Month(month), day, hour, minute, second, microsec*1000, loc)
>
>     return t
> }
>

<                       timeWritten, _ := time.Parse(eventlog.WMIDateFormat, event.TimeWritten)
---
>                       timeWritten := ParseWMIDateTime(event.TimeWritten)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant