Beispiel #1
0
/* Detect a crc32 compensation attack on a packet */
int
detect_attack(u_char *buf, u_int32_t len)
{
	static u_int16_t *h = (u_int16_t *) NULL;
	static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
	u_int32_t i, j;
	u_int32_t l, same;
	u_char *c;
	u_char *d;

	if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
	    len % SSH_BLOCKSIZE != 0) {
		fatal("detect_attack: bad length %d", len);
	}
	for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
		;

	if (h == NULL) {
		debug("Installing crc compensation attack detector.");
		h = (u_int16_t *) xcalloc(l, HASH_ENTRYSIZE);
		n = l;
	} else {
		if (l > n) {
			h = (u_int16_t *)xrealloc(h, l, HASH_ENTRYSIZE);
			n = l;
		}
	}

	if (len <= HASH_MINBLOCKS) {
		for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
			for (d = buf; d < c; d += SSH_BLOCKSIZE) {
				if (!CMP(c, d)) {
					if ((check_crc(c, buf, len)))
						return (DEATTACK_DETECTED);
					else
						break;
				}
			}
		}
		return (DEATTACK_OK);
	}
	memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE);

	for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
		for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
		    i = (i + 1) & (n - 1)) {
			if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
				if (++same > MAX_IDENTICAL)
					return (DEATTACK_DOS_DETECTED);
				if (check_crc(c, buf, len))
					return (DEATTACK_DETECTED);
				else
					break;
			}
		}
		h[i] = j;
	}
	return (DEATTACK_OK);
}
Beispiel #2
0
/* Detect a crc32 compensation attack on a packet */
int
detect_attack(struct deattack_ctx *dctx, const u_char *buf, u_int32_t len)
{
	u_int32_t i, j, l, same;
	const u_char *c, *d;

	if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
	    len % SSH_BLOCKSIZE != 0)
		return DEATTACK_ERROR;
	for (l = dctx->n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
		;

	if (dctx->h == NULL) {
		if ((dctx->h = calloc(l, HASH_ENTRYSIZE)) == NULL)
			return DEATTACK_ERROR;
		dctx->n = l;
	} else {
		if (l > dctx->n) {
			if (reallocn((void **)&dctx->h, l, HASH_ENTRYSIZE) != 0) {
				free(dctx->h);
				dctx->h = NULL;
				return DEATTACK_ERROR;
			}
			dctx->n = l;
		}
	}

	if (len <= HASH_MINBLOCKS) {
		for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
			for (d = buf; d < c; d += SSH_BLOCKSIZE) {
				if (!CMP(c, d)) {
					if ((check_crc(c, buf, len)))
						return DEATTACK_DETECTED;
					else
						break;
				}
			}
		}
		return DEATTACK_OK;
	}
	memset(dctx->h, HASH_UNUSEDCHAR, dctx->n * HASH_ENTRYSIZE);

	for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
		for (i = HASH(c) & (dctx->n - 1); dctx->h[i] != HASH_UNUSED;
		    i = (i + 1) & (dctx->n - 1)) {
			if (!CMP(c, buf + dctx->h[i] * SSH_BLOCKSIZE)) {
				if (++same > MAX_IDENTICAL)
					return DEATTACK_DOS_DETECTED;
				if (check_crc(c, buf, len))
					return DEATTACK_DETECTED;
				else
					break;
			}
		}
		dctx->h[i] = j;
	}
	return DEATTACK_OK;
}
Beispiel #3
0
/* Detect a crc32 compensation attack on a packet */
int detect_attack(uchar *buf, uint32 len, uchar *IV)
{
    static uint16 *h = (uint16 *) NULL;
    static uint32 n = HASH_MINSIZE / HASH_ENTRYSIZE;
    register uint32 i, j;
    uint32 l;
    register uchar *c;
    uchar *d;

    assert(!(len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
             len % SSH_BLOCKSIZE != 0));
    for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
        ;

    if (h == NULL) {
        logevent("Installing CRC compensation attack detector");
        n = l;
        h = (uint16 *) smalloc(n * HASH_ENTRYSIZE);
    } else {
        if (l > n) {
            n = l;
            h = (uint16 *) srealloc(h, n * HASH_ENTRYSIZE);
        }
    }

    if (len <= HASH_MINBLOCKS) {
        for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
            if (IV && (!CMP(c, IV))) {
                if ((check_crc(c, buf, len, IV)))
                    return 1;          /* attack detected */
                else
                    break;
            }
            for (d = buf; d < c; d += SSH_BLOCKSIZE) {
                if (!CMP(c, d)) {
                    if ((check_crc(c, buf, len, IV)))
                        return 1;      /* attack detected */
                    else
                        break;
                }
            }
        }
        return 0;                      /* ok */
    }
    memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE);

    if (IV)
        h[HASH(IV) & (n - 1)] = HASH_IV;

    for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
        for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
             i = (i + 1) & (n - 1)) {
            if (h[i] == HASH_IV) {
                if (!CMP(c, IV)) {
                    if (check_crc(c, buf, len, IV))
                        return 1;      /* attack detected */
                    else
                        break;
                }
            } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
                if (check_crc(c, buf, len, IV))
                    return 1;          /* attack detected */
                else
                    break;
            }
        }
        h[i] = j;
    }
    return 0;                          /* ok */
}
Beispiel #4
0
/*
   detect_attack
   Detects a crc32 compensation attack on a packet
 */
int detect_attack(unsigned char *buf, word32 len, unsigned char *IV)
{
    static word16 *h = (word16 *) NULL;
    static word32 n = HASH_MINSIZE / HASH_ENTRYSIZE;
    register word32 i, j;
    word32 l;
    register unsigned char *c;
    unsigned char *d;


    assert(len <= (SSH_MAXBLOCKS * SSH_BLOCKSIZE));
    assert(len % SSH_BLOCKSIZE == 0);

    for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2);

    if (h == NULL) {
        debug("Installing crc compensation attack detector.");
        n = l;
        h = (word16 *) xmalloc(n * sizeof(word16));
    } else {
        if (l > n) {
            n = l;
            h = (word16 *) xrealloc(h, n * sizeof(word16));
        }
    }


    if (len <= HASH_MINBLOCKS) {
        for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
            if (IV && (!CMP(c, IV))) {
                if ((check_crc(c, buf, len, IV)))
                    return (DEATTACK_DETECTED);
                else
                    break;
            }
            for (d = buf; d < c; d += SSH_BLOCKSIZE) {
                if (!CMP(c, d)) {
                    if ((check_crc(c, buf, len, IV)))
                        return (DEATTACK_DETECTED);
                    else
                        break;
                }
            }
        }
        return (DEATTACK_OK);
    }

    for (i = 0; i < n; i++)
        h[i] = HASH_UNUSED;

    if (IV)
        h[HASH(IV) & (n - 1)] = HASH_IV;


    for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
        for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; i = (i + 1) & (n - 1)) {
            if (h[i] == HASH_IV) {
                if (!CMP(c, IV)) {
                    if (check_crc(c, buf, len, IV))
                        return (DEATTACK_DETECTED);
                    else
                        break;
                }
            } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
                if (check_crc(c, buf, len, IV))
                    return (DEATTACK_DETECTED);
                else
                    break;
            }
        }
        h[i] = j;
    }

    return (DEATTACK_OK);
}