Вычисление прокси серверов

от
Прочее

Не знаю для чего люди пользуются анонимными прокси серверами, но учитывая мой опыт, хорошего от таких посетителей ждать не приходится. Вот и решил так сказать озадачиться определением таких пользователей. В сети по этому вопросу информации не так много и это огорчает. Утверждать не возьмусь, но по-моему есть два вида проксиков. Это всякие онлайн анонимайзеры, то есть сайты предоставляющие такую услугу. И анонимные прокси, которые можно прописать в настройках браузера.

Вычислить первые не составляет труда достаточно сравнить
window.location.hostname с адресом своего сайта. Если пользователь зашел с онлайн прокси в этой переменной будет как раз hostname данного проксика. Возможно некоторые прокси могут подменить данное значение, но мне такие пока не попадались )

Этим собственно можно и ограничиться, но мы не станем =) Следующий шаг – попытка определить реальный ИП адрес, который аноним пытается скрыть.

Алгоритм такой. Нужно вставить в тело страницы Java Script, рисунок, фрейм или еще что-нибудь, что бы вставленный элемент обратился напрямую к нашему сайту. Вот тут и поджидает главная проблема – прокси сервер парсит страницу и подменяет все выше указанные элементы. Поэтому нужно хотя бы минимально зашифровать наш код.

Вот так приблизительно будет выглядеть такой код:
  1. function detect(ip) //Функция добавит JS в код страницы, который и спалит настоящий ИП
  2.  {
  3.  // Типа шифруем все команды =)
  4.  var a = 'h'+'t'+'t'+'p'+':'+'/'+'/'+'site.com'+'?'+'i'+'p'+'='+ip;
  5.  var b = '<'+'s'+'c'+'r'+'i'+'p'+'t t'+'y'+'p'+'e'+'='+'"'+'t'+'e'+'x'+'t'+'/'+'j'+'a'+'v'+'a'+'s'+'c'+'r'+'i'+'p'+'t" s'+'r'+'c'+'="'+a+'+"></s'+'c'+'r'+'i'+'p'+'t>';
  6.  var c = 'd'+'o'+'c'+'u'+'m'+'e'+'n'+'t'+'.'+'w'+'r'+'i'+'t'+'e'+'(\''+b+'\')';
  7.  eval(c);  //Пробуем выполнить
  8.  }
  Однако тут поджидает первая проблема, хороший прокси подменяет eval(arg) чем то вроде eval(parseJS(arg)) – накрылось все наше шифрование. Но! Вызвать eval есть много способов =).

Самый простой – это переопределить ее. Например, так:
  1. var ee = eval; ee(arg); //вызвали ee, выполнится eval =)
Или функциями для работы с массивами, например, так:
  1. [arg].forEach(eval);
Есть еще методы, но пока хватит и этого. Чтобы код работал во всех браузерах, сделаем простую функцию:

  1. function exe(c) // маскируем eval
  2.  {
  3.  try
  4.   {
  5.   [c].forEach(eval); // Попытка 1
  6.   }
  7.  catch(e)
  8.   {
  9.   try
  10.    {
  11.    var ee = eval; ee(c); // Попытка 2  
  12.    }
  13.   catch(e)
  14.    {  
  15.    alert('Detect error...');      
  16.    }
  17.   }
  18.  }
Теперь большинство прокси не смогут корректно подменить данный код. Собственно мне при экспериментах, попался только один, который спалил фишку. Но проблема решилась довольно просто, я подменил функцию, которой он парсил код =) Просто добавил:
  1. parseHTML = function(e) { return (e);} //переопределим парсер которым пользуются некоторые прокси серверы
И вуаля, парсер сдулся.

И так наш скрипт готов, остается разместить на сайте серверную его часть, которая и определит судьбу нашего анонис… анонима тоесть =)

ПХП часть, размещаемая на сайте.

Когда указанный выше JS в код, будет выполнен в браузере, с настоящего ИП адреса будет отправлен запрос на наш сайт, который передаст GET параметром IP адрес прокси сервера. Останется просто сравнить его с $_SERVER['REMOTE_ADDR'] и если результаты не совпадут – задача выполнена, прокси обнаружен, ИП адрес вычислен.
Далее по ИП можно узнать город и провайдера.
Остается вывести данные например с погодой в его городе, пусть наш аноним порадуется =)

К сожалению если браузер не поддерживает JS или используется второй вид прокси серверов, все выше написанное теряет актуальность.

Определение полностью анонимных прокси серверов.

Тут задача довольно не тривиальная и определять их придется по косвенным признакам.
Самый простой способ создать свою базу, куда будут заноситься подозрительные ИП адреса. Так как заполнять такую базу в ручную довольно долго, попробуем автоматизировать данный процесс.

Алгоритм такой:

Ищем ИП адрес в черных списках, есть сервисы предоставляющие такие списки. А так как большинство прокси используется для рассылки спама, то есть хороший шанс, что мы его там найдем.
Далее запрашиваем диапазон ИП в который в ходит данный адрес, например у ripe.net и помещаем весь диапазон в базу данных, соответственно пометив его если он обнаружится в черном списке. Собственно это все. На данный момент мне удалось отфильтровать 62 диапазона из ~500.

Вот функции по проверке и получению диапазона адресов:

  1. function first_check_ip($ip) // проверка в списке 1
  2.  {
  3.  $detect = file_get_contents('http://winmxunlimited.net/api/proxydetection/v1/query/?ip='.$ip);
  4.  return $detect == '0' ? FALSE : TRUE;
  5.  }
  6.  
  7. function last_check_ip($ip) // проверка в списке 2
  8.  {
  9.  $xml = simplexml_load_file('http://api.stopforumspam.org/api?ip='.$ip);
  10.  return intval($xml->frequency) < 4 ? FALSE : TRUE;
  11.  }
  12.  
  13. function get_range_ip($ip) // получение диапазона
  14.  {
  15.  $resut=array();
  16.  $sock = fsockopen ("whois.ripe.net", 43, $errno, $errstr);
  17.  if ($sock)
  18.   {
  19.   fputs ($sock, $ip."\r\n");
  20.   $text='';
  21.   while (!feof($sock))
  22.    {
  23.    $text.=fgets ($sock,128)."<br>";
  24.    }  
  25.   fclose ($sock);  
  26.  
  27.  if (preg_match('/inetnum:\s+([^\s]+) - ([^\s]+)\s.*netname:\s+([^\s]+)\s*.*country:\s+([^\s]+)\s*/si',$text,$content))
  28.    {
  29.    $resut['country'] = strtoupper(trim($content[4]));  
  30.  //  if ($resut['country'] == 'EU') $resut['country'] = strtoupper(get_flag($ip));  
  31.  
  32.    $resut['start']   = $content[1];
  33.    $resut['finish']  = $content[2];
  34.    return $resut;
  35.    }
  36.   }
  37.  return FALSE;
  38.  }
+2   2   0
3581