ha.last_seen = 0;
ha.payloads.clear();
ha.info.clear();
+ ha.banner_updated = false;
}
bool HostTracker::add_client_payload(HostClient& hc, AppId payload, size_t max_payloads)
return false;
}
+bool HostTracker::update_service_banner(Port port, IpProtocol proto)
+{
+ host_tracker_stats.service_finds++;
+ lock_guard<mutex> lck(host_tracker_lock);
+ for ( auto& s : services )
+ {
+ if ( s.port == port and s.proto == proto )
+ {
+ if ( !s.visibility or s.banner_updated )
+ return false;
+
+ s.banner_updated = true;
+ return true;
+ }
+ }
+ return false;
+}
+
bool HostTracker::update_service_user(Port port, IpProtocol proto, const char* user)
{
host_tracker_stats.service_finds++;
for ( auto& info : s.info )
info.visibility = false;
s.user[0] = '\0';
+ s.banner_updated = false;
}
return true;
}
struct HostApplication
{
HostApplication() = default;
- HostApplication(Port pt, IpProtocol pr, AppId ap, bool in, uint32_t ht = 0, uint32_t ls = 0) :
- port(pt), proto(pr), appid(ap), inferred_appid(in), hits(ht), last_seen(ls) { }
+ HostApplication(Port pt, IpProtocol pr, AppId ap, bool in, uint32_t ht = 0, uint32_t ls = 0,
+ bool banner = false) : port(pt), proto(pr), appid(ap), inferred_appid(in), hits(ht),
+ last_seen(ls), banner_updated(banner) { }
HostApplication(const HostApplication& ha): port(ha.port), proto(ha.proto), appid(ha.appid),
inferred_appid(ha.inferred_appid), hits(ha.hits), last_seen(ha.last_seen), info(ha.info),
payloads(ha.payloads) { }
info = ha.info;
payloads = ha.payloads;
visibility = ha.visibility;
+ banner_updated = ha.banner_updated;
return *this;
}
uint32_t hits = 0;
uint32_t last_seen = 0;
char user[INFO_SIZE] = { '\0' };
+ bool banner_updated = false;
std::vector<HostApplicationInfo, HostAppInfoAllocator> info;
std::vector<Payload_t, HostCacheAllocIp<Payload_t>> payloads;
void update_service(const HostApplication&);
bool update_service_info(HostApplication&, const char* vendor, const char* version,
uint16_t max_info);
+ bool update_service_banner(Port, IpProtocol);
bool update_service_user(Port, IpProtocol, const char* username);
void remove_inferred_services();
const auto& appid_session_api = appid_event->get_appid_session_api();
if ( appid_change_bits[APPID_SERVICE_BIT] or appid_change_bits[APPID_CLIENT_BIT] or
- appid_change_bits[APPID_PAYLOAD_BIT] )
+ appid_change_bits[APPID_PAYLOAD_BIT] or appid_change_bits[APPID_SERVICE_VENDOR_BIT] or
+ appid_change_bits[APPID_VERSION_BIT] )
{
AppId service, client, payload;
appid_session_api.get_app_id(&service, &client, &payload, nullptr, nullptr);
src_mac, conf, logger, version, client, service);
}
- if ( appid_change_bits[APPID_PAYLOAD_BIT] and payload > APP_ID_NONE and
- service > APP_ID_NONE)
+ if ( appid_change_bits[APPID_SERVICE_VENDOR_BIT] or appid_change_bits[APPID_VERSION_BIT] )
{
- discover_payload(p, proto, ht, (const struct in6_addr*) src_ip->get_ip6_ptr(),
- src_mac, conf, logger, service, payload, client);
+ const char* vendor;
+ const char* version;
+ const AppIdServiceSubtype* subtype;
+ appid_session_api.get_service_info(vendor, version, subtype);
+ update_service_info(p, proto, vendor, version, ht, src_ip, src_mac, logger, conf,
+ service);
}
- }
-
- if ( appid_change_bits[APPID_SERVICE_VENDOR_BIT] or appid_change_bits[APPID_VERSION_BIT] )
- {
- const char* vendor;
- const char* version;
- const AppIdServiceSubtype* subtype;
- AppId service, client, payload;
- appid_session_api.get_app_id(&service, &client, &payload, nullptr, nullptr);
- appid_session_api.get_service_info(vendor, version, subtype);
- update_service_info(p, proto, vendor, version, ht, src_ip, src_mac, logger, conf,
- service);
+ if ( appid_change_bits[APPID_PAYLOAD_BIT] and payload > APP_ID_NONE
+ and service > APP_ID_NONE )
+ {
+ discover_payload(p, proto, ht, (const struct in6_addr*) src_ip->get_ip6_ptr(),
+ src_mac, conf, logger, service, payload, client);
+ if ( conf->enable_banner_grab )
+ discover_banner(p, proto, ht, &p->flow->server_ip, src_mac, logger, service);
+ }
}
// Appid supports only login success event. Change checks once login failure and
rt->update_service(ha);
}
+void RnaAppDiscovery::discover_banner(const Packet* p, IpProtocol proto, RnaTracker& rt,
+ const snort::SfIp* ip, const uint8_t* mac, RnaLogger& logger, AppId service)
+{
+ auto srt = rt;
+ const uint8_t* service_mac = mac;
+
+ HostApplication ha(p->flow->server_port, proto, service, false);
+ if ( p->is_from_client() )
+ {
+ srt = host_cache.find(p->flow->server_ip);
+ if ( !srt )
+ return;
+
+ if ( layer::get_eth_layer(p) )
+ service_mac = layer::get_eth_layer(p)->ether_dst;
+ else
+ service_mac = srt->get_last_seen_mac();
+ }
+
+ if ( !srt->update_service_banner(p->flow->server_port, proto) )
+ return;
+
+ ha.last_seen = (uint32_t) packet_time();
+ logger.log(RNA_EVENT_CHANGE, CHANGE_BANNER_UPDATE, p, &srt,
+ (const struct in6_addr*) ip->get_ip6_ptr(), service_mac, &ha);
+}
+
void RnaAppDiscovery::discover_client(const Packet* p, RnaTracker& rt,
const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf,
RnaLogger& logger, const char* version, AppId client, AppId service)
static void discover_user(const snort::Packet*, RnaTracker&, const struct in6_addr*,
RnaLogger&, const char* username, AppId, IpProtocol);
+ static void discover_banner(const snort::Packet*, IpProtocol, RnaTracker&,
+ const snort::SfIp*, const uint8_t* mac, RnaLogger&, AppId);
private:
static void update_service_info(const snort::Packet*, IpProtocol, const char* vendor,
const char* version, RnaTracker&, const snort::SfIp*, const uint8_t*,
debug_logf(rna_trace, nullptr, "RNA Service Info log: version: %s\n",
s.version);
}
+ if ( rle.type == RNA_EVENT_CHANGE and rle.subtype == CHANGE_BANNER_UPDATE )
+ debug_logf(rna_trace, nullptr, "RNA Banner log: true\n");
}
if ( rle.user )
assert(ht);
RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var,
- ha, fp, hc, user, appid, di, jb);
+ ha, fp, hc, user, appid, di, jb, p);
if ( src_ip and (!IN6_IS_ADDR_V4MAPPED(src_ip) or src_ip->s6_addr32[3]) )
rle.ip = src_ip;
else
RnaLoggerEvent (uint16_t t, uint16_t st, const uint8_t* mc, const RnaTracker* rt,
const snort::HostMac* hmp, uint16_t pr, void* cv, const snort::HostApplication* hap,
const snort::FpFingerprint* fpr, const snort::HostClient* hcp, const char* u,
- int32_t app, const char* di, bool jb) : type(t), subtype(st), mac(mc), ht(rt), hm(hmp),
- proto(pr), cond_var(cv), ha(hap), fp(fpr), hc(hcp), user(u), appid(app),
- device_info(di), jail_broken(jb) { }
+ int32_t app, const char* di, bool jb, const snort::Packet* p) : type(t), subtype(st),
+ mac(mc), ht(rt), hm(hmp), proto(pr), cond_var(cv), ha(hap), fp(fpr), hc(hcp),
+ user(u), appid(app), device_info(di), jail_broken(jb), pkt(p) { }
uint32_t event_time = 0;
uint16_t type;
AppId appid;
const char* device_info;
bool jail_broken;
+ const snort::Packet* pkt;
};
class RnaLogger
#define CHANGE_HOST_UPDATE 15
#define CHANGE_HOST_TYPE 16
#define CHANGE_VLAN_TAG 18
+ #define CHANGE_BANNER_UPDATE 24
#define CHANGE_CLIENT_APP_UPDATE 32
#define RUA_EVENT 1004