Add padding to cmdmon requests to prevent amplification attack

To prevent an attacker using chronyd in an amplification attack, change
the protocol to include padding in request packets so that the largest
possible reply is not larger than the request. Request packets that
don't include this padding are ignored as invalid.

This is an incompatible change in the protocol. Clients from chrony
1.27, 1.28 and 1.29 will receive NULL reply with STT_BADPKTVERSION and
print "Protocol version mismatch". Clients from 1.26 and older will not
receive a reply as it would be larger than the request if it was padded
to be compatible with their protocol.
This commit is contained in:
Miroslav Lichvar
2014-01-24 13:55:15 +01:00
parent 3e23430926
commit dba458d50c
5 changed files with 197 additions and 17 deletions

View File

@@ -265,11 +265,25 @@ prepare_socket(int family)
void
CAM_Initialise(int family)
{
int i;
assert(!initialised);
initialised = 1;
assert(sizeof (permissions) / sizeof (permissions[0]) == N_REQUEST_TYPES);
for (i = 0; i < N_REQUEST_TYPES; i++) {
CMD_Request r;
int command_length, padding_length;
r.version = PROTO_VERSION_NUMBER;
r.command = htons(i);
command_length = PKL_CommandLength(&r);
padding_length = PKL_CommandPaddingLength(&r);
assert(padding_length <= MAX_PADDING_LENGTH && padding_length <= command_length);
assert(command_length == 0 || command_length >= offsetof(CMD_Reply, data));
}
utoken = (unsigned long) time(NULL);
issued_tokens = returned_tokens = issue_pointer = 0;
@@ -1718,6 +1732,7 @@ read_from_cmd_socket(void *anything)
}
if (expected_length < offsetof(CMD_Request, data) ||
read_length < offsetof(CMD_Reply, data) ||
rx_message.pkt_type != PKT_TYPE_CMD_REQUEST ||
rx_message.res1 != 0 ||
rx_message.res2 != 0) {
@@ -1756,12 +1771,9 @@ read_from_cmd_socket(void *anything)
if (allowed)
CLG_LogCommandAccess(&remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT) {
if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) {
tx_message.status = htons(STT_BADPKTVERSION);
/* add empty MD5 auth so older clients will not drop
the reply due to bad length */
memset(((char *)&tx_message) + PKL_ReplyLength(&tx_message), 0, 16);
transmit_reply(&tx_message, &where_from, 16);
transmit_reply(&tx_message, &where_from, 0);
}
return;
}