From 7899f2b12fdff77b46942d8d6646e0e6f78ffc35 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Tue, 11 Jun 2019 11:58:24 +1200 Subject: [PATCH 01/27] Minor rule enhancements to improve match rate * Nintendo * QUIC * Path of Exile * IPFS * Filenori --- lib/tcp/lpi_filenori.cc | 2 +- lib/tcp/lpi_ipfs.cc | 3 +++ lib/tcp/lpi_pathofexile.cc | 2 +- lib/udp/lpi_nintendo.cc | 3 +-- lib/udp/lpi_quic.cc | 6 +++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/tcp/lpi_filenori.cc b/lib/tcp/lpi_filenori.cc index d1a8a8d4..fb0ea028 100644 --- a/lib/tcp/lpi_filenori.cc +++ b/lib/tcp/lpi_filenori.cc @@ -47,7 +47,7 @@ static inline bool match_100(uint32_t payload, uint32_t len) { static inline bool match_command(uint32_t payload, uint32_t len) { /* Probably short for START */ - if (len == 20 && MATCHSTR(payload, "STAR")) + if ((len == 20 || len == 19) && MATCHSTR(payload, "STAR")) return true; /* DOWNLOAD ? */ diff --git a/lib/tcp/lpi_ipfs.cc b/lib/tcp/lpi_ipfs.cc index 6f031807..1b0ca9ae 100644 --- a/lib/tcp/lpi_ipfs.cc +++ b/lib/tcp/lpi_ipfs.cc @@ -36,6 +36,9 @@ static inline bool match_ipfs_mu(uint32_t payload, uint32_t len) { if (len == 20 && MATCH(payload, 0x13, 0x2f, 'm', 'u')) { return true; } + if (len == 34 && MATCH(payload, 0x13, 0x2f, 'm', 'u')) { + return true; + } return false; } diff --git a/lib/tcp/lpi_pathofexile.cc b/lib/tcp/lpi_pathofexile.cc index fff3bf63..cbb607a2 100644 --- a/lib/tcp/lpi_pathofexile.cc +++ b/lib/tcp/lpi_pathofexile.cc @@ -32,7 +32,7 @@ static inline bool match_poe_40(uint32_t payload, uint32_t len) { if (MATCH(payload, 0x00, 0x03, 0x00, 0x00)) { - if (len == 40 || len == 54) { + if (len == 40 || len == 54 || len == 20 || len == 66) { return true; } } diff --git a/lib/udp/lpi_nintendo.cc b/lib/udp/lpi_nintendo.cc index 5c6c9251..b3bef842 100644 --- a/lib/udp/lpi_nintendo.cc +++ b/lib/udp/lpi_nintendo.cc @@ -34,8 +34,7 @@ static inline bool match_nintendo_magic(uint32_t payload, uint32_t len) { /* https://github.com/Shragei/SplatNet/blob/master/NinMainTiming.txt */ - /* Only seen 64 byte packets so far */ - if (len == 64 && MATCH(payload, 0x32, 0xab, 0x98, 0x64)) + if ((len == 64 || len == 84) && MATCH(payload, 0x32, 0xab, 0x98, 0x64)) return true; return false; } diff --git a/lib/udp/lpi_quic.cc b/lib/udp/lpi_quic.cc index fb6f1b3b..453ce8fa 100644 --- a/lib/udp/lpi_quic.cc +++ b/lib/udp/lpi_quic.cc @@ -176,7 +176,8 @@ static inline bool match_req_q044(uint32_t payload, uint32_t len) { if (MATCHSTR(payload, "\xffQ04") && len == 1330) { return true; } - if (MATCH(payload, 0xc3, 'Q', '0', '4') && len == 1350) { + if (MATCH(payload, 0xc3, 'Q', '0', '4') && + (len == 1350 || len == 1330)) { return true; } return false; @@ -196,6 +197,9 @@ static inline bool match_reply_q044(uint32_t payload, uint32_t len) { if (MATCH(payload, 0xc3, 'Q', '0', '4')) { return true; } + if (MATCH(payload, 0xd3, 'Q', '0', '4')) { + return true; + } return false; } From bbd6a1daf1d73991688ec63b03e696f34080e740 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Tue, 11 Jun 2019 11:59:34 +1200 Subject: [PATCH 02/27] Add 4 new protocols * RR.tv * Apple Remote Desktop * Webex STUN * Remote Manipulator --- lib/libprotoident.h | 4 ++ lib/proto_manager.cc | 4 ++ lib/tcp/Makefile.am | 3 + lib/tcp/lpi_remote_manipulator.cc | 83 ++++++++++++++++++++++++ lib/tcp/lpi_rrtv.cc | 80 +++++++++++++++++++++++ lib/tcp/lpi_webex_stun.cc | 87 +++++++++++++++++++++++++ lib/tcp/tcp_protocols.h | 3 + lib/udp/Makefile.am | 1 + lib/udp/lpi_ard.cc | 101 ++++++++++++++++++++++++++++++ lib/udp/udp_protocols.h | 1 + 10 files changed, 367 insertions(+) create mode 100644 lib/tcp/lpi_remote_manipulator.cc create mode 100644 lib/tcp/lpi_rrtv.cc create mode 100644 lib/tcp/lpi_webex_stun.cc create mode 100644 lib/udp/lpi_ard.cc diff --git a/lib/libprotoident.h b/lib/libprotoident.h index 830e5f73..a74fea63 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -390,6 +390,9 @@ typedef enum { LPI_PROTO_300_HEROES, LPI_PROTO_FILENORI, LPI_PROTO_IPFS, + LPI_PROTO_REMOTE_MANIPULATOR, + LPI_PROTO_WEBEX_STUN, + LPI_PROTO_RRTV, /* UDP Protocols */ LPI_PROTO_UDP, @@ -622,6 +625,7 @@ typedef enum { LPI_PROTO_UDP_HEROES_EVOLVED, LPI_PROTO_UDP_RULES_OF_SURVIVAL, LPI_PROTO_UDP_CONTRACT_WARS, + LPI_PROTO_UDP_ARD, /* Patterns that we can match, but do not know the protocol */ LPI_PROTO_REJECTION, /* All responses are 0x02 */ diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 572b99bc..7d8b7bc6 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -244,9 +244,11 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_realvnc(mod_map); register_rejection(mod_map); register_relay(mod_map); + register_remote_manipulator(mod_map); register_revolver_nblbt(mod_map); register_rfb(mod_map); register_rpcscan(mod_map); + register_rrtv(mod_map); register_rsync(mod_map); register_rtmp(mod_map); register_rtsp(mod_map); @@ -313,6 +315,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_vpnunlimited_tcp(mod_map); register_warcraft3(mod_map); register_web_junk(mod_map); + register_webex_stun(mod_map); register_weblogic(mod_map); register_wechat(mod_map); register_weibo(mod_map); @@ -353,6 +356,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_akamai_transfer(mod_map); register_amanda(mod_map); register_apple_facetime_init(mod_map); + register_ard(mod_map); register_ares_udp(mod_map); register_arksurvival(mod_map); register_arma_server(mod_map); diff --git a/lib/tcp/Makefile.am b/lib/tcp/Makefile.am index 1e46ae3b..df0833e4 100644 --- a/lib/tcp/Makefile.am +++ b/lib/tcp/Makefile.am @@ -177,9 +177,11 @@ libprotoident_tcp_la_SOURCES = \ lpi_realvnc.cc \ lpi_rejection.cc \ lpi_relay.cc \ + lpi_remote_manipulator.cc \ lpi_revolver_nblbt.cc \ lpi_rfb.cc \ lpi_rpcscan.cc \ + lpi_rrtv.cc \ lpi_rsync.cc \ lpi_rtmp.cc \ lpi_rtsp.cc \ @@ -246,6 +248,7 @@ libprotoident_tcp_la_SOURCES = \ lpi_vpnunlimited_tcp.cc \ lpi_warcraft3.cc \ lpi_web_junk.cc \ + lpi_webex_stun.cc \ lpi_weblogic.cc \ lpi_wechat.cc \ lpi_weibo.cc \ diff --git a/lib/tcp/lpi_remote_manipulator.cc b/lib/tcp/lpi_remote_manipulator.cc new file mode 100644 index 00000000..c7a056cb --- /dev/null +++ b/lib/tcp/lpi_remote_manipulator.cc @@ -0,0 +1,83 @@ +/* + * + * 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" + +/* Remote Manipulator System a.k.a Remote Utilities + * + * Russian RDP-style software, sometimes used in malware for remote control. + */ + +static inline bool match_rms_9504(uint32_t payload, uint32_t len) { + if (len == 1338 && MATCH(payload, 0x95, 0x04, 0x00, 0x00)) { + return true; + } + return false; +} + +static inline bool match_rms_d90d(uint32_t payload, uint32_t len) { + if (len == 8 && MATCH(payload, 0xd9, 0x0d, 0x00, 0x00)) { + return true; + } + return false; +} + +static inline bool match_remote_manipulator(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (data->server_port != 5655 && data->client_port != 5655) + return false; + + if (match_rms_9504(data->payload[0], data->payload_len[0])) { + if (match_rms_d90d(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_rms_9504(data->payload[1], data->payload_len[1])) { + if (match_rms_d90d(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_remote_manipulator = { + LPI_PROTO_REMOTE_MANIPULATOR, + LPI_CATEGORY_REMOTE, + "RemoteManipulator", + 100, + match_remote_manipulator +}; + +void register_remote_manipulator(LPIModuleMap *mod_map) { + register_protocol(&lpi_remote_manipulator, mod_map); +} + diff --git a/lib/tcp/lpi_rrtv.cc b/lib/tcp/lpi_rrtv.cc new file mode 100644 index 00000000..f4244b3d --- /dev/null +++ b/lib/tcp/lpi_rrtv.cc @@ -0,0 +1,80 @@ +/* + * + * 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" + +/* rr.tv -- P2P TV/video streaming from China */ + +/* XXX mobile only, need to test the app properly but the initial + * packets literally include URLs referring to rr.tv so I'm pretty + * confident. + */ + +static inline bool match_rrtv_header(uint32_t payload, uint32_t len) { + + /* broad estimate based on what I've seen so far */ + if (len < 550 || len > 700) { + return false; + } + + if ((ntohl(payload) & 0x0000ffff) != len - 4) { + return false; + } + + if (MATCH(payload, 0x01, 0x10, ANY, ANY)) { + return true; + } + + return false; +} + +static inline bool match_rrtv(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_rrtv_header(data->payload[0], data->payload_len[0])) { + if (match_rrtv_header(data->payload[1], data->payload_len[1])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_rrtv = { + LPI_PROTO_RRTV, + LPI_CATEGORY_P2PTV, + "RR.tv", + 120, + match_rrtv +}; + +void register_rrtv(LPIModuleMap *mod_map) { + register_protocol(&lpi_rrtv, mod_map); +} + diff --git a/lib/tcp/lpi_webex_stun.cc b/lib/tcp/lpi_webex_stun.cc new file mode 100644 index 00000000..33560b97 --- /dev/null +++ b/lib/tcp/lpi_webex_stun.cc @@ -0,0 +1,87 @@ +/* + * + * 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" + +/* Bastardization of the STUN protocol used by Cisco Webex */ + +static inline bool match_webex_req(uint32_t payload, uint32_t len) { + + if (len == 28 && MATCH(payload, 0x00, 0x03, 0x00, 0x08)) { + return true; + } + + return false; +} + +static inline bool match_webex_resp(uint32_t payload, uint32_t len) { + + if (MATCH(payload, 0x01, 0x13, 0x00, ANY)) { + if ((ntohl(payload) & 0x0000ffff) == len - 20) + return true; + } + + return false; +} + +static inline bool match_webex_stun(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (data->server_port != 80 && data->client_port != 80) { + return false; + } + + if (match_webex_req(data->payload[0], data->payload_len[0])) { + if (match_webex_resp(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_webex_req(data->payload[1], data->payload_len[1])) { + if (match_webex_resp(data->payload[0], data->payload_len[0])) { + return true; + } + } + + + return false; +} + +static lpi_module_t lpi_webex_stun = { + LPI_PROTO_WEBEX_STUN, + LPI_CATEGORY_TUNNELLING, + "WebexSTUN", + 140, + match_webex_stun +}; + +void register_webex_stun(LPIModuleMap *mod_map) { + register_protocol(&lpi_webex_stun, mod_map); +} + diff --git a/lib/tcp/tcp_protocols.h b/lib/tcp/tcp_protocols.h index c7ae37f0..cd646417 100644 --- a/lib/tcp/tcp_protocols.h +++ b/lib/tcp/tcp_protocols.h @@ -205,9 +205,11 @@ void register_realmofthemadgod(LPIModuleMap *mod_map); void register_realvnc(LPIModuleMap *mod_map); void register_rejection(LPIModuleMap *mod_map); 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_rpcscan(LPIModuleMap *mod_map); +void register_rrtv(LPIModuleMap *mod_map); void register_rsync(LPIModuleMap *mod_map); void register_rtmp(LPIModuleMap *mod_map); void register_rtsp(LPIModuleMap *mod_map); @@ -274,6 +276,7 @@ void register_vpnrobot_tcp(LPIModuleMap *mod_map); void register_vpnunlimited_tcp(LPIModuleMap *mod_map); void register_warcraft3(LPIModuleMap *mod_map); void register_web_junk(LPIModuleMap *mod_map); +void register_webex_stun(LPIModuleMap *mod_map); void register_weblogic(LPIModuleMap *mod_map); void register_wechat(LPIModuleMap *mod_map); void register_weibo(LPIModuleMap *mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index 339f246b..942efc71 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -8,6 +8,7 @@ libprotoident_udp_la_SOURCES = \ lpi_akamai_transfer.cc \ lpi_amanda.cc \ lpi_apple_facetime_init.cc \ + lpi_ard.cc \ lpi_ares.cc \ lpi_ark.cc \ lpi_arma_server.cc \ diff --git a/lib/udp/lpi_ard.cc b/lib/udp/lpi_ard.cc new file mode 100644 index 00000000..1238edfb --- /dev/null +++ b/lib/udp/lpi_ard.cc @@ -0,0 +1,101 @@ +/* + * + * 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" + +/* Apple Remote Desktop protocol, generally used to remotely manage Macs. + * Probably shouldn't be seen on the Internet, particularly with the patterns + * presented here as this was almost certainly a case where a Mac with remote + * management enabled was being abused into performing an amplification attack. + * + * Of course, being Apple, there is no public documentation of this protocol + * anywhere so it's pretty hard to write rules that cover legitimate uses of + * this protocol. + */ + +static inline bool match_ard_tiny_req(uint32_t payload, uint32_t len) { + if (len == 5 && MATCH(payload, 0x00, 0x14, 0x00, 0x01)) { + return true; + } + return false; +} + +static inline bool match_ard_large_resp(uint32_t payload, uint32_t len) { + + /* All my examples were 1006 bytes, but that's just from one + * specific machine */ + if (len < 1000) { + return false; + } + + if ((ntohl(payload) & 0x0000ffff) != len - 4) { + return false; + } + + if (MATCH(payload, 0x00, 0x01, ANY, ANY)) { + return true; + } + + return false; +} + +static inline bool match_ard(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (data->server_port != 3283 && data->client_port != 3283) { + return false; + } + + if (match_ard_tiny_req(data->payload[0], data->payload_len[0])) { + if (match_ard_large_resp(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_ard_tiny_req(data->payload[1], data->payload_len[1])) { + if (match_ard_large_resp(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_ard = { + LPI_PROTO_UDP_ARD, + LPI_CATEGORY_REMOTE, + "ARD", + 20, + match_ard +}; + +void register_ard(LPIModuleMap *mod_map) { + register_protocol(&lpi_ard, mod_map); +} + diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index 1b7d0c99..2b6e77b0 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -38,6 +38,7 @@ void register_akamai(LPIModuleMap *mod_map); void register_akamai_transfer(LPIModuleMap *mod_map); void register_amanda(LPIModuleMap *mod_map); void register_apple_facetime_init(LPIModuleMap *mod_map); +void register_ard(LPIModuleMap *mod_map); void register_ares_udp(LPIModuleMap *mod_map); void register_arksurvival(LPIModuleMap *mod_map); void register_arma_server(LPIModuleMap *mod_map); From c73e76831d8a1dced1a005a8fd2deb82bffca96c Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Tue, 11 Jun 2019 12:00:19 +1200 Subject: [PATCH 03/27] Add file-magic for RIR delegation files --- lib/proto_common.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/proto_common.cc b/lib/proto_common.cc index 8e767e20..9589d1cd 100644 --- a/lib/proto_common.cc +++ b/lib/proto_common.cc @@ -327,6 +327,10 @@ bool match_file_header(uint32_t payload) { if (MATCH(payload, 't', 't', 'c', 'f')) return true; + /* RIR delegation files... */ + if (MATCH(payload, '2', '.', '3', '|')) + return true; + /* REBASE -- restriction enzyme database * A bit niche, but might be fairly common at universities? */ if (MATCH(payload, 0x20, 0x0a, 'R', 'E')) From 4a67406d86489ce80a0a770ebebc486b32ad1833 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 14 Jun 2019 16:32:33 +1200 Subject: [PATCH 04/27] Add rule to ARD for non-responsive amplification targets --- lib/udp/lpi_ard.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/udp/lpi_ard.cc b/lib/udp/lpi_ard.cc index 1238edfb..b4a3e7d9 100644 --- a/lib/udp/lpi_ard.cc +++ b/lib/udp/lpi_ard.cc @@ -49,6 +49,13 @@ static inline bool match_ard_tiny_req(uint32_t payload, uint32_t len) { static inline bool match_ard_large_resp(uint32_t payload, uint32_t len) { + /* Match the case where the client doesn't reply (i.e. participate + * in the amplification attack). + */ + if (len == 0) { + return true; + } + /* All my examples were 1006 bytes, but that's just from one * specific machine */ if (len < 1000) { From bd5188832e4bd76b986fe682ee0b0e8ad87ea610 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 14 Jun 2019 16:33:18 +1200 Subject: [PATCH 05/27] Add new protocol: QVOD UDP --- lib/libprotoident.h | 1 + lib/proto_manager.cc | 1 + lib/udp/Makefile.am | 1 + lib/udp/lpi_qvod_udp.cc | 77 +++++++++++++++++++++++++++++++++++++++++ lib/udp/udp_protocols.h | 1 + 5 files changed, 81 insertions(+) create mode 100644 lib/udp/lpi_qvod_udp.cc diff --git a/lib/libprotoident.h b/lib/libprotoident.h index a74fea63..98e6223a 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -626,6 +626,7 @@ typedef enum { LPI_PROTO_UDP_RULES_OF_SURVIVAL, LPI_PROTO_UDP_CONTRACT_WARS, LPI_PROTO_UDP_ARD, + LPI_PROTO_UDP_QVOD, /* Patterns that we can match, but do not know the protocol */ LPI_PROTO_REJECTION, /* All responses are 0x02 */ diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 7d8b7bc6..019d6730 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -513,6 +513,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_qqspeedmobile_udp(mod_map); register_quake(mod_map); register_quic(mod_map); + register_qvod_udp(mod_map); register_radius(mod_map); register_ramsey_dash(mod_map); register_rdp_udp(mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index 942efc71..4e16a901 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -166,6 +166,7 @@ libprotoident_udp_la_SOURCES = \ lpi_qqspeedmobile_udp.cc \ lpi_quake.cc \ lpi_quic.cc \ + lpi_qvod_udp.cc \ lpi_radius.cc \ lpi_ramseydash.cc \ lpi_rdp_udp.cc \ diff --git a/lib/udp/lpi_qvod_udp.cc b/lib/udp/lpi_qvod_udp.cc new file mode 100644 index 00000000..5541ac81 --- /dev/null +++ b/lib/udp/lpi_qvod_udp.cc @@ -0,0 +1,77 @@ +/* + * + * 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" + +static inline bool match_qvod_1(uint32_t payload, uint32_t len) { + + if (len == 1 && MATCH(payload, 0x30, 0x00, 0x00, 0x00)) { + return true; + } + return false; +} + +static inline bool match_qvod_13(uint32_t payload, uint32_t len) { + + if (len == 13 && MATCH(payload, 0x00, 0x00, 0x00, 0x0d)) { + return true; + } + return false; +} + +static inline bool match_qvod_udp(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_qvod_1(data->payload[0], data->payload_len[0])) { + if (match_qvod_13(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_qvod_1(data->payload[1], data->payload_len[1])) { + if (match_qvod_13(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_qvod_udp = { + LPI_PROTO_UDP_QVOD, + LPI_CATEGORY_P2P, + "QVOD_UDP", + 201, + match_qvod_udp +}; + +void register_qvod_udp(LPIModuleMap *mod_map) { + register_protocol(&lpi_qvod_udp, mod_map); +} + diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index 2b6e77b0..cb80294d 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -195,6 +195,7 @@ void register_qqpcmgr(LPIModuleMap *mod_map); void register_qqspeedmobile_udp(LPIModuleMap *mod_map); void register_quake(LPIModuleMap *mod_map); void register_quic(LPIModuleMap *mod_map); +void register_qvod_udp(LPIModuleMap *mod_map); void register_radius(LPIModuleMap *mod_map); void register_ramsey_dash(LPIModuleMap *mod_map); void register_rdp_udp(LPIModuleMap *mod_map); From 1ab657ebbdba322126b433dbf79fbf865550cac8 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 11 Jul 2019 16:51:13 +1200 Subject: [PATCH 06/27] Update QUIC rule to match packets beginning with 0xe3 --- lib/udp/lpi_quic.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/udp/lpi_quic.cc b/lib/udp/lpi_quic.cc index 453ce8fa..0812aa6c 100644 --- a/lib/udp/lpi_quic.cc +++ b/lib/udp/lpi_quic.cc @@ -200,6 +200,9 @@ static inline bool match_reply_q044(uint32_t payload, uint32_t len) { if (MATCH(payload, 0xd3, 'Q', '0', '4')) { return true; } + if (MATCH(payload, 0xe3, 'Q', '0', '4')) { + return true; + } return false; } From 503a56795eb3c767fcfb7749cf119eccc5a7cd38 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 11 Jul 2019 16:51:45 +1200 Subject: [PATCH 07/27] Extend RTP RTCP report rule to include slightly larger packets --- lib/udp/lpi_rtp.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/udp/lpi_rtp.cc b/lib/udp/lpi_rtp.cc index 03671648..19468946 100644 --- a/lib/udp/lpi_rtp.cc +++ b/lib/udp/lpi_rtp.cc @@ -75,6 +75,8 @@ static inline bool match_rtcp_report(uint32_t payload, uint32_t len) { return true; if (len == 32 && MATCH(payload, 0x81, 0xc9, 0x00, 0x07)) return true; + if (len == 36 && MATCH(payload, 0x81, 0xc9, 0x00, 0x07)) + return true; return false; } From 81cf856c11ccf922339c13e35d28b389e5f320c6 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 11 Jul 2019 16:52:41 +1200 Subject: [PATCH 08/27] Minor rule improvements for RRTV, WoW, DTLS, and Second Life --- lib/tcp/lpi_rrtv.cc | 2 +- lib/tcp/lpi_wow.cc | 2 +- lib/udp/lpi_dtls.cc | 13 +++++++++++++ lib/udp/lpi_second_life.cc | 4 ---- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/tcp/lpi_rrtv.cc b/lib/tcp/lpi_rrtv.cc index f4244b3d..fa5b59d9 100644 --- a/lib/tcp/lpi_rrtv.cc +++ b/lib/tcp/lpi_rrtv.cc @@ -40,7 +40,7 @@ static inline bool match_rrtv_header(uint32_t payload, uint32_t len) { /* broad estimate based on what I've seen so far */ - if (len < 550 || len > 700) { + if (len < 380 || len > 700) { return false; } diff --git a/lib/tcp/lpi_wow.cc b/lib/tcp/lpi_wow.cc index 2814ef7a..368201b7 100644 --- a/lib/tcp/lpi_wow.cc +++ b/lib/tcp/lpi_wow.cc @@ -75,7 +75,7 @@ static inline bool match_wow_s2c(uint32_t payload, uint32_t len) { static inline bool match_wow_2016(uint32_t payload, uint32_t len) { - if (len == 47 || len == 48) { + if (len == 47 || len == 48 || len == 52) { if (MATCHSTR(payload, "WORL")) return true; } diff --git a/lib/udp/lpi_dtls.cc b/lib/udp/lpi_dtls.cc index 7d204572..a76d5eec 100644 --- a/lib/udp/lpi_dtls.cc +++ b/lib/udp/lpi_dtls.cc @@ -65,6 +65,19 @@ static inline bool match_dtls(lpi_data_t *data, lpi_module_t *mod UNUSED) { return true; } + /* DTLS 1.2 */ + if (MATCHSTR(data->payload[0], "\x16\xfe\xfd\x00")) { + if (data->payload_len[1] == 0) + return true; + if (MATCHSTR(data->payload[1], "\x16\xfe\xfd\x00")) + return true; + } + + if (MATCHSTR(data->payload[1], "\x16\xfe\xfd\x00")) { + if (data->payload_len[0] == 0) + return true; + } + /* This is probably Google Duo -- consider separate protocol? */ if (MATCHSTR(data->payload[0], "\x17\xfe\xfd\x00")) { if (MATCHSTR(data->payload[1], "\x17\xfe\xfd\x00")) diff --git a/lib/udp/lpi_second_life.cc b/lib/udp/lpi_second_life.cc index 7be6edce..72a98475 100644 --- a/lib/udp/lpi_second_life.cc +++ b/lib/udp/lpi_second_life.cc @@ -54,8 +54,6 @@ static inline bool match_second_life(lpi_data_t *data, lpi_module_t *mod UNUSED) if (MATCH(data->payload[1], ANY, 0x00, 0x00, 0x00)) { if (data->payload_len[1] < 15) return false; - if ((data->payload_len[1] + 1) % 4 == 0) - return true; } } @@ -65,8 +63,6 @@ static inline bool match_second_life(lpi_data_t *data, lpi_module_t *mod UNUSED) if (MATCH(data->payload[0], ANY, 0x00, 0x00, 0x00)) { if (data->payload_len[0] < 15) return false; - if ((data->payload_len[0] + 1) % 4 == 0) - return true; } } return false; From 1d1007412a73c1f5f32680436e628cd7be084308 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 11 Jul 2019 17:09:11 +1200 Subject: [PATCH 09/27] Minor README edits * Point at github wiki for list of supported protocols (the trac one is way out of date). * Link to libtrace wiki page to explain URIs, as this may not be clear to people otherwise. --- README | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README b/README index f05dda43..70b6999a 100644 --- a/README +++ b/README @@ -65,7 +65,7 @@ The libprotoident tools are built by default - this can be changed by using the Protocols Supported =================== A full list of supported protocols can be found at -http://wand.net.nz/trac/libprotoident/wiki/SupportedProtocols +https://github.com/wanduow/libprotoident/wiki/SupportedProtocols Libprotoident also currently has rules for several "mystery" protocols. These are patterns that commonly occur in our trace sets that we cannot tie to an @@ -93,6 +93,9 @@ There are three tools included with libprotoident. lpi_protoident The input trace must be a valid libtrace URI. + See https://github.com/LibtraceTeam/libtrace/wiki/Supported-Trace-Formats + to learn more about libtrace URIs. Note that a URI may be a live + source, such as a network interface. Output: For each flow in the input trace, a single line is printed to stdout @@ -132,6 +135,9 @@ There are three tools included with libprotoident. lpi_find_unknown The input trace must be a valid libtrace URI. + See https://github.com/LibtraceTeam/libtrace/wiki/Supported-Trace-Formats + to learn more about libtrace URIs. Note that a URI may be a live + source, such as a network interface. Output: For each unknown flow in the input trace, a single line is printed to @@ -167,6 +173,9 @@ There are three tools included with libprotoident. lpi_arff The input trace must be a valid libtrace URI. + See https://github.com/LibtraceTeam/libtrace/wiki/Supported-Trace-Formats + to learn more about libtrace URIs. Note that a URI may be a live + source, such as a network interface. Output: The output begins with a series of lines describing each feature that From 32a3293279ac12679b016290023d4a73005d2b45 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 2 Aug 2019 15:07:50 +1200 Subject: [PATCH 10/27] Add support for buster to gitlab package builder * strip package version numbers from git tags before building packages * Fix missing body in 2.0.13 debian changelog entry --- .gitlab-ci.yml | 14 ++++++++++++++ debian/changelog | 3 ++- gitlab-build.sh | 4 +++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 77520e5c..c7a780d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,6 +30,20 @@ build-debian-stretch: only: - tags +build-debian-buster: + stage: build + image: debian:buster + script: + - ./gitlab-build.sh + - mkdir -p built-packages/buster/ + - mv ../*.deb built-packages/buster/ + artifacts: + paths: + - built-packages/* + expire_in: 1 day + only: + - tags + build-ubuntu-xenial: stage: build image: ubuntu:xenial diff --git a/debian/changelog b/debian/changelog index e29ab11b..42bd28fd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,5 @@ -libprotoident (2.0.13) UNRELEASED; urgency=low +libprotoident (2.0.13) unstable; urgency=low + * New upstream release -- Shane Alcock Tue, 09 Apr 2019 13:49:25 +1200 diff --git a/gitlab-build.sh b/gitlab-build.sh index ea1892db..954b239e 100755 --- a/gitlab-build.sh +++ b/gitlab-build.sh @@ -6,6 +6,8 @@ export DEBEMAIL='packaging@wand.net.nz' export DEBFULLNAME='WAND Packaging' export DEBIAN_FRONTEND=noninteractive +SOURCENAME=`echo ${CI_COMMIT_REF_NAME} | cut -d '-' -f 1` + apt-get update apt-get install -y equivs devscripts dpkg-dev quilt curl apt-transport-https \ apt-utils ssl-cert ca-certificates gnupg lsb-release debhelper git @@ -18,6 +20,6 @@ curl --silent "https://bintray.com/user/downloadSubjectPublicKey?username=wand"\ apt-get update apt-get upgrade -y -dpkg-parsechangelog -S version | grep -q ${CI_COMMIT_REF_NAME} || debchange --newversion ${CI_COMMIT_REF_NAME} -b "New upstream release" +dpkg-parsechangelog -S version | grep -q ${SOURCENAME} || debchange --newversion ${SOURCENAME} -b "New upstream release" mk-build-deps -i -r -t 'apt-get -f -y --force-yes' dpkg-buildpackage -b -us -uc -rfakeroot -j4 From ff8c97346b28ecbaf779bc57f0b66dcde640adf5 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Mon, 30 Sep 2019 16:20:56 +1300 Subject: [PATCH 11/27] Add 5 new protocols: * RabbitMQ * Cloudflare Warp * Wireguard * Rocket League * Yuanfudao --- lib/libprotoident.h | 5 ++ lib/proto_manager.cc | 5 ++ lib/tcp/Makefile.am | 1 + lib/tcp/lpi_rabbitmq.cc | 83 ++++++++++++++++++++++++ lib/tcp/tcp_protocols.h | 1 + lib/udp/Makefile.am | 4 ++ lib/udp/lpi_cloudflare_warp.cc | 115 +++++++++++++++++++++++++++++++++ lib/udp/lpi_rocket_league.cc | 79 ++++++++++++++++++++++ lib/udp/lpi_wireguard.cc | 77 ++++++++++++++++++++++ lib/udp/lpi_yuanfudao.cc | 79 ++++++++++++++++++++++ lib/udp/udp_protocols.h | 4 ++ 11 files changed, 453 insertions(+) create mode 100644 lib/tcp/lpi_rabbitmq.cc create mode 100644 lib/udp/lpi_cloudflare_warp.cc create mode 100644 lib/udp/lpi_rocket_league.cc create mode 100644 lib/udp/lpi_wireguard.cc create mode 100644 lib/udp/lpi_yuanfudao.cc diff --git a/lib/libprotoident.h b/lib/libprotoident.h index 98e6223a..5f33e7c2 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -393,6 +393,7 @@ typedef enum { LPI_PROTO_REMOTE_MANIPULATOR, LPI_PROTO_WEBEX_STUN, LPI_PROTO_RRTV, + LPI_PROTO_RABBITMQ, /* UDP Protocols */ LPI_PROTO_UDP, @@ -627,6 +628,10 @@ typedef enum { LPI_PROTO_UDP_CONTRACT_WARS, LPI_PROTO_UDP_ARD, LPI_PROTO_UDP_QVOD, + LPI_PROTO_UDP_YUANFUDAO, + LPI_PROTO_UDP_ROCKET_LEAGUE, + LPI_PROTO_UDP_CLOUDFLARE_WARP, + LPI_PROTO_UDP_WIREGUARD, /* Patterns that we can match, but do not know the protocol */ LPI_PROTO_REJECTION, /* All responses are 0x02 */ diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 019d6730..31ce2128 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -237,6 +237,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_qqlive_tcp(mod_map); register_qqspeedmobile_tcp(mod_map); register_qvod(mod_map); + register_rabbitmq(mod_map); register_razor(mod_map); register_rbls(mod_map); register_rdp(mod_map); @@ -380,6 +381,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_cirn(mod_map); register_cisco_ipsec(mod_map); register_cisco_sslvpn(mod_map); + register_cloudflare_warp(mod_map); register_combatarms(mod_map); register_combatarms_p2p(mod_map); register_contract_wars(mod_map); @@ -521,6 +523,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_risingstorm(mod_map); register_roblox(mod_map); register_robocraft(mod_map); + register_rocket_league(mod_map); register_rrshare(mod_map); register_rtcp(mod_map); register_rtmfp(mod_map); @@ -578,6 +581,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_webex(mod_map); register_wechat_udp(mod_map); register_winmessage(mod_map); + register_wireguard(mod_map); register_wolfet(mod_map); register_worm_22105(mod_map); register_xfire_p2p(mod_map); @@ -587,6 +591,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_xunyou(mod_map); register_youdao_dict(mod_map); register_youku_udp(mod_map); + register_yuanfudao(mod_map); register_yy_udp(mod_map); register_zalo_call(mod_map); register_zeroaccess_udp(mod_map); diff --git a/lib/tcp/Makefile.am b/lib/tcp/Makefile.am index df0833e4..21929d3a 100644 --- a/lib/tcp/Makefile.am +++ b/lib/tcp/Makefile.am @@ -170,6 +170,7 @@ libprotoident_tcp_la_SOURCES = \ lpi_qqlive_tcp.cc \ lpi_qqspeedmobile_tcp.cc \ lpi_qvod.cc \ + lpi_rabbitmq.cc \ lpi_razor.cc \ lpi_rbls.cc \ lpi_rdp.cc \ diff --git a/lib/tcp/lpi_rabbitmq.cc b/lib/tcp/lpi_rabbitmq.cc new file mode 100644 index 00000000..190204e7 --- /dev/null +++ b/lib/tcp/lpi_rabbitmq.cc @@ -0,0 +1,83 @@ +/* + * + * 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" + + +static inline bool match_amqp_header(uint32_t payload, uint32_t len) { + if (len == 8 && MATCH(payload, 'A', 'M', 'Q', 'P')) { + return true; + } + + return false; +} + +static inline bool match_amqp_start(uint32_t payload) { + /* only seen length 498 so far, but surely this could vary more */ + if (MATCH(payload, 0x01, 0x00, 0x00, 0x00)) { + return true; + } + + return false; +} + +static inline bool match_rabbitmq(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (data->server_port != 5672 && data->client_port != 5672) { + return false; + } + + if (match_amqp_header(data->payload[0], data->payload_len[0])) { + if (match_amqp_start(data->payload[1])) { + return true; + } + } + + if (match_amqp_header(data->payload[1], data->payload_len[1])) { + if (match_amqp_start(data->payload[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_rabbitmq = { + LPI_PROTO_RABBITMQ, + LPI_CATEGORY_MESSAGE_QUEUE, + "RabbitMQ", + 75, + match_rabbitmq +}; + +void register_rabbitmq(LPIModuleMap *mod_map) { + register_protocol(&lpi_rabbitmq, mod_map); +} + diff --git a/lib/tcp/tcp_protocols.h b/lib/tcp/tcp_protocols.h index cd646417..d5fc9a74 100644 --- a/lib/tcp/tcp_protocols.h +++ b/lib/tcp/tcp_protocols.h @@ -198,6 +198,7 @@ void register_qqdownload(LPIModuleMap *mod_map); void register_qqlive_tcp(LPIModuleMap *mod_map); void register_qqspeedmobile_tcp(LPIModuleMap *mod_map); void register_qvod(LPIModuleMap *mod_map); +void register_rabbitmq(LPIModuleMap *mod_map); void register_razor(LPIModuleMap *mod_map); void register_rbls(LPIModuleMap *mod_map); void register_rdp(LPIModuleMap *mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index 4e16a901..4a8c0063 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -31,6 +31,7 @@ libprotoident_udp_la_SOURCES = \ lpi_cirn.cc \ lpi_cisco_ipsec.cc \ lpi_cisco_sslvpn.cc \ + lpi_cloudflare_warp.cc \ lpi_cod.cc \ lpi_combatarms.cc \ lpi_combatarms_p2p.cc \ @@ -174,6 +175,7 @@ libprotoident_udp_la_SOURCES = \ lpi_risingstorm.cc \ lpi_roblox.cc \ lpi_robocraft.cc \ + lpi_rocket_league.cc \ lpi_rrshare.cc \ lpi_rtcp.cc \ lpi_rtmfp.cc \ @@ -230,6 +232,7 @@ libprotoident_udp_la_SOURCES = \ lpi_webex.cc \ lpi_wechat_udp.cc \ lpi_winmessage.cc \ + lpi_wireguard.cc \ lpi_wolfet.cc \ lpi_worm_22105.cc \ lpi_xfire_p2p.cc \ @@ -239,6 +242,7 @@ libprotoident_udp_la_SOURCES = \ lpi_xunyou.cc \ lpi_youdao_dict.cc \ lpi_youku.cc \ + lpi_yuanfudao.cc \ lpi_yy_udp.cc \ lpi_zalo_call.cc \ lpi_zeroaccess_udp.cc \ diff --git a/lib/udp/lpi_cloudflare_warp.cc b/lib/udp/lpi_cloudflare_warp.cc new file mode 100644 index 00000000..6ee6e9b8 --- /dev/null +++ b/lib/udp/lpi_cloudflare_warp.cc @@ -0,0 +1,115 @@ +/* + * + * 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" + +/* 01 == handshake begin */ +static inline bool match_warp_01(uint32_t payload, uint32_t len) { + + if (len != 148) { + return false; + } + + if (MATCH(payload, 0x01, ANY, ANY, ANY)) { + if (MATCH(payload, 0x01, 0x00, 0x00, 0x00)) { + return false; + } + return true; + } + return false; +} + +/* 02 == handshake reply */ +static inline bool match_warp_02(uint32_t payload, uint32_t len) { + + if (len != 92) { + return false; + } + + if (MATCH(payload, 0x02, ANY, ANY, ANY)) { + return true; + } + return false; +} + +/* 04 == data (for sessions where we missed part of the handshake */ +static inline bool match_warp_04(uint32_t payload, uint32_t len) { + + /* 100 is approximate, but 1312 seems to be an actual + * Max Datagram Size */ + if (len < 100 || len > 1312) { + return false; + } + + if (MATCH(payload, 0x04, ANY, ANY, ANY)) { + return true; + } + return false; +} + +static inline bool match_cloudflare_warp(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (data->server_port != 2408 && data->client_port != 2408) { + return false; + } + + if (match_warp_01(data->payload[0], data->payload_len[0])) { + if (match_warp_02(data->payload[1], data->payload_len[1])) { + return true; + } + if (match_warp_04(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_warp_01(data->payload[1], data->payload_len[1])) { + if (match_warp_02(data->payload[0], data->payload_len[0])) { + return true; + } + if (match_warp_04(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_cloudflare_warp = { + LPI_PROTO_UDP_CLOUDFLARE_WARP, + LPI_CATEGORY_TUNNELLING, + "CloudflareWarp", + 21, + match_cloudflare_warp +}; + +void register_cloudflare_warp(LPIModuleMap *mod_map) { + register_protocol(&lpi_cloudflare_warp, mod_map); +} + diff --git a/lib/udp/lpi_rocket_league.cc b/lib/udp/lpi_rocket_league.cc new file mode 100644 index 00000000..19471539 --- /dev/null +++ b/lib/udp/lpi_rocket_league.cc @@ -0,0 +1,79 @@ +/* + * + * 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" + +/* Not confirmed -- RL costs too much money -- but pretty certain */ + +static inline bool match_rl_1d(uint32_t payload, uint32_t len) { + + if (len == 115 && MATCH(payload, 0x1d, 0x01, 0x00, 0x00)) { + return true; + } + return false; +} + +static inline bool match_rl_1c(uint32_t payload, uint32_t len) { + + if (len == 93 && MATCH(payload, 0x1c, 0x01, 0x00, 0x00)) { + return true; + } + return false; +} + +static inline bool match_rocket_league(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_rl_1d(data->payload[0], data->payload_len[0])) { + if (match_rl_1c(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_rl_1c(data->payload[0], data->payload_len[0])) { + if (match_rl_1d(data->payload[1], data->payload_len[1])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_rocket_league = { + LPI_PROTO_UDP_ROCKET_LEAGUE, + LPI_CATEGORY_GAMING, + "RocketLeague", + 175, + match_rocket_league +}; + +void register_rocket_league(LPIModuleMap *mod_map) { + register_protocol(&lpi_rocket_league, mod_map); +} + diff --git a/lib/udp/lpi_wireguard.cc b/lib/udp/lpi_wireguard.cc new file mode 100644 index 00000000..50aa2fbb --- /dev/null +++ b/lib/udp/lpi_wireguard.cc @@ -0,0 +1,77 @@ +/* + * + * 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" + +static inline bool match_wg_first(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x01, 0x00, 0x00, 0x00) && len == 148) { + return true; + } + return false; +} + +static inline bool match_wg_second(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x02, 0x00, 0x00, 0x00) && len == 92) { + return true; + } + return false; +} + + +static inline bool match_wireguard(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_wg_first(data->payload[0], data->payload_len[0])) { + if (match_wg_second(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_wg_first(data->payload[1], data->payload_len[1])) { + if (match_wg_second(data->payload[0], data->payload_len[0])) { + return true; + } + } + + + return false; +} + +static lpi_module_t lpi_wireguard = { + LPI_PROTO_UDP_WIREGUARD, + LPI_CATEGORY_TUNNELLING, + "WireGuard", + 201, + match_wireguard +}; + +void register_wireguard(LPIModuleMap *mod_map) { + register_protocol(&lpi_wireguard, mod_map); +} + diff --git a/lib/udp/lpi_yuanfudao.cc b/lib/udp/lpi_yuanfudao.cc new file mode 100644 index 00000000..ef178573 --- /dev/null +++ b/lib/udp/lpi_yuanfudao.cc @@ -0,0 +1,79 @@ +/* + * + * 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" + +/* Unable to confirm because yuanfudao requires a Chinese mobile number */ + +static inline bool match_yuan_7b(uint32_t payload, uint32_t len) { + if (len == 33 && MATCH(payload, 0x80, 0x7b, 0x00, 0x00)) { + return true; + } + return false; +} + +static inline bool match_yuan_7c(uint32_t payload, uint32_t len) { + if (len == 32 || len == 48 || len == 60) { + if (MATCH(payload, 0x80, 0x7c, 0x00, 0x00)) { + return true; + } + } + return false; +} + +static inline bool match_yuanfudao(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_yuan_7b(data->payload[0], data->payload_len[0])) { + if (match_yuan_7c(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_yuan_7b(data->payload[1], data->payload_len[1])) { + if (match_yuan_7c(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_yuanfudao = { + LPI_PROTO_UDP_YUANFUDAO, + LPI_CATEGORY_STREAMING, + "Yuanfudao", + 79, + match_yuanfudao +}; + +void register_yuanfudao(LPIModuleMap *mod_map) { + register_protocol(&lpi_yuanfudao, mod_map); +} + diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index cb80294d..37d781af 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -62,6 +62,7 @@ void register_chivalry(LPIModuleMap *mod_map); void register_cirn(LPIModuleMap *mod_map); void register_cisco_ipsec(LPIModuleMap *mod_map); void register_cisco_sslvpn(LPIModuleMap *mod_map); +void register_cloudflare_warp(LPIModuleMap *mod_map); void register_combatarms(LPIModuleMap *mod_map); void register_combatarms_p2p(LPIModuleMap *mod_map); void register_contract_wars(LPIModuleMap *mod_map); @@ -203,6 +204,7 @@ void register_real(LPIModuleMap *mod_map); void register_risingstorm(LPIModuleMap *mod_map); void register_roblox(LPIModuleMap *mod_map); void register_robocraft(LPIModuleMap *mod_map); +void register_rocket_league(LPIModuleMap *mod_map); void register_rrshare(LPIModuleMap *mod_map); void register_rtcp(LPIModuleMap *mod_map); void register_rtmfp(LPIModuleMap *mod_map); @@ -260,6 +262,7 @@ void register_warthunder(LPIModuleMap *mod_map); void register_webex(LPIModuleMap *mod_map); void register_wechat_udp(LPIModuleMap *mod_map); void register_winmessage(LPIModuleMap *mod_map); +void register_wireguard(LPIModuleMap *mod_map); void register_wolfet(LPIModuleMap *mod_map); void register_worm_22105(LPIModuleMap *mod_map); void register_xfire_p2p(LPIModuleMap *mod_map); @@ -269,6 +272,7 @@ void register_xunlei_udp(LPIModuleMap *mod_map); void register_xunyou(LPIModuleMap *mod_map); void register_youdao_dict(LPIModuleMap *mod_map); void register_youku_udp(LPIModuleMap *mod_map); +void register_yuanfudao(LPIModuleMap *mod_map); void register_yy_udp(LPIModuleMap *mod_map); void register_zalo_call(LPIModuleMap *mod_map); void register_zeroaccess_udp(LPIModuleMap *mod_map); From 04f4423f760b07e3e019e0f6dbd4bd1ed14fc5b4 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Mon, 30 Sep 2019 16:21:57 +1300 Subject: [PATCH 12/27] Improve several protocol rules: * Dahua TCP * Wechat * Forticlient SSL VPN * Netcat CCTV UDP * QVod UDP * RTP * Second Life * Smite --- lib/tcp/lpi_dahua_tcp.cc | 15 +++++++++++++-- lib/tcp/lpi_wechat.cc | 4 +++- lib/udp/lpi_forticlient_sslvpn.cc | 10 ++++++++++ lib/udp/lpi_netcat_cctv_udp.cc | 2 +- lib/udp/lpi_qvod_udp.cc | 6 ++++++ lib/udp/lpi_rtp.cc | 2 ++ lib/udp/lpi_second_life.cc | 2 ++ lib/udp/lpi_smite.cc | 3 +-- 8 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/tcp/lpi_dahua_tcp.cc b/lib/tcp/lpi_dahua_tcp.cc index db12e26a..8e308bb6 100644 --- a/lib/tcp/lpi_dahua_tcp.cc +++ b/lib/tcp/lpi_dahua_tcp.cc @@ -32,6 +32,17 @@ /* Chinese IP surveillance Cameras */ +static inline bool match_dahua_ports(uint16_t sport, uint16_t cport) { + if (sport == 8888 || cport == 8888) { + return true; + } + + if (sport == 37777 || cport == 37777) { + return true; + } + return false; +} + static inline bool match_f4_186(uint32_t payload, uint32_t len) { if (len == 186 && MATCH(payload, 0xf4, 0x00, 0x00, 0x00)) return true; @@ -40,7 +51,7 @@ static inline bool match_f4_186(uint32_t payload, uint32_t len) { } static inline bool match_f4_208(uint32_t payload, uint32_t len) { - if (len == 186 && MATCH(payload, 0xf4, 0x00, 0x00, 0x58)) + if (len >= 206 && len <= 208 && MATCH(payload, 0xf4, 0x00, 0x00, 0x58)) return true; return false; @@ -48,7 +59,7 @@ static inline bool match_f4_208(uint32_t payload, uint32_t len) { static inline bool match_dahua(lpi_data_t *data, lpi_module_t *mod UNUSED) { - if (data->server_port != 8888 && data->client_port != 8888) { + if (!match_dahua_ports(data->server_port, data->client_port)) { return false; } diff --git a/lib/tcp/lpi_wechat.cc b/lib/tcp/lpi_wechat.cc index 6f1a6b3a..9784355a 100644 --- a/lib/tcp/lpi_wechat.cc +++ b/lib/tcp/lpi_wechat.cc @@ -133,7 +133,7 @@ static inline bool match_wechat(lpi_data_t *data, lpi_module_t *mod UNUSED) { * This is not unique to WeChat though, so we need to be careful. */ - /* Only observed on port 80, 443, 14000 or 8080. Because the payload + /* Only observed on port 80, 443, 14000, 10001 or 8080. Because the payload * signature is not entirely unique to WeChat, let's restrict matches * to flows using those ports unless it shows up on other ports. */ @@ -145,6 +145,8 @@ static inline bool match_wechat(lpi_data_t *data, lpi_module_t *mod UNUSED) { valid_port = true; if (data->server_port == 14000 || data->client_port == 14000) valid_port = true; + if (data->server_port == 10001 || data->client_port == 10001) + valid_port = true; if (!valid_port) return false; diff --git a/lib/udp/lpi_forticlient_sslvpn.cc b/lib/udp/lpi_forticlient_sslvpn.cc index 5f052892..60583b13 100644 --- a/lib/udp/lpi_forticlient_sslvpn.cc +++ b/lib/udp/lpi_forticlient_sslvpn.cc @@ -44,17 +44,27 @@ static inline bool match_forti_vpn(uint32_t payload, uint32_t len) { return false; } +static inline bool match_forti_fd_99(uint32_t payload, uint32_t len) { + if (len == 99 && MATCHSTR(payload, "\x16\xfe\xfd\x00")) + return true; + return false; +} + static inline bool match_forticlient_sslvpn(lpi_data_t *data, lpi_module_t *mod UNUSED) { if (match_forti_vpn_48(data->payload[0], data->payload_len[0])) { if (match_forti_vpn(data->payload[1], data->payload_len[1])) return true; + if (match_forti_fd_99(data->payload[1], data->payload_len[1])) + return true; } if (match_forti_vpn_48(data->payload[1], data->payload_len[1])) { if (match_forti_vpn(data->payload[0], data->payload_len[0])) return true; + if (match_forti_fd_99(data->payload[0], data->payload_len[0])) + return true; } return false; diff --git a/lib/udp/lpi_netcat_cctv_udp.cc b/lib/udp/lpi_netcat_cctv_udp.cc index aa853340..4207e2b2 100644 --- a/lib/udp/lpi_netcat_cctv_udp.cc +++ b/lib/udp/lpi_netcat_cctv_udp.cc @@ -32,7 +32,7 @@ static inline bool match_xmip_header(uint32_t payload, uint32_t len) { if (MATCH(payload, 0x12, 0x20, 0xd0, 0x07)) { - if (len == 112 || len == 120 || len == 184) + if (len == 112 || len == 120 || len == 184 || len == 148) return true; } return false; diff --git a/lib/udp/lpi_qvod_udp.cc b/lib/udp/lpi_qvod_udp.cc index 5541ac81..78e7b708 100644 --- a/lib/udp/lpi_qvod_udp.cc +++ b/lib/udp/lpi_qvod_udp.cc @@ -48,6 +48,12 @@ static inline bool match_qvod_13(uint32_t payload, uint32_t len) { static inline bool match_qvod_udp(lpi_data_t *data, lpi_module_t *mod UNUSED) { + if (match_qvod_13(data->payload[0], data->payload_len[0])) { + if (match_qvod_13(data->payload[1], data->payload_len[1])) { + return true; + } + } + if (match_qvod_1(data->payload[0], data->payload_len[0])) { if (match_qvod_13(data->payload[1], data->payload_len[1])) { return true; diff --git a/lib/udp/lpi_rtp.cc b/lib/udp/lpi_rtp.cc index 19468946..6cc8802c 100644 --- a/lib/udp/lpi_rtp.cc +++ b/lib/udp/lpi_rtp.cc @@ -73,6 +73,8 @@ static inline bool match_rtp_80c9(uint32_t payload, uint32_t len) { static inline bool match_rtcp_report(uint32_t payload, uint32_t len) { if (len == 16 && MATCH(payload, 0x81, 0xcd, 0x00, 0x03)) return true; + if (len == 20 && MATCH(payload, 0x81, 0xcd, 0x00, 0x03)) + return true; if (len == 32 && MATCH(payload, 0x81, 0xc9, 0x00, 0x07)) return true; if (len == 36 && MATCH(payload, 0x81, 0xc9, 0x00, 0x07)) diff --git a/lib/udp/lpi_second_life.cc b/lib/udp/lpi_second_life.cc index 72a98475..0dc07bed 100644 --- a/lib/udp/lpi_second_life.cc +++ b/lib/udp/lpi_second_life.cc @@ -54,6 +54,7 @@ static inline bool match_second_life(lpi_data_t *data, lpi_module_t *mod UNUSED) if (MATCH(data->payload[1], ANY, 0x00, 0x00, 0x00)) { if (data->payload_len[1] < 15) return false; + return true; } } @@ -63,6 +64,7 @@ static inline bool match_second_life(lpi_data_t *data, lpi_module_t *mod UNUSED) if (MATCH(data->payload[0], ANY, 0x00, 0x00, 0x00)) { if (data->payload_len[0] < 15) return false; + return true; } } return false; diff --git a/lib/udp/lpi_smite.cc b/lib/udp/lpi_smite.cc index 9c00fe71..c18caa2c 100644 --- a/lib/udp/lpi_smite.cc +++ b/lib/udp/lpi_smite.cc @@ -36,8 +36,7 @@ static inline bool match_smite(lpi_data_t *data, lpi_module_t *mod UNUSED) { if (MATCH(data->payload[0], 0x01, 0x14, 0x00, 0x00)) { if (MATCH(data->payload[1], 0x01, 0x14, 0x00, 0x00)) { - if (data->payload_len[0] < 100 && data->payload_len[1] < 100) - return true; + return true; } } From 09eb7bd75974c021bf4e16271e13eed8055cfd76 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 4 Oct 2019 11:14:26 +1300 Subject: [PATCH 13/27] Add new protocol: Call of Duty Mobile --- lib/libprotoident.h | 1 + lib/proto_manager.cc | 1 + lib/udp/Makefile.am | 1 + lib/udp/lpi_codmobile.cc | 75 ++++++++++++++++++++++++++++++++++++++++ lib/udp/udp_protocols.h | 1 + 5 files changed, 79 insertions(+) create mode 100644 lib/udp/lpi_codmobile.cc diff --git a/lib/libprotoident.h b/lib/libprotoident.h index 5f33e7c2..de18fe8a 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -632,6 +632,7 @@ typedef enum { LPI_PROTO_UDP_ROCKET_LEAGUE, LPI_PROTO_UDP_CLOUDFLARE_WARP, LPI_PROTO_UDP_WIREGUARD, + LPI_PROTO_UDP_COD_MOBILE, /* Patterns that we can match, but do not know the protocol */ LPI_PROTO_REJECTION, /* All responses are 0x02 */ diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 31ce2128..43e2a1c1 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -382,6 +382,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_cisco_ipsec(mod_map); register_cisco_sslvpn(mod_map); register_cloudflare_warp(mod_map); + register_codmobile(mod_map); register_combatarms(mod_map); register_combatarms_p2p(mod_map); register_contract_wars(mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index 4a8c0063..a6812291 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -33,6 +33,7 @@ libprotoident_udp_la_SOURCES = \ lpi_cisco_sslvpn.cc \ lpi_cloudflare_warp.cc \ lpi_cod.cc \ + lpi_codmobile.cc \ lpi_combatarms.cc \ lpi_combatarms_p2p.cc \ lpi_contract_wars.cc \ diff --git a/lib/udp/lpi_codmobile.cc b/lib/udp/lpi_codmobile.cc new file mode 100644 index 00000000..b1daf2e6 --- /dev/null +++ b/lib/udp/lpi_codmobile.cc @@ -0,0 +1,75 @@ +/* + * + * 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" + +static inline bool match_cod_mob84(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x43, 0x01, 0xc0, 0x12) && len == 84) { + return true; + } + return false; +} + +static inline bool match_cod_mob12(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x43, 0x02, 0xc0, 0x00) && len == 12) { + return true; + } + return false; +} + +static inline bool match_codmobile(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_cod_mob84(data->payload[0], data->payload_len[0])) { + if (match_cod_mob12(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_cod_mob84(data->payload[1], data->payload_len[1])) { + if (match_cod_mob12(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_codmobile = { + LPI_PROTO_UDP_COD_MOBILE, + LPI_CATEGORY_GAMING, + "CallOfDuty_Mobile", + 15, + match_codmobile +}; + +void register_codmobile(LPIModuleMap *mod_map) { + register_protocol(&lpi_codmobile, mod_map); +} + diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index 37d781af..74c23966 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -63,6 +63,7 @@ void register_cirn(LPIModuleMap *mod_map); void register_cisco_ipsec(LPIModuleMap *mod_map); void register_cisco_sslvpn(LPIModuleMap *mod_map); void register_cloudflare_warp(LPIModuleMap *mod_map); +void register_codmobile(LPIModuleMap *mod_map); void register_combatarms(LPIModuleMap *mod_map); void register_combatarms_p2p(LPIModuleMap *mod_map); void register_contract_wars(LPIModuleMap *mod_map); From 536e1d4f19326ac10c9d2436bb7c92a36da2a2b8 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Mon, 7 Oct 2019 11:54:12 +1300 Subject: [PATCH 14/27] Update IPFS rule for new observed pattern --- lib/tcp/lpi_ipfs.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/tcp/lpi_ipfs.cc b/lib/tcp/lpi_ipfs.cc index 1b0ca9ae..23ab4d1c 100644 --- a/lib/tcp/lpi_ipfs.cc +++ b/lib/tcp/lpi_ipfs.cc @@ -48,6 +48,16 @@ static inline bool match_ipfs_single(uint32_t payload, uint32_t len) { return false; } +static inline bool match_ipfs_length(uint32_t payload, uint32_t len) { + uint32_t plen = ntohl(payload); + + /* Starting to see IPFS replies with a four byte length field */ + if (plen + 4 == len) { + return true; + } + return false; +} + static inline bool match_ipfs(lpi_data_t *data, lpi_module_t *mod UNUSED) { /* Port 4001 by default, but probably changeable */ @@ -56,11 +66,15 @@ static inline bool match_ipfs(lpi_data_t *data, lpi_module_t *mod UNUSED) { return true; if (match_ipfs_mu(data->payload[1], data->payload_len[1])) return true; + if (match_ipfs_length(data->payload[1], data->payload_len[1])) + return true; } if (match_ipfs_mu(data->payload[1], data->payload_len[1])) { if (match_ipfs_single(data->payload[0], data->payload_len[0])) return true; + if (match_ipfs_length(data->payload[0], data->payload_len[0])) + return true; } return false; From 0a08962fa0871a087177c4e963f0a54c0777ce23 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 18 Oct 2019 17:24:52 +1300 Subject: [PATCH 15/27] Update rules for 3 protocols: * Cloudflare Warp * Wireguard * Zalo UDP --- lib/udp/lpi_cloudflare_warp.cc | 16 ++++++++++++++- lib/udp/lpi_wireguard.cc | 37 ++++++++++++++++++++++++++++++++++ lib/udp/lpi_zalo_call.cc | 30 +++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/lib/udp/lpi_cloudflare_warp.cc b/lib/udp/lpi_cloudflare_warp.cc index 6ee6e9b8..2d222bb1 100644 --- a/lib/udp/lpi_cloudflare_warp.cc +++ b/lib/udp/lpi_cloudflare_warp.cc @@ -74,9 +74,23 @@ static inline bool match_warp_04(uint32_t payload, uint32_t len) { return false; } +static inline bool is_cf_warp_port(lpi_data_t *data) { + if (data->server_port == 2408 || data->client_port == 2408) { + return true; + } + if (data->server_port == 1701 || data->client_port == 1701) { + return true; + } + if (data->server_port == 500 || data->client_port == 500) { + return true; + } + return false; +} + + static inline bool match_cloudflare_warp(lpi_data_t *data, lpi_module_t *mod UNUSED) { - if (data->server_port != 2408 && data->client_port != 2408) { + if (!is_cf_warp_port(data)) { return false; } diff --git a/lib/udp/lpi_wireguard.cc b/lib/udp/lpi_wireguard.cc index 50aa2fbb..f64bb0be 100644 --- a/lib/udp/lpi_wireguard.cc +++ b/lib/udp/lpi_wireguard.cc @@ -45,20 +45,57 @@ static inline bool match_wg_second(uint32_t payload, uint32_t len) { } +static inline bool match_wg_midsession(uint32_t payload, uint32_t len) { + /* Not a very strong rule, but should only matter if the initial + * packets go missing. + */ + if (MATCH(payload, 0x04, 0x00, 0x00, 0x00)) { + if (len >= 92 && len <= 512) { + return true; + } + } +} + static inline bool match_wireguard(lpi_data_t *data, lpi_module_t *mod UNUSED) { if (match_wg_first(data->payload[0], data->payload_len[0])) { if (match_wg_second(data->payload[1], data->payload_len[1])) { return true; } + if (match_wg_midsession(data->payload[1], + data->payload_len[1])) { + return true; + } } if (match_wg_first(data->payload[1], data->payload_len[1])) { if (match_wg_second(data->payload[0], data->payload_len[0])) { return true; } + if (match_wg_midsession(data->payload[0], + data->payload_len[0])) { + return true; + } } + if (match_wg_second(data->payload[0], data->payload_len[0])) { + if (match_wg_midsession(data->payload[1], + data->payload_len[1])) { + return true; + } + } + + if (match_wg_second(data->payload[1], data->payload_len[1])) { + if (match_wg_midsession(data->payload[0], + data->payload_len[0])) { + return true; + } + } + + if (match_wg_midsession(data->payload[0], data->payload_len[0])) { + if (match_wg_midsession(data->payload[1], data->payload_len[1])) + return true; + } return false; } diff --git a/lib/udp/lpi_zalo_call.cc b/lib/udp/lpi_zalo_call.cc index 28bd747f..1d07777f 100644 --- a/lib/udp/lpi_zalo_call.cc +++ b/lib/udp/lpi_zalo_call.cc @@ -44,6 +44,24 @@ static inline bool match_zalo_pat(uint32_t payload, uint32_t len) { } +static inline bool match_zalo_185(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x01, 0x01, 0x00, 0x00)) { + if (len >= 180 && len <= 185) { + return true; + } + } + return false; +} + +static inline bool match_zalo_56(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x02, 0x01, 0x00, 0x00)) { + if (len >= 52 && len <= 56) { + return true; + } + } + return false; +} + static inline bool match_zalo_call(lpi_data_t *data, lpi_module_t *mod UNUSED) { if (match_zalo_pat(data->payload[0], data->payload_len[0])) { @@ -53,6 +71,18 @@ static inline bool match_zalo_call(lpi_data_t *data, lpi_module_t *mod UNUSED) { } } + if (match_zalo_185(data->payload[0], data->payload_len[0])) { + if (match_zalo_56(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_zalo_185(data->payload[1], data->payload_len[1])) { + if (match_zalo_56(data->payload[0], data->payload_len[0])) { + return true; + } + } + return false; } From b01175d88230a04329b3113f567803a1cda89bad Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 18 Oct 2019 17:25:23 +1300 Subject: [PATCH 16/27] Add 2 new protocols: Beam and ICEP --- lib/libprotoident.h | 2 ++ lib/proto_manager.cc | 2 ++ lib/tcp/Makefile.am | 2 ++ lib/tcp/lpi_beam.cc | 66 +++++++++++++++++++++++++++++++++++ lib/tcp/lpi_icep.cc | 77 +++++++++++++++++++++++++++++++++++++++++ lib/tcp/tcp_protocols.h | 2 ++ 6 files changed, 151 insertions(+) create mode 100644 lib/tcp/lpi_beam.cc create mode 100644 lib/tcp/lpi_icep.cc diff --git a/lib/libprotoident.h b/lib/libprotoident.h index de18fe8a..9b230386 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -394,6 +394,8 @@ typedef enum { LPI_PROTO_WEBEX_STUN, LPI_PROTO_RRTV, LPI_PROTO_RABBITMQ, + LPI_PROTO_ICEP, + LPI_PROTO_BEAM, /* UDP Protocols */ LPI_PROTO_UDP, diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 43e2a1c1..829fbb3e 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -82,6 +82,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_ares(mod_map); register_badbaidu(mod_map); register_baofeng_tcp(mod_map); + register_beam(mod_map); register_bitcoin(mod_map); register_bitextend(mod_map); register_bittorrent(mod_map); @@ -152,6 +153,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_https(mod_map); register_http_tunnel(mod_map); register_ica(mod_map); + register_icep(mod_map); register_id(mod_map); register_idrivesync(mod_map); register_ihexin(mod_map); diff --git a/lib/tcp/Makefile.am b/lib/tcp/Makefile.am index 21929d3a..625bac86 100644 --- a/lib/tcp/Makefile.am +++ b/lib/tcp/Makefile.am @@ -15,6 +15,7 @@ libprotoident_tcp_la_SOURCES = \ lpi_ares.cc \ lpi_badbaidu.cc \ lpi_baofeng_tcp.cc \ + lpi_beam.cc \ lpi_bitcoin.cc \ lpi_bitextend.cc \ lpi_bittorrent.cc \ @@ -85,6 +86,7 @@ libprotoident_tcp_la_SOURCES = \ lpi_https.cc \ lpi_http_tunnel.cc \ lpi_ica.cc \ + lpi_icep.cc \ lpi_id.cc \ lpi_idrivesync.cc \ lpi_ihexin.cc \ diff --git a/lib/tcp/lpi_beam.cc b/lib/tcp/lpi_beam.cc new file mode 100644 index 00000000..e9c64011 --- /dev/null +++ b/lib/tcp/lpi_beam.cc @@ -0,0 +1,66 @@ +/* + * + * 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" + +static inline bool match_bm(uint32_t payload, uint32_t len) { + if (len == 40 && MATCH(payload, 'B', 'm', 0x0a, 0x04)) { + return true; + } + return false; +} + +static inline bool match_beam(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (data->server_port != 8100 && data->client_port != 8100) { + return false; + } + + if (match_bm(data->payload[0], data->payload_len[0])) { + if (match_bm(data->payload[1], data->payload_len[1])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_beam = { + LPI_PROTO_BEAM, + LPI_CATEGORY_ECOMMERCE, + "Beam", + 25, + match_beam +}; + +void register_beam(LPIModuleMap *mod_map) { + register_protocol(&lpi_beam, mod_map); +} + diff --git a/lib/tcp/lpi_icep.cc b/lib/tcp/lpi_icep.cc new file mode 100644 index 00000000..1c0f7d87 --- /dev/null +++ b/lib/tcp/lpi_icep.cc @@ -0,0 +1,77 @@ +/* + * + * 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" + +/* Internet Communications Engine Protocol */ + +static inline bool match_icep_validate(uint32_t payload, uint32_t len) { + if (len == 14 && MATCHSTR(payload, "IceP")) { + return true; + } + return false; +} + +static inline bool match_icep_req(uint32_t payload, uint32_t len) { + if (MATCHSTR(payload, "IceP") && len >= 30) { + return true; + } + return false; +} + +static inline bool match_icep(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_icep_validate(data->payload[0], data->payload_len[0])) { + if (match_icep_req(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_icep_validate(data->payload[1], data->payload_len[1])) { + if (match_icep_req(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_icep = { + LPI_PROTO_ICEP, + LPI_CATEGORY_NAT, /* unsure about this one */ + "IceP", + 8, + match_icep +}; + +void register_icep(LPIModuleMap *mod_map) { + register_protocol(&lpi_icep, mod_map); +} + diff --git a/lib/tcp/tcp_protocols.h b/lib/tcp/tcp_protocols.h index d5fc9a74..4ab47f3c 100644 --- a/lib/tcp/tcp_protocols.h +++ b/lib/tcp/tcp_protocols.h @@ -43,6 +43,7 @@ void register_apple_push(LPIModuleMap *mod_map); void register_ares(LPIModuleMap *mod_map); void register_badbaidu(LPIModuleMap *mod_map); void register_baofeng_tcp(LPIModuleMap *mod_map); +void register_beam(LPIModuleMap *mod_map); void register_bitcoin(LPIModuleMap *mod_map); void register_bitextend(LPIModuleMap *mod_map); void register_bittorrent(LPIModuleMap *mod_map); @@ -113,6 +114,7 @@ void register_http_nonstandard(LPIModuleMap *mod_map); void register_https(LPIModuleMap *mod_map); void register_http_tunnel(LPIModuleMap *mod_map); void register_ica(LPIModuleMap *mod_map); +void register_icep(LPIModuleMap *mod_map); void register_id(LPIModuleMap *mod_map); void register_idrivesync(LPIModuleMap *mod_map); void register_ihexin(LPIModuleMap *mod_map); From 3adc65f24bb962b5f386cb867d7f6b88877e6536 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 1 Nov 2019 17:12:29 +1300 Subject: [PATCH 17/27] Updated two protocols: RRTV and OpenVPN --- lib/tcp/lpi_rrtv.cc | 2 +- lib/udp/lpi_openvpn.cc | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/tcp/lpi_rrtv.cc b/lib/tcp/lpi_rrtv.cc index fa5b59d9..a76e89d1 100644 --- a/lib/tcp/lpi_rrtv.cc +++ b/lib/tcp/lpi_rrtv.cc @@ -40,7 +40,7 @@ static inline bool match_rrtv_header(uint32_t payload, uint32_t len) { /* broad estimate based on what I've seen so far */ - if (len < 380 || len > 700) { + if (len < 380 || len > 900) { return false; } diff --git a/lib/udp/lpi_openvpn.cc b/lib/udp/lpi_openvpn.cc index 9ff68271..8e1af22b 100644 --- a/lib/udp/lpi_openvpn.cc +++ b/lib/udp/lpi_openvpn.cc @@ -50,6 +50,11 @@ static inline bool match_openvpn_handshake(uint32_t pl_a, uint32_t pl_b) { return true; } + if (MATCH(pl_a, 0x49, ANY, ANY, ANY)) { + if (MATCH(pl_b, 0x49, ANY, ANY, ANY)) + return true; + } + return false; } From 30ca461163950c8f6a58c39b6afd43f68948af7d Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Fri, 1 Nov 2019 17:12:56 +1300 Subject: [PATCH 18/27] Added two new protocols: Nvidia Gamestream and VHD P2P --- lib/libprotoident.h | 2 + lib/proto_manager.cc | 2 + lib/tcp/Makefile.am | 1 + lib/tcp/lpi_vhdp2p.cc | 62 +++++++++++++++++++++++ lib/tcp/tcp_protocols.h | 1 + lib/udp/Makefile.am | 1 + lib/udp/lpi_nvidia_gamestream.cc | 84 ++++++++++++++++++++++++++++++++ lib/udp/udp_protocols.h | 1 + 8 files changed, 154 insertions(+) create mode 100644 lib/tcp/lpi_vhdp2p.cc create mode 100644 lib/udp/lpi_nvidia_gamestream.cc diff --git a/lib/libprotoident.h b/lib/libprotoident.h index 9b230386..b9665e81 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -396,6 +396,7 @@ typedef enum { LPI_PROTO_RABBITMQ, LPI_PROTO_ICEP, LPI_PROTO_BEAM, + LPI_PROTO_VHDP2P, /* UDP Protocols */ LPI_PROTO_UDP, @@ -635,6 +636,7 @@ typedef enum { LPI_PROTO_UDP_CLOUDFLARE_WARP, LPI_PROTO_UDP_WIREGUARD, LPI_PROTO_UDP_COD_MOBILE, + LPI_PROTO_UDP_NVIDIA_GAMESTREAM, /* Patterns that we can match, but do not know the protocol */ LPI_PROTO_REJECTION, /* All responses are 0x02 */ diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 829fbb3e..1aed71e0 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -311,6 +311,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_twitch_irc(mod_map); register_utherverse(mod_map); register_vainglory(mod_map); + register_vhdp2p(mod_map); register_viber(mod_map); register_vmware(mod_map); register_vodlocker(mod_map); @@ -496,6 +497,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_ntp(mod_map); register_ntp_reflect(mod_map); register_nwn(mod_map); + register_nvidia_gamestream(mod_map); register_opaserv(mod_map); register_openvpn_udp(mod_map); register_orbit_udp(mod_map); diff --git a/lib/tcp/Makefile.am b/lib/tcp/Makefile.am index 625bac86..a3f1f977 100644 --- a/lib/tcp/Makefile.am +++ b/lib/tcp/Makefile.am @@ -244,6 +244,7 @@ libprotoident_tcp_la_SOURCES = \ lpi_twitch_irc.cc \ lpi_utherverse.cc \ lpi_vainglory.cc \ + lpi_vhdp2p.cc \ lpi_viber.cc \ lpi_vmware.cc \ lpi_vodlocker.cc \ diff --git a/lib/tcp/lpi_vhdp2p.cc b/lib/tcp/lpi_vhdp2p.cc new file mode 100644 index 00000000..a4d49f9d --- /dev/null +++ b/lib/tcp/lpi_vhdp2p.cc @@ -0,0 +1,62 @@ +/* + * + * 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" + +static inline bool match_vhd(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x13, 'v', 'h', 'd') && len < 150) { + return true; + } + return false; +} + +static inline bool match_vhdp2p(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_vhd(data->payload[0], data->payload_len[0])) { + if (match_vhd(data->payload[1], data->payload_len[1])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_vhdp2p = { + LPI_PROTO_VHDP2P, + LPI_CATEGORY_P2P, + "VHD_P2P", + 7, + match_vhdp2p +}; + +void register_vhdp2p(LPIModuleMap *mod_map) { + register_protocol(&lpi_vhdp2p, mod_map); +} + diff --git a/lib/tcp/tcp_protocols.h b/lib/tcp/tcp_protocols.h index 4ab47f3c..f23bbfbd 100644 --- a/lib/tcp/tcp_protocols.h +++ b/lib/tcp/tcp_protocols.h @@ -272,6 +272,7 @@ void register_twitcasting(LPIModuleMap *mod_map); void register_twitch_irc(LPIModuleMap *mod_map); void register_utherverse(LPIModuleMap *mod_map); void register_vainglory(LPIModuleMap *mod_map); +void register_vhdp2p(LPIModuleMap *mod_map); void register_viber(LPIModuleMap *mod_map); void register_vmware(LPIModuleMap *mod_map); void register_vodlocker(LPIModuleMap *mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index a6812291..60036d52 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -146,6 +146,7 @@ libprotoident_udp_la_SOURCES = \ lpi_ntp.cc \ lpi_ntp_reflect.cc \ lpi_nwn.cc \ + lpi_nvidia_gamestream.cc \ lpi_opaserv.cc \ lpi_openvpn.cc \ lpi_orbit.cc \ diff --git a/lib/udp/lpi_nvidia_gamestream.cc b/lib/udp/lpi_nvidia_gamestream.cc new file mode 100644 index 00000000..3a956b4a --- /dev/null +++ b/lib/udp/lpi_nvidia_gamestream.cc @@ -0,0 +1,84 @@ +/* + * + * 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" + +static inline bool match_gs_ping(uint32_t payload, uint32_t len) { + if (len == 4 && MATCHSTR(payload, "PING")) { + return true; + } + return false; +} + +static inline bool match_gs_rtp(uint32_t payload, uint32_t len) { + if (MATCH(payload, 0x80, 0x61, 0x00, 0x00)) { + if (len == 72) { + return true; + } + } + + if (MATCH(payload, 0x90, 0x67, 0x00, 0x00)) { + if (len == 1040) { + return true; + } + } + return false; +} + +static inline bool match_nvidia_gamestream(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_gs_ping(data->payload[0], data->payload_len[0])) { + if (match_gs_rtp(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_gs_ping(data->payload[1], data->payload_len[1])) { + if (match_gs_rtp(data->payload[0], data->payload_len[0])) { + return true; + } + } + + + return false; +} + +static lpi_module_t lpi_nvidia_gamestream = { + LPI_PROTO_UDP_NVIDIA_GAMESTREAM, + LPI_CATEGORY_GAMING, + "NVIDIAGamestream", + 99, + match_nvidia_gamestream +}; + +void register_nvidia_gamestream(LPIModuleMap *mod_map) { + register_protocol(&lpi_nvidia_gamestream, mod_map); +} + diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index 74c23966..a0f4200f 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -175,6 +175,7 @@ void register_norton(LPIModuleMap *mod_map); void register_ntp(LPIModuleMap *mod_map); void register_ntp_reflect(LPIModuleMap *mod_map); void register_nwn(LPIModuleMap *mod_map); +void register_nvidia_gamestream(LPIModuleMap *mod_map); void register_opaserv(LPIModuleMap *mod_map); void register_openvpn_udp(LPIModuleMap *mod_map); void register_orbit_udp(LPIModuleMap *mod_map); From 15b77dcba5586e5c46f3703c9af6dfe724498769 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 7 Nov 2019 16:43:06 +1300 Subject: [PATCH 19/27] Add new protocols: ClassIn TCP and ClassIn UDP Also added new category: Educational Fixed missing printable string for Message Queuing category --- lib/libprotoident.cc | 4 ++ lib/libprotoident.h | 4 ++ lib/proto_manager.cc | 2 + lib/tcp/Makefile.am | 1 + lib/tcp/lpi_classin_tcp.cc | 75 ++++++++++++++++++++++++++++++++++++++ lib/tcp/tcp_protocols.h | 1 + lib/udp/Makefile.am | 1 + lib/udp/lpi_classin_udp.cc | 75 ++++++++++++++++++++++++++++++++++++++ lib/udp/udp_protocols.h | 1 + 9 files changed, 164 insertions(+) create mode 100644 lib/tcp/lpi_classin_tcp.cc create mode 100644 lib/udp/lpi_classin_udp.cc diff --git a/lib/libprotoident.cc b/lib/libprotoident.cc index 797f56c8..ba7d631f 100644 --- a/lib/libprotoident.cc +++ b/lib/libprotoident.cc @@ -439,6 +439,10 @@ const char *lpi_print_category(lpi_category_t category) { return "Mobile App"; case LPI_CATEGORY_IPCAMERAS: return "IP Cameras"; + case LPI_CATEGORY_EDUCATIONAL: + return "Educational"; + case LPI_CATEGORY_MESSAGE_QUEUE: + return "Message_Queuing"; case LPI_CATEGORY_ICMP: return "ICMP"; case LPI_CATEGORY_MIXED: diff --git a/lib/libprotoident.h b/lib/libprotoident.h index b9665e81..87e09b89 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -107,6 +107,8 @@ typedef enum { LPI_CATEGORY_ICS, /* Industrial control system protocols */ LPI_CATEGORY_IPCAMERAS, /* IP Surveillance Camera protocols */ LPI_CATEGORY_MESSAGE_QUEUE, /* Message queuing protocols */ + LPI_CATEGORY_EDUCATIONAL, /* Educational applications, e.g. virtual + classrooms */ LPI_CATEGORY_ICMP, /* ICMP */ LPI_CATEGORY_MIXED, /* Different protos in each direction */ LPI_CATEGORY_NOPAYLOAD, /* No payload observed */ @@ -397,6 +399,7 @@ typedef enum { LPI_PROTO_ICEP, LPI_PROTO_BEAM, LPI_PROTO_VHDP2P, + LPI_PROTO_CLASSIN, /* UDP Protocols */ LPI_PROTO_UDP, @@ -637,6 +640,7 @@ typedef enum { LPI_PROTO_UDP_WIREGUARD, LPI_PROTO_UDP_COD_MOBILE, LPI_PROTO_UDP_NVIDIA_GAMESTREAM, + LPI_PROTO_UDP_CLASSIN, /* Patterns that we can match, but do not know the protocol */ LPI_PROTO_REJECTION, /* All responses are 0x02 */ diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 1aed71e0..5f544684 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -95,6 +95,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) { register_chatango(mod_map); register_cisco_vpn(mod_map); register_clashofclans(mod_map); + register_classin_tcp(mod_map); register_clubbox(mod_map); register_cod_waw(mod_map); register_conquer(mod_map); @@ -384,6 +385,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_cirn(mod_map); register_cisco_ipsec(mod_map); register_cisco_sslvpn(mod_map); + register_classin_udp(mod_map); register_cloudflare_warp(mod_map); register_codmobile(mod_map); register_combatarms(mod_map); diff --git a/lib/tcp/Makefile.am b/lib/tcp/Makefile.am index a3f1f977..a13ae19b 100644 --- a/lib/tcp/Makefile.am +++ b/lib/tcp/Makefile.am @@ -28,6 +28,7 @@ libprotoident_tcp_la_SOURCES = \ lpi_chatango.cc \ lpi_cisco_vpn.cc \ lpi_clashofclans.cc \ + lpi_classin_tcp.cc \ lpi_clubbox.cc \ lpi_cod_waw.cc \ lpi_conquer.cc \ diff --git a/lib/tcp/lpi_classin_tcp.cc b/lib/tcp/lpi_classin_tcp.cc new file mode 100644 index 00000000..fcf9697b --- /dev/null +++ b/lib/tcp/lpi_classin_tcp.cc @@ -0,0 +1,75 @@ +/* + * + * 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" + +static inline bool match_classin_41(uint32_t payload, uint32_t len) { + if (len == 41 && MATCH(payload, 0x1a, 0x03, 0x00, 0x02)) { + return true; + } + return false; +} + +static inline bool match_classin_52(uint32_t payload, uint32_t len) { + if (len == 52 && MATCH(payload, 0x1a, 0x03, 0x00, 0x02)) { + return true; + } + return false; +} + +static inline bool match_classin_tcp(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_classin_41(data->payload[0], data->payload_len[0])) { + if (match_classin_52(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_classin_41(data->payload[1], data->payload_len[1])) { + if (match_classin_52(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_classin_tcp = { + LPI_PROTO_CLASSIN, + LPI_CATEGORY_EDUCATIONAL, + "ClassIn_TCP", + 133, + match_classin_tcp +}; + +void register_classin_tcp(LPIModuleMap *mod_map) { + register_protocol(&lpi_classin_tcp, mod_map); +} + diff --git a/lib/tcp/tcp_protocols.h b/lib/tcp/tcp_protocols.h index f23bbfbd..ca30b72a 100644 --- a/lib/tcp/tcp_protocols.h +++ b/lib/tcp/tcp_protocols.h @@ -56,6 +56,7 @@ void register_cgp(LPIModuleMap *mod_map); void register_chatango(LPIModuleMap *mod_map); void register_cisco_vpn(LPIModuleMap *mod_map); void register_clashofclans(LPIModuleMap *mod_map); +void register_classin_tcp(LPIModuleMap *mod_map); void register_clubbox(LPIModuleMap *mod_map); void register_cod_waw(LPIModuleMap *mod_map); void register_conquer(LPIModuleMap *mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index 60036d52..7b74f9ab 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -31,6 +31,7 @@ libprotoident_udp_la_SOURCES = \ lpi_cirn.cc \ lpi_cisco_ipsec.cc \ lpi_cisco_sslvpn.cc \ + lpi_classin_udp.cc \ lpi_cloudflare_warp.cc \ lpi_cod.cc \ lpi_codmobile.cc \ diff --git a/lib/udp/lpi_classin_udp.cc b/lib/udp/lpi_classin_udp.cc new file mode 100644 index 00000000..656b752b --- /dev/null +++ b/lib/udp/lpi_classin_udp.cc @@ -0,0 +1,75 @@ +/* + * + * 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" + +static inline bool match_classin_41(uint32_t payload, uint32_t len) { + if (len == 41 && MATCH(payload, 0x1a, 0x03, 0x00, 0x02)) { + return true; + } + return false; +} + +static inline bool match_classin_56(uint32_t payload, uint32_t len) { + if (len == 56 && MATCH(payload, 0x1a, 0x03, 0x00, 0x02)) { + return true; + } + return false; +} + +static inline bool match_classin_udp(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_classin_41(data->payload[0], data->payload_len[0])) { + if (match_classin_56(data->payload[1], data->payload_len[1])) { + return true; + } + } + + if (match_classin_41(data->payload[1], data->payload_len[1])) { + if (match_classin_56(data->payload[0], data->payload_len[0])) { + return true; + } + } + + return false; +} + +static lpi_module_t lpi_classin_udp = { + LPI_PROTO_UDP_CLASSIN, + LPI_CATEGORY_EDUCATIONAL, + "ClassIn_UDP", + 133, + match_classin_udp +}; + +void register_classin_udp(LPIModuleMap *mod_map) { + register_protocol(&lpi_classin_udp, mod_map); +} + diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index a0f4200f..1f2bbbf6 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -62,6 +62,7 @@ void register_chivalry(LPIModuleMap *mod_map); void register_cirn(LPIModuleMap *mod_map); void register_cisco_ipsec(LPIModuleMap *mod_map); void register_cisco_sslvpn(LPIModuleMap *mod_map); +void register_classin_udp(LPIModuleMap *mod_map); void register_cloudflare_warp(LPIModuleMap *mod_map); void register_codmobile(LPIModuleMap *mod_map); void register_combatarms(LPIModuleMap *mod_map); From 99af784ba6bd517e4854ffbb805b02bedd019de6 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 7 Nov 2019 16:43:48 +1300 Subject: [PATCH 20/27] Improved rule for SpeedIn --- lib/tcp/lpi_speedin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tcp/lpi_speedin.cc b/lib/tcp/lpi_speedin.cc index fc78667b..0b5831a8 100644 --- a/lib/tcp/lpi_speedin.cc +++ b/lib/tcp/lpi_speedin.cc @@ -41,7 +41,7 @@ static inline bool match_speedin_3byte(uint32_t payload, uint32_t len) { } static inline bool match_speedin_other(uint32_t payload, uint32_t len) { - if (len <= 75 || len >= 135) + if (len <= 75 || len >= 137) return false; if (MATCH(payload, 0x23, 0x00, ANY, ANY)) From ec076c78f49ba96e4b1dd5ee3fa38fb454ba28a1 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 7 Nov 2019 17:49:48 +1300 Subject: [PATCH 21/27] Fix missing return statement in Wireguard rule --- lib/udp/lpi_wireguard.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/udp/lpi_wireguard.cc b/lib/udp/lpi_wireguard.cc index f64bb0be..8ad6b1a0 100644 --- a/lib/udp/lpi_wireguard.cc +++ b/lib/udp/lpi_wireguard.cc @@ -54,6 +54,7 @@ static inline bool match_wg_midsession(uint32_t payload, uint32_t len) { return true; } } + return false; } static inline bool match_wireguard(lpi_data_t *data, lpi_module_t *mod UNUSED) { From a8fc4398eb16d13a6338b3833e43904b0fe299c5 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 7 Nov 2019 17:50:10 +1300 Subject: [PATCH 22/27] lpi_arff: fix bug where output line could be truncated --- tools/arff/lpi_arff.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/arff/lpi_arff.cc b/tools/arff/lpi_arff.cc index a078ef8b..ada48d72 100644 --- a/tools/arff/lpi_arff.cc +++ b/tools/arff/lpi_arff.cc @@ -258,7 +258,7 @@ char *display_ident(Flow *f, IdentFlow *ident, struct globalopts *opts) f->id.get_server_ip_str(s_ip); f->id.get_client_ip_str(c_ip); - str = (char *)malloc(750); + str = (char *)malloc(1000); dump_len_stats(&ident->out, len_stats_out, 200); dump_len_stats(&ident->in, len_stats_in, 200); @@ -266,7 +266,7 @@ char *display_ident(Flow *f, IdentFlow *ident, struct globalopts *opts) dump_iat_stats(&ident->in, iat_stats_in, 200); /* basic statistics */ - snprintf(str, 749, + snprintf(str, 999, "%s,%d,%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 "%s%s%s%s,%.0f,%f\n", proto->name, f->id.get_protocol(), From bb1b17c916352e36c24cf36875ed0300326e0247 Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Thu, 7 Nov 2019 17:50:37 +1300 Subject: [PATCH 23/27] Fix "too many arguments" warning when compiling find_unknown tool --- tools/find_unknown/lpi_find_unknown.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/find_unknown/lpi_find_unknown.cc b/tools/find_unknown/lpi_find_unknown.cc index 2bb7a7f7..58a019d6 100644 --- a/tools/find_unknown/lpi_find_unknown.cc +++ b/tools/find_unknown/lpi_find_unknown.cc @@ -167,7 +167,7 @@ void dump_payload(lpi_data_t lpi, uint8_t dir, char *space, int spacelen) { if (*pl > 32 && *pl < 126) { snprintf(ascii[i], 5, "%c", *pl); } else { - snprintf(ascii[i], 5, ".", NULL); + snprintf(ascii[i], 5, "."); } pl ++; } From 39f86e30aaa2db3046cf10387323eacb96bdd359 Mon Sep 17 00:00:00 2001 From: Jacob van Walraven Date: Tue, 19 Nov 2019 16:54:34 +1300 Subject: [PATCH 24/27] add lpi_get_protocol_by_name() function (#31) * Added `lpi_get_protocol_by_name()` function to get a lpi_protocol_t from a protocol string name. --- lib/libprotoident.cc | 22 +++++++++++++++++++--- lib/libprotoident.h | 8 ++++++++ lib/proto_manager.cc | 16 ++++++++++------ lib/proto_manager.h | 7 ++++--- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/lib/libprotoident.cc b/lib/libprotoident.cc index ba7d631f..ef9418bc 100644 --- a/lib/libprotoident.cc +++ b/lib/libprotoident.cc @@ -50,6 +50,7 @@ lpi_module_t *lpi_unknown_tcp = NULL; lpi_module_t *lpi_unknown_udp = NULL; static LPINameMap lpi_names; +static LPIProtocolMap lpi_protocols; static int seq_cmp (uint32_t seq_a, uint32_t seq_b) { @@ -78,10 +79,10 @@ int lpi_init_library() { if (register_udp_protocols(&UDP_protocols) == -1) return -1; - init_other_protocols(&lpi_names); + init_other_protocols(&lpi_names, &lpi_protocols); - register_names(&TCP_protocols, &lpi_names); - register_names(&UDP_protocols, &lpi_names); + register_names(&TCP_protocols, &lpi_names, &lpi_protocols); + register_names(&UDP_protocols, &lpi_names, &lpi_protocols); init_called = true; @@ -476,6 +477,21 @@ const char *lpi_print(lpi_protocol_t proto) { } +lpi_protocol_t lpi_get_protocol_by_name(char *name) { + + LPIProtocolMap::iterator it; + + it = lpi_protocols.find(name); + + if (it == lpi_protocols.end()) { + return LPI_PROTO_LAST; + } + + return (it->second); +} + + + bool lpi_is_protocol_inactive(lpi_protocol_t proto) { LPINameMap::iterator it; diff --git a/lib/libprotoident.h b/lib/libprotoident.h index 87e09b89..9a12224a 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -788,6 +788,14 @@ const char *lpi_print_category(lpi_category_t category); */ lpi_module_t *lpi_guess_protocol(lpi_data_t *data); +/** Given the protocol name, returns the lpi protcol it matches. + * + * @param name The protocol name + * + * @returns The LPI protocol for the supplied name. + */ +lpi_protocol_t lpi_get_protocol_by_name(char *name); + /** Determines whether the protocol matching a given protocol number is no * longer supported by libprotoident. * diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 5f544684..7d681cf4 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -606,28 +606,29 @@ int register_udp_protocols(LPIModuleMap *mod_map) { return 0; } -static void register_list_names(LPIModuleList *ml, LPINameMap *names) { +static void register_list_names(LPIModuleList *ml, LPINameMap *names, LPIProtocolMap *protos) { LPIModuleList::iterator it; for (it = ml->begin(); it != ml->end(); it ++) { lpi_module_t *mod = *it; (*names)[mod->protocol] = mod->name; + (*protos)[std::string(mod->name)] = mod->protocol; } } -void register_names(LPIModuleMap *mods, LPINameMap *names) { +void register_names(LPIModuleMap *mods, LPINameMap *names, LPIProtocolMap *protocols) { LPIModuleMap::iterator it; for (it = mods->begin(); it != mods->end(); it ++) { - register_list_names(it->second, names); + register_list_names(it->second, names, protocols); } } -void init_other_protocols(LPINameMap *name_map) { +void init_other_protocols(LPINameMap *name_map, LPIProtocolMap *proto_map) { lpi_icmp = new lpi_module_t; @@ -637,6 +638,7 @@ void init_other_protocols(LPINameMap *name_map) { lpi_icmp->priority = 255; lpi_icmp->lpi_callback = NULL; (*name_map)[lpi_icmp->protocol] = lpi_icmp->name; + (*proto_map)[std::string(lpi_icmp->name)] = lpi_icmp->protocol; lpi_unknown_tcp = new lpi_module_t; @@ -646,7 +648,8 @@ void init_other_protocols(LPINameMap *name_map) { lpi_unknown_tcp->priority = 255; lpi_unknown_tcp->lpi_callback = NULL; (*name_map)[lpi_unknown_tcp->protocol] = lpi_unknown_tcp->name; - + (*proto_map)[std::string(lpi_unknown_tcp->name)] = lpi_unknown_tcp->protocol; + lpi_unknown_udp = new lpi_module_t; lpi_unknown_udp->protocol = LPI_PROTO_UDP; @@ -655,6 +658,7 @@ void init_other_protocols(LPINameMap *name_map) { lpi_unknown_udp->priority = 255; lpi_unknown_udp->lpi_callback = NULL; (*name_map)[lpi_unknown_udp->protocol] = lpi_unknown_udp->name; + (*proto_map)[std::string(lpi_unknown_udp->name)] = lpi_unknown_udp->protocol; lpi_unsupported = new lpi_module_t; @@ -664,6 +668,6 @@ void init_other_protocols(LPINameMap *name_map) { lpi_unsupported->priority = 255; lpi_unsupported->lpi_callback = NULL; (*name_map)[lpi_unsupported->protocol] = lpi_unsupported->name; - + (*proto_map)[std::string(lpi_unsupported->name)] = lpi_unsupported->protocol; } diff --git a/lib/proto_manager.h b/lib/proto_manager.h index 7dd03aac..5ef4499d 100644 --- a/lib/proto_manager.h +++ b/lib/proto_manager.h @@ -31,19 +31,20 @@ #include #include #include +#include #include "libprotoident.h" - typedef std::list LPIModuleList; typedef std::map LPIModuleMap; typedef std::map LPINameMap; +typedef std::map LPIProtocolMap; void register_protocol(lpi_module_t *mod, LPIModuleMap *mod_map); int register_tcp_protocols(LPIModuleMap *mod_map); int register_udp_protocols(LPIModuleMap *mod_map); -void register_names(LPIModuleMap *mod_map, LPINameMap *name_map); -void init_other_protocols(LPINameMap *name_map); +void register_names(LPIModuleMap *mod_map, LPINameMap *name_map, LPIProtocolMap *proto_map); +void init_other_protocols(LPINameMap *name_map, LPIProtocolMap *proto_map); void free_protocols(LPIModuleMap *mod_map); From fb7787e3314bd55758afc4d32100b1a0f542a97c Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Wed, 20 Nov 2019 14:06:03 +1300 Subject: [PATCH 25/27] Rename Roblox to Raknet Roblox uses the Raknet protocol, as does a number of other games so it is better for us to label that traffic according to the underlying protocol. --- lib/libprotoident.h | 2 +- lib/proto_manager.cc | 2 +- lib/udp/Makefile.am | 2 +- lib/udp/{lpi_roblox.cc => lpi_raknet.cc} | 26 ++++++++++++------------ lib/udp/udp_protocols.h | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) rename lib/udp/{lpi_roblox.cc => lpi_raknet.cc} (69%) diff --git a/lib/libprotoident.h b/lib/libprotoident.h index 9a12224a..1acbb4d9 100644 --- a/lib/libprotoident.h +++ b/lib/libprotoident.h @@ -521,7 +521,7 @@ typedef enum { LPI_PROTO_UDP_SPOTIFY_BROADCAST, LPI_PROTO_UDP_MDNS, /* Multicast DNS */ LPI_PROTO_UDP_FASP, - LPI_PROTO_UDP_ROBLOX, + LPI_PROTO_UDP_RAKNET, LPI_PROTO_UDP_OPENVPN, LPI_PROTO_UDP_NOE, /* Alcatel's New Office Environment */ LPI_PROTO_UDP_VIBER, diff --git a/lib/proto_manager.cc b/lib/proto_manager.cc index 7d681cf4..445f6a79 100644 --- a/lib/proto_manager.cc +++ b/lib/proto_manager.cc @@ -528,7 +528,7 @@ int register_udp_protocols(LPIModuleMap *mod_map) { register_rdp_udp(mod_map); register_real(mod_map); register_risingstorm(mod_map); - register_roblox(mod_map); + register_raknet(mod_map); register_robocraft(mod_map); register_rocket_league(mod_map); register_rrshare(mod_map); diff --git a/lib/udp/Makefile.am b/lib/udp/Makefile.am index 7b74f9ab..86315e65 100644 --- a/lib/udp/Makefile.am +++ b/lib/udp/Makefile.am @@ -176,7 +176,7 @@ libprotoident_udp_la_SOURCES = \ lpi_rdp_udp.cc \ lpi_real.cc \ lpi_risingstorm.cc \ - lpi_roblox.cc \ + lpi_raknet.cc \ lpi_robocraft.cc \ lpi_rocket_league.cc \ lpi_rrshare.cc \ diff --git a/lib/udp/lpi_roblox.cc b/lib/udp/lpi_raknet.cc similarity index 69% rename from lib/udp/lpi_roblox.cc rename to lib/udp/lpi_raknet.cc index 25fcfb5f..e33f05f2 100644 --- a/lib/udp/lpi_roblox.cc +++ b/lib/udp/lpi_raknet.cc @@ -30,7 +30,7 @@ #include "proto_manager.h" #include "proto_common.h" -static inline bool match_roblox_out(uint32_t payload, uint32_t len) { +static inline bool match_raknet_out(uint32_t payload, uint32_t len) { if (MATCHSTR(payload, "\x05\x00\xff\xff")) return true; @@ -38,7 +38,7 @@ static inline bool match_roblox_out(uint32_t payload, uint32_t len) { } -static inline bool match_roblox_in(uint32_t payload, uint32_t len) { +static inline bool match_raknet_in(uint32_t payload, uint32_t len) { if (len != 28) return false; @@ -48,29 +48,29 @@ static inline bool match_roblox_in(uint32_t payload, uint32_t len) { } -static inline bool match_roblox(lpi_data_t *data, lpi_module_t *mod UNUSED) { +static inline bool match_raknet(lpi_data_t *data, lpi_module_t *mod UNUSED) { - if (match_roblox_out(data->payload[0], data->payload_len[0])) { - if (match_roblox_in(data->payload[1], data->payload_len[1])) + if (match_raknet_out(data->payload[0], data->payload_len[0])) { + if (match_raknet_in(data->payload[1], data->payload_len[1])) return true; } - if (match_roblox_out(data->payload[1], data->payload_len[1])) { - if (match_roblox_in(data->payload[0], data->payload_len[0])) + if (match_raknet_out(data->payload[1], data->payload_len[1])) { + if (match_raknet_in(data->payload[0], data->payload_len[0])) return true; } return false; } -static lpi_module_t lpi_roblox = { - LPI_PROTO_UDP_ROBLOX, +static lpi_module_t lpi_raknet = { + LPI_PROTO_UDP_RAKNET, LPI_CATEGORY_GAMING, - "Roblox", + "Raknet", 7, - match_roblox + match_raknet }; -void register_roblox(LPIModuleMap *mod_map) { - register_protocol(&lpi_roblox, mod_map); +void register_raknet(LPIModuleMap *mod_map) { + register_protocol(&lpi_raknet, mod_map); } diff --git a/lib/udp/udp_protocols.h b/lib/udp/udp_protocols.h index 1f2bbbf6..5d2ac41b 100644 --- a/lib/udp/udp_protocols.h +++ b/lib/udp/udp_protocols.h @@ -205,7 +205,7 @@ void register_ramsey_dash(LPIModuleMap *mod_map); void register_rdp_udp(LPIModuleMap *mod_map); void register_real(LPIModuleMap *mod_map); void register_risingstorm(LPIModuleMap *mod_map); -void register_roblox(LPIModuleMap *mod_map); +void register_raknet(LPIModuleMap *mod_map); void register_robocraft(LPIModuleMap *mod_map); void register_rocket_league(LPIModuleMap *mod_map); void register_rrshare(LPIModuleMap *mod_map); From 6186edbb6d9f9348ef101957fbe774b9ff5c659d Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Wed, 20 Nov 2019 14:07:13 +1300 Subject: [PATCH 26/27] Updated TCP Steam to include matches for VT01 traffic --- lib/tcp/lpi_steam.cc | 51 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/tcp/lpi_steam.cc b/lib/tcp/lpi_steam.cc index 27e51910..6c68bf74 100644 --- a/lib/tcp/lpi_steam.cc +++ b/lib/tcp/lpi_steam.cc @@ -30,7 +30,7 @@ #include "proto_manager.h" #include "proto_common.h" -static inline bool match_steam(lpi_data_t *data, lpi_module_t *mod UNUSED) { +static inline bool match_old_steam(lpi_data_t *data) { /* Steam TCP Download */ @@ -57,11 +57,58 @@ static inline bool match_steam(lpi_data_t *data, lpi_module_t *mod UNUSED) { return false; } +static inline bool match_steam_len(uint32_t payload, uint32_t len) { + + /* length is stored as a little-endian integer */ +#if BYTE_ORDER == BIG_ENDIAN + uint32_t plen = bswap32(payload); +#else + uint32_t plen = payload; +#endif + + if (plen == len - 8) { + return true; + } + return false; +} + +static inline bool match_steam_vt01(lpi_data_t *data) { + + /* I imagine other ports are possible? */ + + if (data->server_port != 27050 && data->client_port != 27050) { + return false; + } + + /* Observed length pairs so far: + * 150, 76 + */ + + if (match_steam_len(data->payload[0], data->payload_len[0])) { + if (match_steam_len(data->payload[1], data->payload_len[1])) { + return true; + } + } + + return false; +} + +static inline bool match_steam(lpi_data_t *data, lpi_module_t *mod UNUSED) { + + if (match_old_steam(data)) + return true; + if (match_steam_vt01(data)) { + return true; + } + return false; +} + + static lpi_module_t lpi_steam = { LPI_PROTO_STEAM, LPI_CATEGORY_GAMING, "Steam_TCP", - 4, /* Might not be as reliable as some other rules (?) */ + 104, /* Might not be as reliable as some other rules (?) */ match_steam }; From f7f3d69e2c47b136e05aff887cea2ddb7cd5b6ca Mon Sep 17 00:00:00 2001 From: Shane Alcock Date: Wed, 20 Nov 2019 14:16:01 +1300 Subject: [PATCH 27/27] Bump version to 2.0.14 --- README | 3 ++- configure.ac | 2 +- debian/changelog | 14 ++++++++++++++ lib/Makefile.am | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README b/README index 70b6999a..7af4cfac 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -libprotoident 2.0.13 +libprotoident 2.0.14 --------------------------------------------------------------------------- Copyright (c) 2011-2019 The University of Waikato, Hamilton, New Zealand. @@ -27,6 +27,7 @@ With contributions from: Jeroen Roovers Jiri Havranek Romain Fontugne + Jacob van Walraven Introduction ============ diff --git a/configure.ac b/configure.ac index 53908496..1d444c7d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(libprotoident, 2.0.13, contact@wand.net.nz) +AC_INIT(libprotoident, 2.0.14, contact@wand.net.nz) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR(lib/libprotoident.cc) diff --git a/debian/changelog b/debian/changelog index e0a792cc..76512708 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +libprotoident (2.0.14-1) unstable; urgency=low + + * New upstream release. + * Added new API method: lpi_get_protocol_by_name(). + * Fixed bug where lpi_print_category() would fail for the message + queuing category. + * Renamed "Roblox" to "Raknet" to better reflect the real underlying + protocol. + * Added new protocol category for educational applications. + * Added 17 new application protocols. + * Improved rules for a further 17 application protocols. + + -- Shane Alcock Wed, 20 Nov 2019 14:11:21 +1300 + libprotoident (2.0.13) unstable; urgency=low * New upstream release diff --git a/lib/Makefile.am b/lib/Makefile.am index dfd47999..bb1867fd 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -10,5 +10,5 @@ libprotoident_la_SOURCES=libprotoident.h libprotoident.cc \ INCLUDES=@ADD_INCLS@ libprotoident_la_LIBADD = @ADD_LIBS@ tcp/libprotoident_tcp.la \ udp/libprotoident_udp.la -libprotoident_la_LDFLAGS = @ADD_LDFLAGS@ -version-info 2:13:0 +libprotoident_la_LDFLAGS = @ADD_LDFLAGS@ -version-info 3:0:1 libprotoident_la_CPPFLAGS = -Werror