Add the CRC32 compensation attack detector that all other SSH

clients have had for ages and I forgot about. Of course I've got the
version with the buffer overflow fixed!

[originally from svn r1535]
This commit is contained in:
Simon Tatham 2002-01-08 11:57:32 +00:00
Родитель 349e2ce9e2
Коммит d237773599
10 изменённых файлов: 183 добавлений и 11 удалений

Просмотреть файл

@ -1,7 +1,8 @@
PuTTY is copyright 1997-2001 Simon Tatham.
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry.
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
and CORE SDI S.A.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files

Просмотреть файл

@ -115,9 +115,9 @@ MOBJ2 = tree234.$(OBJ)
COBJS = console.$(OBJ)
##-- objects putty pscp psftp plink
OBJS1 = sshcrc.$(OBJ) sshdes.$(OBJ) sshmd5.$(OBJ) sshrsa.$(OBJ) sshrand.$(OBJ)
OBJS2 = sshsha.$(OBJ) sshblowf.$(OBJ) noise.$(OBJ) sshdh.$(OBJ) sshdss.$(OBJ)
OBJS3 = sshbn.$(OBJ) sshpubk.$(OBJ) ssh.$(OBJ) pageantc.$(OBJ) sshzlib.$(OBJ)
OBJS4 = x11fwd.$(OBJ) portfwd.$(OBJ) sshaes.$(OBJ) sshsh512.$(OBJ)
OBJS2 = sshsha.$(OBJ) sshblowf.$(OBJ) noise.$(OBJ) sshdh.$(OBJ) sshcrcda.$(OBJ)
OBJS3 = sshpubk.$(OBJ) ssh.$(OBJ) pageantc.$(OBJ) sshzlib.$(OBJ) sshdss.$(OBJ)
OBJS4 = x11fwd.$(OBJ) portfwd.$(OBJ) sshaes.$(OBJ) sshsh512.$(OBJ) sshbn.$(OBJ)
##-- objects pageant
PAGE1 = pageant.$(OBJ) sshrsa.$(OBJ) sshpubk.$(OBJ) sshdes.$(OBJ) sshbn.$(OBJ)
PAGE2 = sshmd5.$(OBJ) version.$(OBJ) tree234.$(OBJ) misc.$(OBJ) sshaes.$(OBJ)

Просмотреть файл

@ -1,11 +1,12 @@
\versionid $Id: licence.but,v 1.1 2001/12/16 14:56:02 simon Exp $
\versionid $Id: licence.but,v 1.2 2002/01/08 11:57:32 simon Exp $
\A{licence} PuTTY Licence
PuTTY is copyright 1997-2001 Simon Tatham.
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry.
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
and CORE SDI S.A.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files

Просмотреть файл

@ -66,7 +66,7 @@ BEGIN
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
LTEXT "Barry.", 1003, 10, 42, 206, 8
LTEXT "Barry, and CORE SDI S.A.", 1003, 10, 42, 206, 8
LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8

Просмотреть файл

@ -59,7 +59,7 @@ BEGIN
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
LTEXT "Barry.", 1003, 10, 42, 206, 8
LTEXT "Barry, and CORE SDI S.A.", 1003, 10, 42, 206, 8
LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8

5
ssh.c
Просмотреть файл

@ -724,6 +724,11 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
st->to_read -= st->chunk;
}
if (cipher && detect_attack(pktin.data, st->biglen, NULL)) {
bombout(("Network attack (CRC compensation) detected!"));
crReturn(0);
}
if (cipher)
cipher->decrypt(pktin.data, st->biglen);

4
ssh.h
Просмотреть файл

@ -72,6 +72,10 @@ typedef unsigned int word32;
typedef unsigned int uint32;
unsigned long crc32(const void *s, size_t len);
unsigned long crc32_update(unsigned long crc_input, const void *s, size_t len);
/* SSH CRC compensation attack detector */
int detect_attack(unsigned char *buf, uint32 len, unsigned char *IV);
typedef struct {
uint32 h[4];

Просмотреть файл

@ -211,9 +211,8 @@ int main(void)
}
#endif
unsigned long crc32(const void *buf, size_t len)
unsigned long crc32_update(unsigned long crcword, const void *buf, size_t len)
{
unsigned long crcword = 0L;
const unsigned char *p = (const unsigned char *) buf;
while (len--) {
unsigned long newbyte = *p++;
@ -222,3 +221,8 @@ unsigned long crc32(const void *buf, size_t len)
}
return crcword;
}
unsigned long crc32(const void *buf, size_t len)
{
return crc32_update(0L, buf, len);
}

157
sshcrcda.c Normal file
Просмотреть файл

@ -0,0 +1,157 @@
/* $OpenBSD: deattack.c,v 1.14 2001/06/23 15:12:18 itojun Exp $ */
/*
* Cryptographic attack detector for ssh - source code
*
* Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
*
* All rights reserved. Redistribution and use in source and binary
* forms, with or without modification, are permitted provided that
* this copyright notice is retained.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
* CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
* SOFTWARE.
*
* Ariel Futoransky <futo@core-sdi.com>
* <http://www.core-sdi.com>
*
* Modified for use in PuTTY by Simon Tatham
*/
#include <assert.h>
#include "misc.h"
#include "ssh.h"
typedef unsigned char uchar;
typedef unsigned short uint16;
/* SSH Constants */
#define SSH_MAXBLOCKS (32 * 1024)
#define SSH_BLOCKSIZE (8)
/* Hashing constants */
#define HASH_MINSIZE (8 * 1024)
#define HASH_ENTRYSIZE (sizeof(uint16))
#define HASH_FACTOR(x) ((x)*3/2)
#define HASH_UNUSEDCHAR (0xff)
#define HASH_UNUSED (0xffff)
#define HASH_IV (0xfffe)
#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE)
#define GET_32BIT_MSB_FIRST(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
/* Hash function (Input keys are cipher results) */
#define HASH(x) GET_32BIT_MSB_FIRST(x)
#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE))
uchar ONE[4] = { 1, 0, 0, 0 };
uchar ZERO[4] = { 0, 0, 0, 0 };
static void crc_update(uint32 *a, void *b)
{
*a = crc32_update(*a, b, 4);
}
/* detect if a block is used in a particular pattern */
static int check_crc(uchar *S, uchar *buf, uint32 len, uchar *IV)
{
uint32 crc;
uchar *c;
crc = 0;
if (IV && !CMP(S, IV)) {
crc_update(&crc, ONE);
crc_update(&crc, ZERO);
}
for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
if (!CMP(S, c)) {
crc_update(&crc, ONE);
crc_update(&crc, ZERO);
} else {
crc_update(&crc, ZERO);
crc_update(&crc, ZERO);
}
}
return (crc == 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 */
}

Просмотреть файл

@ -87,7 +87,7 @@ BEGIN
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
LTEXT "Barry.", 1003, 10, 42, 206, 8
LTEXT "Barry, and CORE SDI S.A.", 1003, 10, 42, 206, 8
LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8