Lines 30-35
Link Here
|
30 |
#include "crc32.h" |
30 |
#include "crc32.h" |
31 |
#include "misc.h" |
31 |
#include "misc.h" |
32 |
|
32 |
|
|
|
33 |
/* |
34 |
* CRC attack detection has a worst-case behaviour that is O(N^3) over |
35 |
* the number of identical blocks in a packet. This behaviour can be |
36 |
* exploited to create a limited denial of service attack. |
37 |
* |
38 |
* However, because we are dealing with encrypted data, identical |
39 |
* blocks should only occur every 2^35 maximally-sized packets or so. |
40 |
* Consequently, we can detect this DoS by looking for identical blocks |
41 |
* in a packet. |
42 |
* |
43 |
* The parameter below determines how many identical blocks we will |
44 |
* accept in a single packet, trading off between attack detection and |
45 |
* likelihood of terminating a legitimate connection. A value of 32 |
46 |
* corresponds to an average of 2^40 messages before an attack is |
47 |
* misdetected |
48 |
*/ |
49 |
#define MAX_IDENTICAL 32 |
50 |
|
33 |
/* SSH Constants */ |
51 |
/* SSH Constants */ |
34 |
#define SSH_MAXBLOCKS (32 * 1024) |
52 |
#define SSH_MAXBLOCKS (32 * 1024) |
35 |
#define SSH_BLOCKSIZE (8) |
53 |
#define SSH_BLOCKSIZE (8) |
Lines 85-91
Link Here
|
85 |
static u_int16_t *h = (u_int16_t *) NULL; |
103 |
static u_int16_t *h = (u_int16_t *) NULL; |
86 |
static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; |
104 |
static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; |
87 |
u_int32_t i, j; |
105 |
u_int32_t i, j; |
88 |
u_int32_t l; |
106 |
u_int32_t l, same; |
89 |
u_char *c; |
107 |
u_char *c; |
90 |
u_char *d; |
108 |
u_char *d; |
91 |
|
109 |
|
Lines 122-132
Link Here
|
122 |
if (IV) |
140 |
if (IV) |
123 |
h[HASH(IV) & (n - 1)] = HASH_IV; |
141 |
h[HASH(IV) & (n - 1)] = HASH_IV; |
124 |
|
142 |
|
125 |
for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { |
143 |
for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { |
126 |
for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; |
144 |
for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; |
127 |
i = (i + 1) & (n - 1)) { |
145 |
i = (i + 1) & (n - 1)) { |
128 |
if (h[i] == HASH_IV) { |
146 |
if (h[i] == HASH_IV) { |
129 |
if (!CMP(c, IV)) { |
147 |
if (!CMP(c, IV)) { |
|
|
148 |
if (++same > MAX_IDENTICAL) |
149 |
return (DEATTACK_DOS_DETECTED); |
130 |
if (check_crc(c, buf, len, IV)) |
150 |
if (check_crc(c, buf, len, IV)) |
131 |
return (DEATTACK_DETECTED); |
151 |
return (DEATTACK_DETECTED); |
132 |
else |
152 |
else |
Lines 991-999
Link Here
|
991 |
* (C)1998 CORE-SDI, Buenos Aires Argentina |
991 |
* (C)1998 CORE-SDI, Buenos Aires Argentina |
992 |
* Ariel Futoransky(futo@core-sdi.com) |
992 |
* Ariel Futoransky(futo@core-sdi.com) |
993 |
*/ |
993 |
*/ |
994 |
if (!receive_context.plaintext && |
994 |
if (!receive_context.plaintext) { |
995 |
detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED) |
995 |
switch (detect_attack(buffer_ptr(&input), padded_len, NULL)) { |
996 |
packet_disconnect("crc32 compensation attack: network attack detected"); |
996 |
case DEATTACK_DETECTED: |
|
|
997 |
packet_disconnect("crc32 compensation attack: " |
998 |
"network attack detected"); |
999 |
case DEATTACK_DOS_DETECTED: |
1000 |
packet_disconnect("deattack denial of " |
1001 |
"service detected"); |
1002 |
} |
1003 |
} |
997 |
|
1004 |
|
998 |
/* Decrypt data to incoming_packet. */ |
1005 |
/* Decrypt data to incoming_packet. */ |
999 |
buffer_clear(&incoming_packet); |
1006 |
buffer_clear(&incoming_packet); |
Lines 25-30
Link Here
|
25 |
/* Return codes */ |
25 |
/* Return codes */ |
26 |
#define DEATTACK_OK 0 |
26 |
#define DEATTACK_OK 0 |
27 |
#define DEATTACK_DETECTED 1 |
27 |
#define DEATTACK_DETECTED 1 |
|
|
28 |
#define DEATTACK_DOS_DETECTED 2 |
28 |
|
29 |
|
29 |
int detect_attack(u_char *, u_int32_t); |
30 |
int detect_attack(u_char *, u_int32_t); |
30 |
#endif |
31 |
#endif |