Zeek Scripting "Поле ошибки отсутствует в значении" - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь написать скрипт Zeek, чтобы разделить трафик dns c на два файла журнала (запрос и ответ). Ошибка «Поле отсутствует значение» для кода $TTL=c$dns$TTLs в событии dns_query_reply. Я не понимаю причину этой ошибки, поскольку файл dns.log правильно содержит значение.

Код выглядит следующим образом:

 module DnsFeatureExtractor;

export{

    redef enum Log::ID += {QueryDNS};
    redef enum Log::ID += {ReplyDNS};


    type InfoQuery: record{
        uid:                string              &log;
        id:                 conn_id             &log;
        domain:             string              &log    &optional;
        query_type:         string              &log    &optional;
        timestamp:          time                &log;
    };


    type InfoReply: record{
        uid:                string              &log;
        id:                 conn_id             &log;
        response_code:      count               &log    &optional;
        TTL:                vector of interval  &log    &optional;
        resolved_IP:        vector of string    &log    &optional;
        timestamp:          time                &log;
    };  
}

event zeek_init(){

    Log::create_stream(QueryDNS, [$columns=InfoQuery, $path="QueryDNS"]);
    Log::create_stream(ReplyDNS, [$columns=InfoReply, $path="ReplyDNS"]);
}

event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count){

    local name_qtype = DNS::query_types[qtype];

    local rec: DnsFeatureExtractor::InfoQuery = [$uid=c$uid, $id=c$id, $domain=query, $query_type=name_qtype, $timestamp=c$start_time];
    Log::write(DnsFeatureExtractor::QueryDNS, rec);
}

event dns_query_reply(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count){

    local rec_r: DnsFeatureExtractor::InfoReply = [$uid=c$uid, $id=c$id, $response_code=msg$rcode, $TTL=c$dns$TTLs, $resolved_IP=c$dns$answers, $timestamp=c$start_time];
    Log::write(DnsFeatureExtractor::ReplyDNS, rec_r);
}

1 Ответ

0 голосов
/ 01 мая 2020

Это тонко: вы видите проблему заказа. Обработчик события dns_query_reply вызывается до события, которое фактически заполняет TTL (например, dns_A_reply).

Указанные поля c$dns заполняются в хуке DNS::do_reply , поэтому вам лучше всего добавить в ловушку. Если вы используете приоритет по умолчанию, он будет запускаться после того, который заполняет поля. Попробуйте вместо обработчика dns_query_reply:

hook DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) {
    local rec_r: DnsFeatureExtractor::InfoReply = [$uid=c$uid, $id=c$id, $response_code=msg$rcode, $TTL=c$dns$TTLs, $resolved_IP=c$dns$answers, $timestamp=c$start_time];
    Log::write(DnsFeatureExtractor::ReplyDNS, rec_r);
}

Обратите внимание, что вы по-прежнему имеете дело с необязательными значениями записи, поэтому возможно, что, несмотря на вышесказанное, вы все равно не увидите все значения полей. Чтобы избежать этого, вы можете проверить, действительно ли определены дополнительные значения, и скопировать их только в этом случае:

hook DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string)
{
    local rec_r: DnsFeatureExtractor::InfoReply = [$uid=c$uid, $id=c$id, $response_code=msg$rcode, $timestamp=c$start_time];

    if ( c$dns?$TTLs )
        rec_r$TTL = c$dns$TTLs;
    if ( c$dns?$answers )
        rec_r$resolved_IP = c$dns$answers;

    Log::write(DnsFeatureExtractor::ReplyDNS, rec_r);
}
...