Lua метка времени извлечения Wireshark извлекает в формате автоматизации OLE - PullRequest
0 голосов
/ 12 февраля 2020

ref: Дата автоматизации OLE в lua

Я пишу простой анализатор UDP в LUA для декодирования пакетов, которые содержат метку времени, которая была закодирована как автоматизация OLE свидание. Кодирование приводит к 8-байтовому шаблону данных:

C2 F5 4F 12 FD 6B E5 40     

, который декодируется как 43871.90848539352 = '2/10/2020 9:48:13 PM'. В C#. NET это происходит с помощью метода DateTime.ToOADate () (который работает нормально).

Вот мой упрощенный диссектор, который «декодирует» 8-байтовое сообщение, состоящее только из отметка времени:

local logger_proto = Proto("logger", "LOGGER")
local logger_hdr={
    atime = ProtoField.absolute_time("test.atime","test atime",base.UTC),
    rtime = ProtoField.relative_time("test.rtime","test rtime",base.UTC),
}
logger_proto.fields=logger_hdr

function logger_proto.init() end

function logger_proto.dissector(tvbuf, pktinfo, root)
    root:add(logger_hdr.atime,tvbuf:range(0,8))
    root:add(logger_hdr.atime,tvbuf:range(8,8))
end

В тестовом пакете я дважды отправляю отметку времени, второй раз с байтами в обратном порядке для проверки на наличие порядковых номеров (подход «схватившись за str aws»). Данные пакета:

C2 F5 4F 12 FD 6B E5 40 40 E5 6B FD 12 4F F5 C2 

две найденные метки времени

Aug 25, 2073 03:14:26.-4360608 UTC
Jul  2, 2004 14:06:53.307230146 UTC

«правильная» метка времени должна быть

Feb 10, 2020 21:48:13 UTC

Похоже на ProtoField.absolute_time с base.UT C не совсем то, что я ищу. Итак, мои вопросы

  1. Есть ли опция ProtoField для правильного извлечения этой метки времени в формате, который исключает дробные секунды?
  2. Если нет, как бы я извлек дату / время в байтовом режиме и сделать расчеты для форматирования правильной даты вручную?

1 Ответ

1 голос
/ 14 февраля 2020

Мне пришлось немного узнать о датах OLE, но я нашел соответствующую информацию в DateTime.ToOADate Method . Я также использовал информацию из даты OLE Automation в вопросе lua, а также из Преобразование отметки времени США в absolute_time , чтобы найти решение возможных для вы. Я сомневаюсь, что это оптимальный вариант, но кажется работать на основе предоставленных данных. Надеюсь, это сработает для вас, но если нет, то должно приблизить вас к решению.

Долгосрочное решение будет, если Wireshark сможет предоставить native поддержку для дат OLE, и для этого чтобы это произошло, я бы порекомендовал подать усовершенствование Wireshark отчет об ошибке , запрашивающий именно такую ​​вещь.

A возможное решение (с некоторыми дополнительными вещами для иллюстративных целей):

local p_logger = Proto("logger", "LOGGER")
local logger_hdr = {
    -- Only the oletime_abs field is useful; the rest just help illustrate things
    -- and helped me during debugging.  Remove/rename as you see fit.

    oletime = ProtoField.double("logger.oletime", "OLE time"),

    -- Note: .int64 doesn't work so just using .int32
    oletime_days = ProtoField.int32("logger.oletime.days", "Days"),
    oletime_partial = ProtoField.double("logger.oletime.partial", "Partial"),
    oletime_abs = ProtoField.absolute_time("logger.oleabstime", "OLE Abs time", base.UTC)
}
p_logger.fields = logger_hdr

function p_logger.dissector(tvbuf, pinfo, tree)
    local logger_tree = tree:add(p_logger, tvbuf(0,-1))
    local OLE_DIFF_TO_UNIX = 25569
    local SECS_PER_DAY = 86400
    local oletime = tvbuf:range(0, 8):le_float() - OLE_DIFF_TO_UNIX
    local oletime_days = math.floor(oletime)
    local oletime_partial = (oletime - oletime_days) * SECS_PER_DAY
    local secs = oletime_days * SECS_PER_DAY + math.floor(oletime_partial)
    local nstime = NSTime.new(secs, 0)

    pinfo.cols.protocol:set("LOGGER")
    logger_tree:add(logger_hdr.oletime, tvbuf:range(0, 8), oletime)
    logger_tree:add(logger_hdr.oletime_days, tvbuf:range(0, 8), oletime_days)
    logger_tree:add(logger_hdr.oletime_partial, tvbuf:range(0, 8), oletime_partial)
    logger_tree:add(logger_hdr.oletime_abs, tvbuf:range(0, 8), nstime)
end

-- Register dissector (this particular registration is just for my testing)
local udp_table = DissectorTable.get("udp.port")
udp_table:add(33333, p_logger)

Я уверен, что это можно исправить / оптимизировать, но я оставляю это в качестве упражнения для читателя. Протестировано со следующим ручным пакетом:

0000   00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00   ..............E.
0010   00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00   .7..@.@......e..
0020   02 66 82 35 82 35 00 23 e8 54 c2 f5 4f 12 fd 6b   .f.5.5.#.T..O..k
0030   e5 40 40 e5 6b fd 12 4f f5 c2 00 00 00 00 00 00   .@@.k..O........
0040   00 00 00 00 00                                    .....

... и вы получите следующий декодер "Logger" OLE date:

LOGGER
    OLE time: 18302.9084853935
    Days: 18302
    Partial: 78493.1380001362
    OLE Abs time: Feb 10, 2020 21:48:13.000000000 UTC

Вы можете использовать text2pcap, чтобы преобразовать его в файл pcap для тестирования. Например: text2pcap -a logger.txt logger.pcap ... где logger.txt - текстовый файл, содержащий необработанные байты пакета, вставленные выше.

...