Compare commits

...

2 commits

Author SHA1 Message Date
Tim Wojtulewicz
ca3da1c0a8 Remove SMB_time and SMB_date record types 2025-09-27 03:43:05 +00:00
Tim Wojtulewicz
cf6945ef71 SMB: Init lanman time and set TZ correctly before calling mktime
This makes a change to the record for smb1-negotiate-response as well.
Times and dates are two 2-byte sections, not three. Switch the parsing
to just use two uint16s, and pass those into the lanman time conversion
function.
2025-09-27 03:43:05 +00:00
7 changed files with 56 additions and 25 deletions

View file

@ -1,6 +1,6 @@
%header{
double filetime2zeektime(uint64_t ts);
double time_from_lanman(SMB_time* t, SMB_date* d, uint16_t tz);
double time_from_lanman(uint32_t smb_time, uint32_t smb_date, uint16_t tz);
zeek::RecordValPtr SMB_BuildMACTimes(uint64_t modify, uint64_t access,
uint64_t create, uint64_t change);
@ -14,17 +14,30 @@ double filetime2zeektime(uint64_t ts)
return (static_cast<double>(ts) / 10000000.0) - 11644473600.0;
}
double time_from_lanman(SMB_time* t, SMB_date* d, uint16_t tz)
double time_from_lanman(uint32_t smb_time, uint32_t smb_date, uint16_t tz)
{
tm lTime;
lTime.tm_sec = ${t.two_seconds} * 2;
lTime.tm_min = ${t.minutes};
lTime.tm_hour = ${t.hours};
lTime.tm_mday = ${d.day};
lTime.tm_mon = ${d.month};
lTime.tm_year = 1980 + ${d.year};
tm lTime{0};
// Lanman uses this format for time/date:
// https://learn.microsoft.com/en-us/cpp/c-runtime-library/32-bit-windows-time-date-formats
// Seconds is in 2-second increments in the data.
lTime.tm_sec = (smb_time & 0x1f) * 2;
lTime.tm_min = (smb_time >> 5) & 0x3f;
lTime.tm_hour = (smb_time >> 11) & 0x1f;
lTime.tm_mday = smb_date & 0x1f;
// tm_mon is zero-indexed, so adjust for that.
lTime.tm_mon = ((smb_date >> 5) & 0x0f) - 1;
// The year in the data is the number of years from 1980, while tm_year is the
// number of years since 1900.
lTime.tm_year = ((smb_date >> 9) & 0x7f) + 80;
lTime.tm_isdst = -1;
return mktime(&lTime) + tz;
// The timezone passed in the data is the number of minutes from UTC, while
// tm_gmtoff is the number of seconds east of UTC. Adjust for that.
lTime.tm_gmtoff = static_cast<long>(tz) * 60;
return timegm(&lTime);
}
zeek::RecordValPtr SMB_BuildMACTimes(uint64_t modify, uint64_t access,
@ -45,15 +58,3 @@ zeek::RecordValPtr SMB_BuildMACTimes(uint64_t modify, uint64_t access,
type SMB_timestamp32 = uint32;
type SMB_timestamp = uint64;
type SMB_time = record {
two_seconds : uint16;
minutes : uint16;
hours : uint16;
} &byteorder = littleendian;
type SMB_date = record {
day : uint16;
month : uint16;
year : uint16;
} &byteorder = littleendian;

View file

@ -181,8 +181,8 @@ type SMB1_negotiate_lanman_response(header: SMB_Header) = record {
max_number_vcs : uint16;
raw_mode : uint16; # expanded in &let
session_key : uint32;
server_time : SMB_time;
server_date : SMB_date;
server_time : uint16;
server_date : uint16;
server_tz : uint16;
encryption_key_length : uint16;
reserved : uint16; # must be zero

View file

@ -31,7 +31,7 @@ type SMB1_query_information_request(header: SMB_Header) = record {
type SMB1_query_information_response(header: SMB_Header) = record {
word_count : uint8;
file_attribs : uint16;
last_write_time : SMB_time;
last_write_time : uint32;
file_size : uint32;
reserved : uint16[5];
byte_count : uint16;

View file

@ -0,0 +1,8 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
smb1_negotiate_request
[command=114, status=0, flags=24, flags2=51283, tid=0, pid=4660, uid=0, mid=1]
[PC NETWORK PROGRAM 1.0, LANMAN1.0, LM1.2X002, LANMAN2.1]
smb1_negotiate_response
[command=114, status=0, flags=152, flags2=51283, tid=0, pid=4660, uid=0, mid=1]
[core=<uninitialized>, lanman=[word_count=13, dialect_index=3, security_mode=[user_level=T, challenge_response=T, signatures_enabled=<uninitialized>, signatures_required=<uninitialized>], max_buffer_size=4356, max_mpx_count=32, max_number_vcs=1, raw_mode=[read_raw=F, write_raw=F], session_key=0, server_time=1758862898.0, encryption_key=\x11"3DUfw\x88, primary_domain=\xe4\xbd\x97\xe4\xad\x92\xe5\x89\x87\xe5\x95\x8fP], ntlm=<uninitialized>]
Parsed Response Server Time: 2025-09-26-05:01:38T

View file

@ -56,3 +56,6 @@ Trace Index/Sources:
- smb_v2_only_non_zero_reserved1.pcap
Provided by @predator89090 on #4730
https://github.com/zeek/zeek/issues/4730
- smb/cifs_negotiate_lanman.pcap
Generated with scapy/chatgpt by @Mohan-Dhawan
https://github.com/zeek/zeek/issues/4545

Binary file not shown.

View file

@ -0,0 +1,19 @@
# @TEST-DOC: Tests parsing of SMB1 Negotiate Request/Response LanMan messages. Primarily exists to test parsing of the timetstamps.
#
# @TEST-EXEC: zeek -r ${TRACES}/smb/cifs_negotiate_lanman.pcap %INPUT > out
# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff out
event smb1_negotiate_request(c: connection, hdr: SMB1::Header, dialects: string_vec)
{
print "smb1_negotiate_request";
print hdr;
print dialects;
}
event smb1_negotiate_response(c: connection, hdr: SMB1::Header, response: SMB1::NegotiateResponse)
{
print "smb1_negotiate_response";
print hdr;
print response;
print fmt("Parsed Response Server Time: %DT", response$lanman$server_time);
}