what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

core-sdi.rsaref

core-sdi.rsaref
Posted Dec 2, 1999
Site core-sdi.com

Core/SDI discovered a second buffer overflow in the implmementation of the RSA algorithm in RSAREF2 from RSA Data Security. This advisory addresses the details of the bug discovered, the details are somewhat focused on the ability to exploit the bug in SSH compiled with RSAREF2, but its extensible to any software product that uses RSAREF2.

tags | overflow
SHA-256 | 527168062ffc62dfc807ebe43c1e9bb63bab56ab4c45d4ed0623b4acd4bf4dcc

core-sdi.rsaref

Change Mirror Download



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

-
------------------------------------------------------------------------


CORE SDI S.A.
Buenos Aires, Argentina
<http://www.core-sdi.com>


CORE SDI Security Advisory
December 1st., 1999

Buffer overflow in RSAREF2

-
-------------------------------------------------------------------------

While researching the exploitability of a buffer overflow in
SSH up to version 1.2.27, we discovered a second buffer overflow
in the implmementation of the RSA algorithm in RSAREF2 from
RSA Data Security.
This advisory addresses the details of the bug discovered,
the details are somewhat focused on the ability to exploit the bug
in SSH compiled with RSAREF2, but its extensible to any software product
that uses RSAREF2


Problem description
~~~~~~~~~~~~~~~~~~~~

RSAREF2 API exports 4 functions in rsa.c:

int RSAPublicEncrypt()
int RSAPrivateEncrypt()
int RSAPublicDecrypt()
int RSAPrivateDecrypt()

The 4 functions define a local variable pkcsBlock of fixed length
MAX_RSA_MODULUS_LEN (128 bytes)

In order to perform the RSA operations, the functions call the internal
functions
RSAPrivateBlock() and RSAPublicBlock().

RSAPrivateDecrypt() and RSAPublicDecrypt() pass a pointer to the local
variable pkcsBlock to be used as the output buffer for RSAPublicBlock()
and RSAPrivateBlock() respectively. The two functions then perform the
RSA
operations and copy the results to the output buffer using the
NN_Encode()
and NN_Decode() functions.

Lack of strict bounds checking and proper validation of input parameters
in
all these functions allows an attacker to overflow the pkcsBLock
variable and
overwrite the stack, making it possible to execute arbitrary commands on
the
vulnerable system.


Technical details
~~~~~~~~~~~~~~~~~
As an axample we will describe the vulnerability focusing on the decrypt
operations performed in RSAREF2 based on the private key. Such
operations are
done with the function RSAPrivateDecrypt() defined as follows in rsa.c:

/* RSA private-key decryption, according to PKCS #1.
*/
int RSAPrivateDecrypt (output, outputLen, input, inputLen, privateKey)
unsigned char *output; /* output
block */
unsigned int *outputLen; /* length of output
block */
unsigned char *input; /* input
block */
unsigned int inputLen; /* length of input
block */
R_RSA_PRIVATE_KEY *privateKey; /* RSA private
key */
{
int status;
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
unsigned int i, modulusLen, pkcsBlockLen;

modulusLen = (privateKey->bits + 7) / 8;
if (inputLen > modulusLen)
return (RE_LEN);

if (status = RSAPrivateBlock
(pkcsBlock, &pkcsBlockLen, input, inputLen, privateKey))
return (status);

...


return (0);
}

Note that inputLen is checked against a transformation of privateKey's
bits
field, to satisfy this constrain an attacker must alter this field in
privateKey, but this, almost by miracle doesn't affect the final result.

Notese que se hace una verificacion sobre la longitud del buffer de
entrada,
comparandola con una transformacion del campo bits de la clave privada
(privateKey), para que esta validacion sea satisfecha es necesario
cambiar
este campo en privateKey, pero esto, casi milagrosamente no afecta al
resultado
de la encripcion.

As we can see, RSAPrivateDecrypt() calls RSAPrivateBlock() passing
pkcsBlock as
the output buffer, no length checking is performed to ensure that
pkcsBlock
will not be overrun. RSAPrivateBLock() performs the RSA private key
operations
ans is define as follows:

/* Raw RSA private-key operation. Output has same length as modulus.

Assumes inputLen < length of modulus.
Requires input < modulus.
*/
static int RSAPrivateBlock (output, outputLen, input, inputLen,
privateKey)
unsigned char *output; /* output
block */
unsigned int *outputLen; /* length of output
block */
unsigned char *input; /* input
block */
unsigned int inputLen; /* length of input
block */
R_RSA_PRIVATE_KEY *privateKey; /* RSA private
key */
{
NN_DIGIT c[MAX_NN_DIGITS], cP[MAX_NN_DIGITS], cQ[MAX_NN_DIGITS],
dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], mP[MAX_NN_DIGITS],
mQ[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS],
q[MAX_NN_DIGITS],
qInv[MAX_NN_DIGITS], t[MAX_NN_DIGITS];
unsigned int cDigits, nDigits, pDigits;

NN_Decode (c, MAX_NN_DIGITS, input, inputLen);
...
cDigits = NN_Digits (c, MAX_NN_DIGITS);
nDigits = NN_Digits (n, MAX_NN_DIGITS);
pDigits = NN_Digits (p, MAX_NN_DIGITS);

/* Compute mP = cP^dP mod p and mQ = cQ^dQ mod q. (Assumes q has
length at most pDigits, i.e., p > q.)
*/

...
/* Chinese Remainder Theorem:
m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ.
*/
if (NN_Cmp (mP, mQ, pDigits) >= 0)
NN_Sub (t, mP, mQ, pDigits);
else {
NN_Sub (t, mQ, mP, pDigits);
NN_Sub (t, p, t, pDigits);
}
NN_ModMult (t, t, qInv, p, pDigits);
NN_Mult (t, t, q, pDigits);
NN_Add (t, t, mQ, nDigits);

*outputLen = (privateKey->bits + 7) / 8;
NN_Encode (output, *outputLen, t, nDigits);

...

return (0);
}

RSAPrivateBlock() calls NN_Encode() to encode and copy the results into
the
output buffer (a pointer to the pkcsBlock variable in RSAPublicDecrypt()
function), the length of the output buffer is calculated based on the
bits
field of the pivateKey structure, passed originally to
RSAPublicDecrypt() and
does not take into account the fixed length characteristics of the
output
buffer.

The NN_Encode() function is defined as follows:


/* Encodes b into character string a, where character string is ordered
from most to least significant.

Lengths: a[len], b[digits].
Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant
digits are truncated.)
*/
void NN_Encode (a, len, b, digits)
NN_DIGIT *b;
unsigned char *a;
unsigned int digits, len;
{
NN_DIGIT t;
int j;
unsigned int i, u;

for (i = 0, j = len - 1; i < digits && j >= 0; i++) {
t = b[i];
for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
a[j] = (unsigned char)(t >> u);
}

for (; j >= 0; j--)
a[j] = 0;
}

NN_Encode() encodes and copies to 'a' (the output buffer, pkcsBLock)
'digits'
bytes of 'b' (the results of the RSA private key operation) from the end
to the
start of the buffer, starting at position 'len', the modulus length of
the
private key passed to RSAPrivateDecrypt().
Providing a suitable modulus length to RSAPrivateDecrypt() it is
possible to
force NN_Encode() to copy data beyond the bounds of pkcsBLock and
overwrite the
return address of RSAPRivateDecrypt(), gaining control of the processor
and
being able to execute code located elsewhere in the vulnerable program.

The exploitability of this bug in SSH comes from the fact that a bug in
SSH
itself <http://www.securityfocus.com/vdb/bottom.html?vid=797> discussed
and
published in the vuln-dev and bugtraq mailing lists, allows a remote
client to
provide a suitable private key to the RSAREF functions.

The same problem is present in the RSAPublicDecrypt() function, and its
exploitability might be even easier, since its much easier to provide a
malicious public key to any software package that supports RSA and uses
the
RSAREF2 implementation.


Impact
~~~~~~
It is possible to execute arbitrary commands as
the user that runs the RSAREF2 code.

For SSH up to 1.2.27 compiled with RSAREF2 this implies the
remote execution of arbitrary commands as root.


Fix information
~~~~~~~~~~~~~~~

RSA Security was contacted and replied that they don't support RSAREF2
anymore.
For futher details you may contact John Linn <jlinn@rsasecurity.com>

A patch is provided below, please read carefully the file license.txt
from the
RSAREF2 distribution before applying it


Vulnerable systems
~~~~~~~~~~~~~~~~~~
- - SSH up to 1.2.27 compiled with RSAREF2 (RSAREF is not compiled in by
default
but it's required in some cases in USA)
- - Possibly any other software packages that uses RSAREF2

Additional information
~~~~~~~~~~~~~~~~~~~~~~
This vulnerability was discovered by Alberto Solino
<asolino@core-sdi.com>
and Gerardo Richarte <gera@core-sdi.com> at Core SDI S.A.
<http://www.core-sdi.com>

Copyright Notice:
~~~~~~~~~~~~~~~~~
The contents of this advisory are copyright (c) 1999 CORE SDI S.A. and
may be
distributed freely provided that no fee is charged for this
distribution and
proper credit is given.

Fix
~~~

Copy de remining of this message to a file named rsaref.patch in
rsaref2/source, and apply with 'patch <rsaref.patch'

- --- rsa.original.c Wed Dec 1 11:29:57 1999
+++ rsa.c Wed Dec 1 11:45:51 1999
@@ -33,6 +33,8 @@
unsigned char byte, pkcsBlock[MAX_RSA_MODULUS_LEN];
unsigned int i, modulusLen;

+ if (inputLen+3>MAX_RSA_MODULUS_LEN) return (RE_LEN);
+
modulusLen = (publicKey->bits + 7) / 8;
if (inputLen + 11 > modulusLen)
return (RE_LEN);
@@ -78,6 +80,8 @@
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
unsigned int i, modulusLen, pkcsBlockLen;

+ if (inputLen>MAX_RSA_MODULUS_LEN) return (RE_LEN);
+
modulusLen = (publicKey->bits + 7) / 8;
if (inputLen > modulusLen)
return (RE_LEN);
@@ -129,6 +133,8 @@
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
unsigned int i, modulusLen;

+ if (inputLen+3>MAX_RSA_MODULUS_LEN) return (RE_LEN);
+
modulusLen = (privateKey->bits + 7) / 8;
if (inputLen + 11 > modulusLen)
return (RE_LEN);
@@ -168,6 +174,8 @@
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
unsigned int i, modulusLen, pkcsBlockLen;

+ if (inputLen>MAX_RSA_MODULUS_LEN) return (RE_LEN);
+
modulusLen = (privateKey->bits + 7) / 8;
if (inputLen > modulusLen)
return (RE_LEN);


-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv

iQA/AwUBOEXStUBPS1M5RMLQEQLf4QCg6kaXLdSnzgfbgVXztOD38MFTX7AAmwTG
F9dMkpeKR3EiiuDSCwi4tNrd
=NNXd
-----END PGP SIGNATURE-----

--- For a personal reply use gera@core-sdi.com
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    8 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    11 Files
  • 23
    Apr 23rd
    68 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close