mirror of
https://github.com/yrutschle/sslh.git
synced 2026-10-22 18:12:10 +03:00
probes: fix msrdp length truncation, teamspeak match, unaligned reads
- is_msrdp_protocol() stored the 16-bit TPKT length in a char, so a
packet claiming length 263 (0x0107) but carrying only 7 bytes
compared 7 == 7 and matched - any sufficiently short packet whose
declared length low byte equals its size is accepted as RDP.
Keep the declared length in a uint16_t. Verified with a harness:
{0x03 0x00 0x01 0x07 ...} no longer matches.
- is_teamspeak_protocol() used strncmp(p, "TS3INIT1", len): for the
first datagram of a real TS3 client (len > 8) this compares the
string literal's terminating NUL against packet byte 8, which is a
version field, so it could never match real traffic (and reads
past the literal for len > 9). Use a fixed 8-byte memcmp prefix.
- is_openvpn_protocol() and is_wireguard_protocol() dereferenced the
packet buffer through uint16_t*/uint32_t* casts; the buffer is not
aligned, which is UB and traps on strict-alignment targets (ARM).
Use memcpy() instead, as already done elsewhere in this file.
This commit is contained in:
1 parent
ca5e7fe6f3
commit
7cc9dc90be
1 file changed
+16
-6
@@ -156,7 +156,10 @@ static int is_openvpn_protocol (const char*p,ssize_t len, struct sslhcfg_protoco
|
||||
if (len < 2)
|
||||
return PROBE_AGAIN;
|
||||
|
||||
packet_len = ntohs(*(uint16_t*)p);
|
||||
/* p may be unaligned (e.g. on ARM), do not cast to uint16_t* */
|
||||
uint16_t wire_len;
|
||||
memcpy(&wire_len, p, sizeof(wire_len));
|
||||
packet_len = ntohs(wire_len);
|
||||
return packet_len == len - 2;
|
||||
} else {
|
||||
if (len < 1)
|
||||
@@ -205,7 +208,9 @@ static int is_wireguard_protocol(const char *p, ssize_t len, struct sslhcfg_prot
|
||||
return PROBE_NEXT;
|
||||
|
||||
// Handshake Init: p[0] = 0x01, p[1..3] = 0x000000 (reserved)
|
||||
if (ntohl(*(uint32_t*)p) != 0x01000000)
|
||||
uint32_t type;
|
||||
memcpy(&type, p, sizeof(type));
|
||||
if (ntohl(type) != 0x01000000)
|
||||
return PROBE_NEXT;
|
||||
|
||||
return PROBE_MATCH;
|
||||
@@ -407,20 +412,25 @@ static int is_teamspeak_protocol(const char *p, ssize_t len, struct sslhcfg_prot
|
||||
if (len < 8)
|
||||
return PROBE_NEXT;
|
||||
|
||||
return !strncmp(p, "TS3INIT1", len);
|
||||
/* Compare a fixed-length prefix: strncmp(p, "TS3INIT1", len) would read
|
||||
* len bytes of the 9-byte literal and never match a real packet, whose
|
||||
* byte 8 is not NUL */
|
||||
return !memcmp(p, "TS3INIT1", 8);
|
||||
}
|
||||
|
||||
static int is_msrdp_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
char version;
|
||||
char packet_len;
|
||||
uint16_t packet_len;
|
||||
if (len < 7)
|
||||
return PROBE_NEXT;
|
||||
version=*p;
|
||||
if (version!=0x03)
|
||||
return 0;
|
||||
packet_len = ntohs(*(uint16_t*)(p+2));
|
||||
return packet_len == len;
|
||||
memcpy(&packet_len, p+2, sizeof(packet_len));
|
||||
/* The declared TPKT length must fit the entire received packet; a char
|
||||
* would truncate e.g. 0x0107 to 7 and accept truncated packets */
|
||||
return ntohs(packet_len) == len;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_REGEX
|
||||
|
||||
Reference in new issue
Block a user