首页 -> 安全研究

安全研究

绿盟月刊
绿盟安全月刊->第18期->最新漏洞
期刊号: 类型: 关键词:
SSH1 守护程序crc32补偿攻击检测安全漏洞

日期:2001-02-05

受影响的系统:  
    - SSH 1.2.x (ssh.com) -- 所有最近的版本
    - F-SECURE SSH 1.3.x -- 所有最近的版本
    - OpenSSH  2.3.0以前版本 (除非SSH1协议被禁止)
    - OSSH 1.5.7 以及其他ssh1/OpenSSH系列守护程序

不受影响系统:  
    - SSH2 (ssh.com): 所有2.x版本
      注意:如果安装中带了对SSH1的支持,也受影响
    - OpenSSH 2.3.0  
    - SSH1 1.2.24 (此版本没有增加CRC攻击的检测代码)
    - Cisco SSH
    - LSH (不支持SSH1协议)

描述:
--------------------------------------------------------------------------------


BUGTRAQ ID : 2347
CVE ID: CAN-2001-0144

较新版本的ssh1守护程序中所带的一段代码中存在一个整数溢出问题。问题出在
deattack.c,此程序由CORE SDI开发,用来防止SSH1协议受到CRC32补偿攻击。

由于在detect_attack()函数中错误的将一个16位的无符号变量当成了32位变量
来使用,导致表索引溢出问题。

这将允许一个攻击者覆盖内存中的任意位置的内容,攻击者可能远程获取root权
限。

问题出在detect_attack()函数中:

...
/*
   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 word16 n = HASH_MINSIZE / HASH_ENTRYSIZE;
    register word32 i, j;
    word32 l;
...

n 被错误的定义为16位整数,因此攻击者可以设法导致其值为0,在进行完
xmalloc(0)分配后,将执行下列代码:
               for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;

由于i被设置为32位无符号整数,在n=0时,结果就变成了:
i = HASH(c) & 0xffffffff

而c可以由客户端提供。如果i的值超出了正常范围,程序在试图访问h[i]时将
会发生段错误。

通过精心构造攻击报文,攻击者可能覆盖任意地址的内容并远程执行任意代码。
攻击者不需要有效的系统帐号即可进行攻击。


<*来源:Michal Zalewski (lcamtuf@razor.bindview.com)
       相关链接:http://www.core-sdi.com/advisories/ssh1_deattack.htm
                 http://razor.bindview.com/publish/advisories/adv_ssh1crc.html
*>




测试程序:
--------------------------------------------------------------------------------

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!



$ ssh -v -l `perl -e '{print "A"x88000}'` localhost


Program received signal SIGSEGV, Segmentation fault.
0x806cfbd in detect_attack ( ..., len=88016, IV=0x0) at deattack.c:138
136                     for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;

We can inspect the table index (SEGV happened during h[i] != HASH_UNSIGNED comparsion):

(gdb) printf "%x\n",i



--------------------------------------------------------------------------------
建议:

临时解决方法:

如果您正在运行SSH2, 并允许兼容SSH1,NSFOCUS建议您暂时禁止SSH1.
Michal Zalewski (lcamtuf@razor.bindview.com)也提供了下
列的临时补丁程序:

SSH1 software:


8<---------------------patch for ssh-1.2.31---------------------------
--- deattack.c.orig Wed Feb 7 13:53:47 2001
+++ deattack.c Wed Feb 7 13:54:24 2001
@@ -79,7 +79,7 @@
detect_attack(unsigned char *buf, word32 len, unsigned char *IV)
{
   static word16 *h = (word16 *) NULL;
- static word16 n = HASH_MINSIZE / HASH_ENTRYSIZE;
+ static word32 n = HASH_MINSIZE / HASH_ENTRYSIZE;
   register word32 i, j;
   word32 l;
   register unsigned char *c;
8<---------------------patch for ssh-1.2.31---------------------------


Bjoern Groenvall's ossh (ftp://ftp.pdc.kth.se/pub/krypto/ossh/):


8<---------------------patch for ossh-1.5.7---------------------------
--- deattack.c.orig Wed Feb 7 14:11:23 2001
+++ deattack.c Wed Feb 7 14:11:46 2001
@@ -91,7 +91,7 @@
detect_attack(const unsigned char *buf, word32 len)
{
   static u_int16_t *h = (u_int16_t *) NULL;
- static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
+ static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
   register word32 i, j;
   word32 l;
   const unsigned char *c, *d;
8<---------------------patch for ossh-1.5.7---------------------------


OpenSSH 2.2.0:


8<-------------------patch for openssh-2.2.0--------------------------
--- deattack.c.orig Wed Feb 7 14:18:23 2001
+++ deattack.c Wed Feb 7 14:19:33 2001
@@ -84,7 +84,7 @@
detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV)
{
        static u_int16_t *h = (u_int16_t *) NULL;
- static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
+ static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
        register u_int32_t i, j;
        u_int32_t l;
        register unsigned char *c;
8<-------------------patch for openssh-2.2.0--------------------------

厂商补丁:

SSH :   SSH公司建议您升级到2.x版本并禁止兼容SSH1
         http://www.ssh.com
OpenSSH:升级到2.3.0获更高版本
         http://www.openssh.com

版权所有,未经许可,不得转载