Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/libprotoident.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ typedef enum {
LPI_PROTO_TRANSOCKS,
LPI_PROTO_RAGNAROK_ONLINE,
LPI_PROTO_ETHERNETIP,
LPI_PROTO_KERBEROS,
LPI_PROTO_RPC,

/* UDP Protocols */
LPI_PROTO_UDP,
Expand Down
8 changes: 8 additions & 0 deletions lib/proto_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ bool match_chars_either(lpi_data_t *data, char a, char b, char c,
return false;
}

bool match_chars_both(lpi_data_t *data, char a, char b, char c, char d) {
if (!MATCH(data->payload[0], a, b, c, d))
return false;
if (!MATCH(data->payload[1], a, b, c, d))
return false;
return true;
}

bool match_payload_length(uint32_t payload, uint32_t payload_len) {

uint32_t header = 0;
Expand Down
1 change: 1 addition & 0 deletions lib/proto_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ bool match_str_both(lpi_data_t *data, const char *string1,
const char *string2);
bool match_chars_either(lpi_data_t *data, char a, char b, char c,
char d);
bool match_chars_both(lpi_data_t *data, char a, char b, char c, char d);
bool match_payload_length(uint32_t payload, uint32_t payload_len);
bool match_ip_address_both(lpi_data_t *data);
bool match_file_header(uint32_t payload);
Expand Down
2 changes: 2 additions & 0 deletions lib/proto_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) {
register_kankan_tcp(mod_map);
register_kaseya(mod_map);
register_kaspersky(mod_map);
register_kerberos(mod_map);
register_kik(mod_map);
register_kingofglory_tcp(mod_map);
register_kuaibo(mod_map);
Expand Down Expand Up @@ -253,6 +254,7 @@ int register_tcp_protocols(LPIModuleMap *mod_map) {
register_remote_manipulator(mod_map);
register_revolver_nblbt(mod_map);
register_rfb(mod_map);
register_rpc(mod_map);
register_rpcscan(mod_map);
register_rrtv(mod_map);
register_rsync(mod_map);
Expand Down
2 changes: 2 additions & 0 deletions lib/tcp/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ libprotoident_tcp_la_SOURCES = \
lpi_kankan_tcp.cc \
lpi_kaseya.cc \
lpi_kaspersky.cc \
lpi_kerberos.cc \
lpi_kik.cc \
lpi_kingofglory_tcp.cc \
lpi_kuaibo.cc \
Expand Down Expand Up @@ -186,6 +187,7 @@ libprotoident_tcp_la_SOURCES = \
lpi_remote_manipulator.cc \
lpi_revolver_nblbt.cc \
lpi_rfb.cc \
lpi_rpc.cc \
lpi_rpcscan.cc \
lpi_rrtv.cc \
lpi_rsync.cc \
Expand Down
53 changes: 53 additions & 0 deletions lib/tcp/lpi_kerberos.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
*
* Copyright (c) 2011-2016 The University of Waikato, Hamilton, New Zealand.
* All rights reserved.
*
* This file is part of libprotoident.
*
* This code has been developed by the University of Waikato WAND
* research group. For further information please see http://www.wand.net.nz/
*
* libprotoident is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* libprotoident is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/

#include "libprotoident.h"
#include "proto_manager.h"
#include "proto_common.h"

static inline bool match_kerberos(lpi_data_t *data, lpi_module_t *mod UNUSED) {

/* Quite a weak rule, first 4 bytes of kerberos is the record length which
* is spread over multiple packets */

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also add a check that if the value of data->payload[x] < 1400, then it must match data->payload_size[x]? Or can small records still be spread across multiple packets?

Just trying to think of ways where we can rule out certain payload patterns that might just happen to be on port 88 -- very unlikely, I know, but anything to make this rule seem a bit stronger...

if (data->server_port == 88)
return true;

return false;
}

static lpi_module_t lpi_kerberos = {
LPI_PROTO_KERBEROS,
LPI_CATEGORY_KEY_EXCHANGE,
"Kerberos",
200,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this rule is so weak, I think the priority should be set to 250 just so it is run after any other possible matches.

match_kerberos
};

void register_kerberos(LPIModuleMap *mod_map) {
register_protocol(&lpi_kerberos, mod_map);
}

16 changes: 11 additions & 5 deletions lib/tcp/lpi_ldap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "proto_manager.h"
#include "proto_common.h"

static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {
static inline bool match_ldap_payload(uint32_t payload, uint32_t len, uint16_t server_port) {

uint8_t *byte = ((uint8_t *)&payload);
uint16_t struct_len = 0;
Expand All @@ -40,9 +40,10 @@ static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {

byte ++;

// multibyte lengths?
if (((*byte) & 0x80) == 0x80) {
uint8_t bytes_required = ((*byte) & 0x7f);
if (bytes_required > 2 || bytes_required == 0)
if (bytes_required == 0)
return false;

if (bytes_required == 1) {
Expand All @@ -52,10 +53,15 @@ static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {
struct_len = 3 + ((uint8_t)(*byte));
if (!MATCH(payload, 0x30, ANY, ANY, 0x02))
return false;
} else {
} else if (bytes_required == 2) {
struct_len = 4 + ntohs(*((uint16_t *)(byte + 1)));
if (!MATCH(payload, 0x30, ANY, ANY, ANY))
return false;
} else {
// the length is now past the first 4 bytes of payload so we are unable
// to check it, fallback to port in this case
if (server_port == 389)
return true;
}
} else {
if (!MATCH(payload, 0x30, ANY, 0x02, 0x01))
Expand All @@ -75,9 +81,9 @@ static inline bool match_ldap_payload(uint32_t payload, uint32_t len) {

static inline bool match_ldap(lpi_data_t *data, lpi_module_t *mod UNUSED) {

if (!match_ldap_payload(data->payload[0], data->payload_len[0]))
if (!match_ldap_payload(data->payload[0], data->payload_len[0], data->server_port))
return false;
if (!match_ldap_payload(data->payload[1], data->payload_len[1]))
if (!match_ldap_payload(data->payload[1], data->payload_len[1], data->server_port))
return false;

return true;
Expand Down
61 changes: 61 additions & 0 deletions lib/tcp/lpi_rpc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
*
* Copyright (c) 2011-2016 The University of Waikato, Hamilton, New Zealand.
* All rights reserved.
*
* This file is part of libprotoident.
*
* This code has been developed by the University of Waikato WAND
* research group. For further information please see http://www.wand.net.nz/
*
* libprotoident is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* libprotoident is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/

#include <string.h>

#include "libprotoident.h"
#include "proto_manager.h"
#include "proto_common.h"

#define PDU_TYPE(x) (data->payload[0] & 0xff0000) >> 16

static inline bool match_rpc(lpi_data_t *data, lpi_module_t *mod UNUSED) {

if (data->server_port != 135 && data->client_port != 135)
return false;

// valid PDUs are 0 - 19
if (PDU_TYPE(data->payload[0]) > 19 || PDU_TYPE(data->payload[1]) > 19)
return false;

if (match_chars_both(data, 0x05, 0x00, ANY, 0x03))
return true;

return false;
}

static lpi_module_t lpi_rpc = {
LPI_PROTO_RPC,
LPI_CATEGORY_SERVICES,
"RPC",
200,
match_rpc
};

void register_rpc(LPIModuleMap *mod_map) {
register_protocol(&lpi_rpc, mod_map);
}

2 changes: 2 additions & 0 deletions lib/tcp/tcp_protocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ void register_kakao(LPIModuleMap *mod_map);
void register_kankan_tcp(LPIModuleMap *mod_map);
void register_kaseya(LPIModuleMap *mod_map);
void register_kaspersky(LPIModuleMap *mod_map);
void register_kerberos(LPIModuleMap *mod_map);
void register_kik(LPIModuleMap *mod_map);
void register_kingofglory_tcp(LPIModuleMap *mod_map);
void register_kuaibo(LPIModuleMap *mod_map);
Expand Down Expand Up @@ -214,6 +215,7 @@ void register_relay(LPIModuleMap *mod_map);
void register_remote_manipulator(LPIModuleMap *mod_map);
void register_revolver_nblbt(LPIModuleMap *mod_map);
void register_rfb(LPIModuleMap *mod_map);
void register_rpc(LPIModuleMap *mod_map);
void register_rpcscan(LPIModuleMap *mod_map);
void register_rrtv(LPIModuleMap *mod_map);
void register_rsync(LPIModuleMap *mod_map);
Expand Down