diff --git a/lib/libprotoident.h b/lib/libprotoident.h
index 6ea9cec..7455744 100644
--- a/lib/libprotoident.h
+++ b/lib/libprotoident.h
@@ -403,6 +403,8 @@ typedef enum {
LPI_PROTO_TRANSOCKS,
LPI_PROTO_RAGNAROK_ONLINE,
LPI_PROTO_ETHERNETIP,
+ LPI_PROTO_KERBEROS,
+ LPI_PROTO_RPC,
/* UDP Protocols */
LPI_PROTO_UDP,
diff --git a/lib/proto_common.cc b/lib/proto_common.cc
index 6fffd05..c5888dd 100644
--- a/lib/proto_common.cc
+++ b/lib/proto_common.cc
@@ -74,6 +74,14 @@ bool match_chars_either(lpi_data_t *data, char a, char b, char c,
return false;
}
+bool match_chars_both(lpi_data_t *data, char a, char b, char c, char d) {
+ if (!MATCH(data->payload[0], a, b, c, d))
+ return false;
+ if (!MATCH(data->payload[1], a, b, c, d))
+ return false;
+ return true;
+}
+
bool match_payload_length(uint32_t payload, uint32_t payload_len) {
uint32_t header = 0;
diff --git a/lib/proto_common.h b/lib/proto_common.h
index 679f784..b01a196 100644
--- a/lib/proto_common.h
+++ b/lib/proto_common.h
@@ -125,6 +125,7 @@ bool match_str_both(lpi_data_t *data, const char *string1,
const char *string2);
bool match_chars_either(lpi_data_t *data, char a, char b, char c,
char d);
+bool match_chars_both(lpi_data_t *data, char a, char b, char c, char d);
bool match_payload_length(uint32_t payload, uint32_t payload_len);
bool match_ip_address_both(lpi_data_t *data);
bool match_file_header(uint32_t payload);
diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc
index 4d9f12a..1a4a491 100644
--- a/lib/proto_manager.cc
+++ b/lib/proto_manager.cc
@@ -178,6 +178,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) {
register_kankan_tcp(mod_map);
register_kaseya(mod_map);
register_kaspersky(mod_map);
+ register_kerberos(mod_map);
register_kik(mod_map);
register_kingofglory_tcp(mod_map);
register_kuaibo(mod_map);
@@ -253,6 +254,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) {
register_remote_manipulator(mod_map);
register_revolver_nblbt(mod_map);
register_rfb(mod_map);
+ register_rpc(mod_map);
register_rpcscan(mod_map);
register_rrtv(mod_map);
register_rsync(mod_map);
diff --git a/lib/tcp/Makefile.am b/lib/tcp/Makefile.am
index 4531a57..1f891a8 100644
--- a/lib/tcp/Makefile.am
+++ b/lib/tcp/Makefile.am
@@ -111,6 +111,7 @@ libprotoident_tcp_la_SOURCES = \
lpi_kankan_tcp.cc \
lpi_kaseya.cc \
lpi_kaspersky.cc \
+ lpi_kerberos.cc \
lpi_kik.cc \
lpi_kingofglory_tcp.cc \
lpi_kuaibo.cc \
@@ -186,6 +187,7 @@ libprotoident_tcp_la_SOURCES = \
lpi_remote_manipulator.cc \
lpi_revolver_nblbt.cc \
lpi_rfb.cc \
+ lpi_rpc.cc \
lpi_rpcscan.cc \
lpi_rrtv.cc \
lpi_rsync.cc \
diff --git a/lib/tcp/lpi_kerberos.cc b/lib/tcp/lpi_kerberos.cc
new file mode 100644
index 0000000..c1f052d
--- /dev/null
+++ b/lib/tcp/lpi_kerberos.cc
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright (c) 2011-2016 The University of Waikato, Hamilton, New Zealand.
+ * All rights reserved.
+ *
+ * This file is part of libprotoident.
+ *
+ * This code has been developed by the University of Waikato WAND
+ * research group. For further information please see http://www.wand.net.nz/
+ *
+ * libprotoident is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libprotoident is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ *
+ */
+
+#include "libprotoident.h"
+#include "proto_manager.h"
+#include "proto_common.h"
+
+static inline bool match_kerberos(lpi_data_t *data, lpi_module_t *mod UNUSED) {
+
+ /* Quite a weak rule, first 4 bytes of kerberos is the record length which
+ * is spread over multiple packets */
+
+ if (data->server_port == 88)
+ return true;
+
+ return false;
+}
+
+static lpi_module_t lpi_kerberos = {
+ LPI_PROTO_KERBEROS,
+ LPI_CATEGORY_KEY_EXCHANGE,
+ "Kerberos",
+ 200,
+ match_kerberos
+};
+
+void register_kerberos(LPIModuleMap *mod_map) {
+ register_protocol(&lpi_kerberos, mod_map);
+}
+
diff --git a/lib/tcp/lpi_ldap.cc b/lib/tcp/lpi_ldap.cc
index 80f8614..c45f4d0 100644
--- a/lib/tcp/lpi_ldap.cc
+++ b/lib/tcp/lpi_ldap.cc
@@ -30,7 +30,7 @@
#include "proto_manager.h"
#include "proto_common.h"
-static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {
+static inline bool match_ldap_payload(uint32_t payload, uint32_t len, uint16_t server_port) {
uint8_t *byte = ((uint8_t *)&payload);
uint16_t struct_len = 0;
@@ -40,9 +40,10 @@ static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {
byte ++;
+ // multibyte lengths?
if (((*byte) & 0x80) == 0x80) {
uint8_t bytes_required = ((*byte) & 0x7f);
- if (bytes_required > 2 || bytes_required == 0)
+ if (bytes_required == 0)
return false;
if (bytes_required == 1) {
@@ -52,10 +53,15 @@ static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {
struct_len = 3 + ((uint8_t)(*byte));
if (!MATCH(payload, 0x30, ANY, ANY, 0x02))
return false;
- } else {
+ } else if (bytes_required == 2) {
struct_len = 4 + ntohs(*((uint16_t *)(byte + 1)));
if (!MATCH(payload, 0x30, ANY, ANY, ANY))
return false;
+ } else {
+ // the length is now past the first 4 bytes of payload so we are unable
+ // to check it, fallback to port in this case
+ if (server_port == 389)
+ return true;
}
} else {
if (!MATCH(payload, 0x30, ANY, 0x02, 0x01))
@@ -75,9 +81,9 @@ static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {
static inline bool match_ldap(lpi_data_t *data, lpi_module_t *mod UNUSED) {
- if (!match_ldap_payload(data->payload[0], data->payload_len[0]))
+ if (!match_ldap_payload(data->payload[0], data->payload_len[0], data->server_port))
return false;
- if (!match_ldap_payload(data->payload[1], data->payload_len[1]))
+ if (!match_ldap_payload(data->payload[1], data->payload_len[1], data->server_port))
return false;
return true;
diff --git a/lib/tcp/lpi_rpc.cc b/lib/tcp/lpi_rpc.cc
new file mode 100644
index 0000000..54ae0b9
--- /dev/null
+++ b/lib/tcp/lpi_rpc.cc
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright (c) 2011-2016 The University of Waikato, Hamilton, New Zealand.
+ * All rights reserved.
+ *
+ * This file is part of libprotoident.
+ *
+ * This code has been developed by the University of Waikato WAND
+ * research group. For further information please see http://www.wand.net.nz/
+ *
+ * libprotoident is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libprotoident is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ *
+ */
+
+#include
+
+#include "libprotoident.h"
+#include "proto_manager.h"
+#include "proto_common.h"
+
+#define PDU_TYPE(x) (data->payload[0] & 0xff0000) >> 16
+
+static inline bool match_rpc(lpi_data_t *data, lpi_module_t *mod UNUSED) {
+
+ if (data->server_port != 135 && data->client_port != 135)
+ return false;
+
+ // valid PDUs are 0 - 19
+ if (PDU_TYPE(data->payload[0]) > 19 || PDU_TYPE(data->payload[1]) > 19)
+ return false;
+
+ if (match_chars_both(data, 0x05, 0x00, ANY, 0x03))
+ return true;
+
+ return false;
+}
+
+static lpi_module_t lpi_rpc = {
+ LPI_PROTO_RPC,
+ LPI_CATEGORY_SERVICES,
+ "RPC",
+ 200,
+ match_rpc
+};
+
+void register_rpc(LPIModuleMap *mod_map) {
+ register_protocol(&lpi_rpc, mod_map);
+}
+
diff --git a/lib/tcp/tcp_protocols.h b/lib/tcp/tcp_protocols.h
index 89c2bf7..e3086f8 100644
--- a/lib/tcp/tcp_protocols.h
+++ b/lib/tcp/tcp_protocols.h
@@ -139,6 +139,7 @@ void register_kakao(LPIModuleMap *mod_map);
void register_kankan_tcp(LPIModuleMap *mod_map);
void register_kaseya(LPIModuleMap *mod_map);
void register_kaspersky(LPIModuleMap *mod_map);
+void register_kerberos(LPIModuleMap *mod_map);
void register_kik(LPIModuleMap *mod_map);
void register_kingofglory_tcp(LPIModuleMap *mod_map);
void register_kuaibo(LPIModuleMap *mod_map);
@@ -214,6 +215,7 @@ void register_relay(LPIModuleMap *mod_map);
void register_remote_manipulator(LPIModuleMap *mod_map);
void register_revolver_nblbt(LPIModuleMap *mod_map);
void register_rfb(LPIModuleMap *mod_map);
+void register_rpc(LPIModuleMap *mod_map);
void register_rpcscan(LPIModuleMap *mod_map);
void register_rrtv(LPIModuleMap *mod_map);
void register_rsync(LPIModuleMap *mod_map);