SSH 1.2.27 远程缓冲区溢出(RSAREF)
发布日期:1999-11-20
更新日期:1999-11-20
受影响系统:SSH 1.2.27
描述:
SSH 1.2.27 中的一个内部缓冲区存在溢出,可能会导致程序崩溃或执行溢出代码。不过此漏洞已在 2.0 及更高版本中打了补丁。
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
技术分析:
在 sshd.c,1513行中,从客户端获取一个整数值串,用于与服务器公共密钥和主机公共密钥一起生成会话密钥:
/* 获得加密后的整数串 */
mpz_init(&session_key_int);
packet_get_mp_int(&session_key_int);
该加密会话密钥(在大约第1525行)传递给函数 rsa_private_decrypt 进行第一次解密。使用服务器端私有密钥还是主机私有密钥,将取决于这两者谁的加密密度大。
rsa_private_decrypt( &session_key_int, &session_key_int,
&sensitive_data.private_key );
如果使用了 RSAREF (例如在代码中定义(defined)了 RSAREF),则 rsaglue.c 源代码中 rsa_private_decrypt 过程如下:
void rsa_private_decrypt(MP_INT *output, MP_INT *input, RSAPrivateKey
*key)
{
unsigned char input_data[MAX_RSA_MODULUS_LEN];
unsigned char output_data[MAX_RSA_MODULUS_LEN]
unsigned int input_len, output_len, input_bits;
[...]
input_bits = mpz_sizeinbase(input, 2);
input_len = (input_bits + 7) / 8;
gmp_to_rsaref(input_data, input_len, input);
[...]
}
问题出现在一个固定长度缓冲区 input_data[MAX_RSA_MODULUS_LEN]。该缓冲区的指针和加密会话密钥指针、加密会话密钥长度(input_len)将作为参数传递给转换函数 gmp_to_rsaref 。注意,加密会话密钥长度有可能超过 [MAX_RSA_MODULES_LEN]。但 gmp_to_rsaref(在 rsaglue.c 的79行)只是简单地调用函数 mp_linearize_msb_first(buf, len, varlue)。如下:
void gmp_to_rsaref(unsigned char *buf, unsigned int len, MP_INT *value)
{
mp_linearize_msb_first(buf, len, value);
}
mp_linearize_msb_first 函数的实现过程在 mpaux.c 的41行:
void mp_linearize_msb_first(unsigned char *buf, unsigned int len, MP_INT
*value)
{
unsigned int i;
MP_INT aux;
mpz_init_set(&aux, value);
for (i = len; i >= 4; i -= 4) <-------
{
unsigned long limb = mpz_get_ui(&aux);
PUT_32BIT(buf + i - 4, limb); <-------
mpz_div_2exp(&aux, &aux, 32);
}
[...]
}
溢出就发生在这里!len 是加密会话密钥的长度,而buf是固定长度数组缓冲区指针。但该函数没有检查 len 变量是否超过 MAX_RSA_MODULES_LEN 值。
可能的攻击:
在这个溢出里,客户端加密会话密钥可被用于进行溢出攻击。也就是说将 shellcode、NOP空指令和跳转地址作为加密会话密钥发送给服务器。 但是,由于最终被写入溢出缓冲区的数据必须是一串整数值(session_key_int),因此缓总区溢出攻击代码必须转换成不含非整数的形式。这虽然比较困难,但却是可能实现的。
建议:
最新版本的SSH服务器可从以下网址下载:
http://www.datafellows.com/products/cryptography/f-sshserver.htm
浏览次数:8088
严重程度:0(网友投票)