/* RFI Scanner By DiGitalX (DiGi7alX@Gmail.com) Date: 6/4/2007 -- MicroSystem Team */ #define WIN32_LEAN_AND_MEAN #include #include //#define _DEBUG //debug mode (for me :D) #define DEBUG_ROOT "output" //put the vuln functions here //functions that if a var is in its arguments then possible RFI occurs //IMPORTANT: keep this order char* vuln[] = { "include_once", "include", "require_once", "require", NULL }; //global BOOL bShortDis = FALSE; void usage(char* app) { printf("usage: [-s] %s \n", app); printf("\t-s\tshort display mode\n"); } void banner(void) { printf("RFI Scanner By DiGitalX (DiGi7alX@Gmail.com)\n"); printf("Date: 6/4/2007 -- MicroSystem Team\n\n"); } //return: FALSE if EOF reached, TRUE otherwise BOOL freadline(FILE* f, char* line, int size) { int b, i = 0; //zero line memset(line, 0, size); do { //read one byte b = fgetc(f); //check if EOF if (b == EOF) return FALSE; //check if newline cha reached or line is full if ((b == '\n') || (i == 1023)) return TRUE; *line++ = b; //fill line i++; //increment counter } while (1); return 1; /* unreachable code */ } BOOL php_scanfile(char* file) { char line[1024], line2[1024]; int linenum = 0; BOOL notend; char* tmp, *tmp2, *x; //open file FILE* f = fopen(file, "rb"); //check if (f == NULL) return FALSE; do { //opened, then read line by line notend = freadline(f, line, sizeof(line)); linenum++; //lower the line strcpy(line2, line); CharLower(line2); for (int i = 0; vuln[i] != NULL; i++) { //now line contains one line of code, search for RFI functions //include, include_once, require, require_once tmp = strstr(line2, vuln[i]); if (tmp != NULL) { //line contains vuln function maybe RFI. //check if function tmp += strlen(vuln[i]); //skip function name while (*tmp != '(') { //check if end of line reached or someother char (not whitespace means not function) if (*tmp == '\0') goto next; //then goto next vuln function //check if there's crap between vuln function and the first '(' reached //if so then it's not a vuln function maybe comment or var or string or something else if ((*tmp != ' ') && (*tmp != '\t')) goto next; //just dun bother and goto next vuln function tmp++; //keep incrementing tmp until catching '(' [opening parentheses of the vuln function] } //check for var inside this function tmp2 = tmp; //set tmp2 at begin of include function while (*tmp2 != ')') { tmp2++; //keep incrementing tmp2 until catching ')' [closing parentheses of the include function] //check if end of line reached if (*tmp2 == '\0') goto next; //then goto next vuln function } x = tmp; //set x at begin of include function while ((*x != '$') && (x < tmp2)) x++; //keep incrementing x until catching a var inside include functino or include function closing parentheses //check which condition just holded if (*x == '$') { //BINGO, possible RFI cought :D printf("possible RFI at line: %u", linenum); //if bShortDis then provide filename if (bShortDis) printf(" in \"%s\"\n", file); else printf("\n"); //otherwise just newline break; //break off the for loop } } next: } if (!notend) break; //NOT not end == end :D } while (1); fclose(f); return TRUE; } void php_search(void) { WIN32_FIND_DATA wfd; HANDLE fh; char lpBuffer[320]; char *lpFilePart; fh = FindFirstFile("*.*",&wfd); if (fh != INVALID_HANDLE_VALUE) { do { // skip '.' and '..' dirs if (wfd.cFileName[0] == '.') continue; // if dir enter it if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (SetCurrentDirectory(wfd.cFileName) == TRUE) { php_search(); // recursive call SetCurrentDirectory(".."); } continue; } // otherwise carry on our process if (GetFullPathName(wfd.cFileName,320,lpBuffer,&lpFilePart) == 0) continue; CharLower(lpBuffer); // checking if the extension of the file is php if (memcmp(&lpBuffer[lstrlen(lpBuffer)-3],"php",3) == 0) { //skip if bShortDis is set if (!bShortDis) printf("Scanning %s...\n", lpBuffer); php_scanfile(lpBuffer); } } while (FindNextFile(fh,&wfd) == TRUE); FindClose(fh); // closing find handle } } BOOL begin_rfi_scan(char* root) { //first set the root dir as current dir if (!SetCurrentDirectory(root)) return FALSE; //begin the hunting for php files printf("Beginning Hunting RFI Vulnerabilities...\n"); //if -s is given then inform user that mode is activated if (bShortDis) printf("Short Display Mode Activated\n"); php_search(); printf("Finished of Hunting.\n"); return TRUE; } int main(int argc, char** argv) { int pos = 1; //root position in cmd line //show banner banner(); #ifndef _DEBUG //check if root dir is given in the cmd line if (argc < 2) { //show usage screen and exit usage(argv[0]); return 1; } #endif //-s switch is specified if (strcmp(argv[1], "-s") == 0) { bShortDis = TRUE; //set flag pos = 2; //change root position in cmd line } //root dir is given good, then scan all the files inside this root directory #ifndef _DEBUG if (!begin_rfi_scan(argv[pos])) { #else if (!begin_rfi_scan(DEBUG_ROOT)) { #endif printf("Error: initializing RFI Scanner... Try Again"); return 1; } return 0; }