(current->flags & PF_CHROUTES))) {
#else
if (!capable(CAP_NET_ADMIN)) {
#endif
#ifdef CONFIG_LIDS
lids_security_alert("CAP_NET_ADMIN violation: ioctl SIOC #%i",cmd);
#endif
return -EPERM;
.........
你能发现,如果你要为嗅探改变状态的话, 你必须让CAP_NET_ADMIN开启来实现这个功能。你可以在内核密封前启动CAP_NET_ADMIN,然后在内核密封后禁止它。
3、内核的检测端口扫描的功能
为什么要在内核里需要一个端口扫描的检测?
因为一个端口扫描的时候能检测到半连接的扫描。所以,端口扫描检测需要作为一个嗅探的程序来运行。如果我们需要检测端口扫描。我们又要开启允许嗅探程序的运行,在内核中的端口扫描检测很有用处。
端口扫描的主要思想是在一段短的时间内扫描一个范围的端口,然后,它们会在扫描后记录那些端口是开放的。用这个方法,扫描器就可以检测到远端的机器开放了什么端口。在内核里,我们能发现下面的代码。
内核中的端口扫描检测
让我们看看tcp的端口扫描
/* in net/ipv4/tcp_ipv4.c */
int tcp_v4_rcv(struct sk_buff *skb, unsigned short len)
{
........
__skb_queue_tail(&sk->back_log, skb);
return 0;
no_tcp_socket:
#ifdef CONFIG_LIDS
lids_check_scan(skb->nh.iph->saddr,ntohs(th->dest));
#endif
tcp_v4_send_reset(skb);
discard_it:
.........
}
lids_check_scan()有两个参数,一个是影响no_sock_srror的源地址,另外一个是你要通讯的机器上的端口。
Lids_check_scan()主要的任务是统计由同一个资源发出的错误信息。但是lids_check_scan()在源地址是一个端口扫描器的时候不会做检查,它会要timer来做。现在,让我们看看lids_check_scan()的代码。
/* in net/ipv4/lids_check_scan.c */
int lids_check_scan(__u32 addr,__u16 port)
{
...........
if((p = lids_find_scan(addr)) == NULL) {
p1 = &lids_scan_head;
p = (struct lids_scan*)kmalloc(sizeof(struct lids_scan),GFP_ATOMIC);
if(p == NULL ) {
return -1;
}
while((p1->next)!=NULL)p1=p1->next;
/* init the structure. */
p1->next = p;
spin_unlock(p->lock);
p->next = NULL;
p->addr = addr;
p->counter = 0;
p->lower_counter = 0;
p->create_time = current_time;
/* init a timer to do the detect thing */
init_timer(&(p->timer));
p->timer.expires = LIDS_SCAN_TIMEOUT + current_time;
p->timer.data = (unsigned long) p;
p->timer.function = lids_proceed_scan ;
add_timer(&(p->timer));
}
/* add the counter when hit */
spin_lock(p->lock);
(p->counter)++;
/* we here defined the port < 1024 and > 1024 */
if(port < 1024)
(p->lower_counter)++;
spin_unlock(p->lock);
return 0;
}
从上面的代码,我们能看到这个函数的主要是一个列表,所以它很快。为了防止在kmalloc()的DoS的攻击,我们也需要来限制检测的列表。在这个代码里可能是错误的,但是因为记时的函数timer lids_proceed_scan能非常快的更新这个列表(每3秒一次)。所以DoS攻击很难让内核迷惑扫描源的真实性
九、入侵响应系统
当我们检测到了一些程序违反了我们定的规则,我们必须要对它做出响应。在当前的LIDS系统,我们可以用记录的功能来记录下所有的信息。我们也可以挂起这个用户用到的控制台。然后,我们就会给LIDS加上更多的响应系统,不但是在内核里,还是在用户区。
1、允许用安全的方法登陆
在传统的内核登陆模式,我们每次都是用printk在控制台打印信息。但是这样很容易会被DoS攻击内核。他会让系统频繁的运行printk命令,我们可以在内核用security_alert()来实现报警响应功能。
你可以看看/include/linux/kernel.h的代码。
2、控制台挂起
这个功能是用安全日志来挂起那些违反LIDS定义的安全规则的人的控制台。他们要继续必须重新登陆系统。但是他们所做的一切都已经被系统日志记录下来或是用e-mail的方法发送给了管理员。
3、用e-mail或是传呼来报告管理员
这个功能是boidi开发的。用这个工具,我们可以很容易的知道系统什么地方出错,我们可以及时的响应入侵。
这些就是大概的LIDS的基本原理,它可能很多的涉及到了内核模块的编程。这个方面内容,大家可以到chinabyte的linux专区,那里有coolboy的关于可加载模块lkm的资料。很cool。 有什么问题,也可以e-mail给我chaobowang@sina.com。
关键词:LIDS精通与进阶(下)