Blog. Just Blog

Web-мастеру и не только

Полезные решения для Web-мастеров
Web-мастеру и не только - RSS-канал Web-мастеру и не только - Карта сайта

Проверка принадлежности IP-адреса заданному диапазону

19.11.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Проверка вхождения IP в заданный диапазон может применяться во многих ситуациях. Например бан всей подсетки злоумышленника, принудительное ограничение скорости для зарубежного трафика, переадресация на различные разделы сайта в зависимости от провайдера пользователя и т.д. Я использую такие функции:
  1. // ------------------------------------------------------------
  2. // Проверка вхождения IP в заданный диапазон
  3. // На входе:
  4. // $ip - массив октетов проверяемого IP
  5. // $ip_start - массив октетов начала интервала
  6. // $ip_end - массив октетов конца интервала
  7. // В интервалах допускаются маски '*'
  8. // На выходе: TRUE или FALSE, входит IP или нет в диапазон
  9. // ------------------------------------------------------------
  10. function chk_ips($ip,$ip_start,$ip_end) {
  11.   for ($i=0$i<4$i++) {
  12.     if ($ip_start[$i]=='*') { $ip_start[$i]='0'; }
  13.     if ($ip_end[$i]=='*') { $ip_end[$i]='255'; }
  14.   }
  15.   $ip_num=ip2long(join('.',$ip));
  16.   if ($ip_num>=ip2long(join('.',$ip_start)) 
  17.       && $ip_num<=ip2long(join('.',$ip_end))) {
  18.     // IP входит в интервал
  19.     return true;
  20.   }
  21.   else {
  22.     // IP не входит в интервал
  23.     return false;
  24.   }
  25. }
Функция универсальная, позволяет обрабатывать одиночные IP-адреса, точно заданные диапазоны и диапазоны с маской "*" в любом октете. Дополнительных проверок на корректность диапазонов не производится.

Читать статью целиком »
Просмотров: 16200 | Комментариев: 1

Отправка сообщений на ICQ из PHP-скриптов

09.11.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Для отправки сообщений на ICQ из PHP-скриптов очень удобно использовать готовый класс WebIcqPro от автора Сергея Акудовича. Этот класс может послужить основой для создания ICQ-роботов, системы оповещения о различных событиях с сайтов, удаленного администрирования через ICQ и многого другого. WebIcqPro не требует установки на сервере дополнительных компонентов и библиотек. Достаточно подключить через include сам класс в ваш PHP-скрипт и воспользоваться его методами и свойствами. Для работы WebIcqPro требуется PHP 5.2.0 и выше. Класс активно развивается и скоро будет включать в себя практически все функции протокола Oscar. Если по каким-либо причинам на сервере установлена более старая версия PHP, то можно воспользоваться облегченной версией класса WebIcqLite. В ней есть только функции отправки и получения сообщений, но обычно этого вполне достаточно. Класс неплохо документирован, все описания на русском языке, методы и свойства приведены с примерами использования. Очень хороший скрипт, пользуюсь сам и другим рекомендую.

Помните, что на сервере ICQ установлена защита от брутфорса, и при частых подключениях аккаунт блокируется на несколько десятков минут. Поэтому если для вашего проекта критично, чтобы все сообщения были отправлены, то зарегистрируйте несколько ICQ-аккаунтов и отправляйте сообщения с них по очереди или выбирая один случайным образом. Количество необходимых аккаунтов определяется опытным путем в зависимости от нагрузки.

Просмотров: 14541 | Комментариев: 16

Работа с недокументированными API WHM и cPanel

20.10.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
cPanel является одной из самых популярных коммерческих панелей управления аккаунтами на серверах виртуального хостинга. Все действия выполняются обычно через web-интерфейс, но для использования в ваших проектах авторами предоставляется API. К сожалению вообще никакой вменяемой документации разработчикам не предоставляется. Эту позорную отмазку на официальном сайте назвать технической документацией трудно, поэтому при разработке очередного проекта пришлось создавать собственный класс для работы с cPanel. Попутно удалось реализовать несколько недокументированных функций и расширить функционал уже имеющихся.
  1. <?
  2. // -------------------------------------------------------------
  3. // Класс для работы с WHM/cPanel через API
  4. // (C) ManHunter / PCL
  5. // http://www.manhunter.ru
  6. // -------------------------------------------------------------
  7. class cpanel_class {
  8.   var $cpanelaccterr;
  9.   var $host;
  10.   var $user;
  11.   var $accesshash;
  12.   var $usessl;
  13.  
  14.   // -------------------------------------------------------------
  15.   // Изменить пароль на аккаунте
  16.   // Для выполнения нужна авторизация только с рутовым доступом
  17.   // $chuser - аккаунт на сервере
  18.   // $password - новый пароль
  19.   // -------------------------------------------------------------
  20.   function chgpassword ($chuser$password) {
  21.     if ($this->user!="root") {
  22.       $this->cpanelaccterr="Root privileges required";
  23.       return;
  24.     }
  25.     $result $this->whmreq("/scripts/passwd?user=${chuser}&password=${password}&password2=${password}");
  26.     $result=eregi_replace("[\n]{1,}","\n",strip_tags($result));
  27.     if ($this->cpanelaccterr != "") { return; }
  28.     if (strpos($result,"could not be changed")!==false) {
  29.       $this->cpanelaccterr=$result;
  30.       return;
  31.     }
  32.     return $result;
  33.   }
  34.  
  35.   // -------------------------------------------------------------
  36.   // Заблокировать аккаунт
  37.   // $suspenduser - аккаунт на сервере
  38.   // $reason - причина блокировки, сделано на перспективу,
  39.   //           фактически параметр панелью игнорируется
  40.   // -------------------------------------------------------------
  41.   function suspend ($suspenduser$reason="") {
  42.     $reason=str_replace(" ","+",$reason);
  43.     $result $this->whmreq("/scripts/remote_suspend?user=${suspenduser}&reason=${reason}");
  44.     if ($this->cpanelaccterr != "") { return; }
  45.     if (strpos($result,"Access Denied")!==false) {
  46.       $this->cpanelaccterr=$result;
  47.       return;
  48.     }
  49.     return $result;
  50.   }
  51.  
  52.   // -------------------------------------------------------------
  53.   // Разблокировать аккаунт
  54.   // $unsuspenduser - аккаунт на сервере
  55.   // -------------------------------------------------------------
  56.   function unsuspend ($unsuspenduser) {
  57.     $result $this->whmreq("/scripts/remote_unsuspend?user=${unsuspenduser}");
  58.     if ($this->cpanelaccterr != "") { return; }
  59.     if (strpos($result,"Access Denied")!==false) {
  60.       $this->cpanelaccterr=$result;
  61.       return;
  62.     }
  63.     return $result;
  64.   }
  65.  
  66.   // -------------------------------------------------------------
  67.   // Удалить аккаунт
  68.   // $killuser - аккаунт на сервере
  69.   // -------------------------------------------------------------
  70.   function killacct ($killuser) {
  71.     $result $this->whmreq("/scripts/killacct?user=${killuser}&nohtml=1");
  72.     if ($this->cpanelaccterr != "") { return; }
  73.     return $result;
  74.   }
  75.  
  76.   // -------------------------------------------------------------
  77.   // Показать версию WHM/cPanel
  78.   // -------------------------------------------------------------
  79.   function showversion () {
  80.     $result $this->whmreq("/scripts2/showversion");
  81.     if ($this->cpanelaccterr != "") { return; }
  82.     return $result;
  83.   }
  84.  
  85.   // -------------------------------------------------------------
  86.   // Перевести аккаунт на новый тарифный план
  87.   // $upuser - аккаунт на сервере
  88.   // $acctplan - новый тарифный план
  89.   // -------------------------------------------------------------
  90.   function update ($upuser$acctplan) {
  91.     $acctplan=str_replace(" ","+",$acctplan);
  92.     $result $this->whmreq("/scripts2/upacct?user=${upuser}&pkg=${acctplan}");
  93.     if ($this->cpanelaccterr != "") { return; }
  94.     return $result;
  95.   }
  96.  
  97.   // -------------------------------------------------------------
  98.   // Открыть новый аккаунт
  99.   // $acctdomain - домен
  100.   // $acctuser - логин для аккаунта
  101.   // $acctpass - пароль для аккаунта
  102.   // $acctplan - тарифный план
  103.   // $accemail - контактный email аккаунта
  104.   // $acccpmod - стиль cPanel по умолчанию
  105.   // -------------------------------------------------------------
  106.   function createacct ($acctdomain$acctuser$acctpass$acctplan$accemail,
  107.            $acccpmod="bluelagoon") {
  108.     if (!eregi("^[-a-z0-9\.]{4,}$",$acctdomain)) {
  109.       $this->cpanelaccterr="Invalid domain name";
  110.       return;
  111.     }
  112.     $acctplan=str_replace(" ","+",$acctplan);
  113.     $accemail=str_replace("@","%40",$accemail);
  114.     $result $this->whmreq("/scripts/wwwacct?remote=1&nohtml=1&username=${acctuser}&password=${acctpass}&domain=${acctdomain}&plan=${acctplan}&contactemail=${accemail}&cpmod=${acccpmod}");
  115.     if ($this->cpanelaccterr != "") { return; }
  116.     return $result;
  117.   }
  118.  
  119.   // -------------------------------------------------------------
  120.   // Показать список имеющихся на сервере аккаунтов
  121.   // -------------------------------------------------------------
  122.   function listaccts () {
  123.     $result $this->whmreq("/scripts2/listaccts?nohtml=1&viewall=1");
  124.     if ($this->cpanelaccterr != "") { return; }
  125.  
  126.     $page split("\n",$result);
  127.     foreach ($page as $line) {
  128.       list($acct,$contents) = split("="$line);
  129.       if ($acct != "") {
  130.         $allc split(","$contents);
  131.         $accts[$acct] = $allc;
  132.       }
  133.     }
  134.     return($accts);
  135.   }
  136.  
  137.   // -------------------------------------------------------------
  138.   // Показать список заведенных на сервере тарифных планов
  139.   // -------------------------------------------------------------
  140.   function listpkgs () {
  141.     $result $this->whmreq("/scripts/remote_listpkg");
  142.     if ($this->cpanelaccterr != "") { return; }
  143.  
  144.     $page split("\n",$result);
  145.     foreach ($page as $line) {
  146.       list($pkg,$contents) = split("="$line);
  147.       if ($pkg != "") {
  148.         $allc split(","$contents);
  149.         $pkgs[$pkg] = $allc;
  150.       }
  151.     }
  152.     return($pkgs);
  153.   }
  154.  
  155.   // -------------------------------------------------------------
  156.   // Запрос к WHM/cPanel. Используется только для работы внутри
  157.   // класса, извне вызываться не должен
  158.   // -------------------------------------------------------------
  159.   function whmreq ($request) {
  160.     $cleanaccesshash preg_replace("'(\r|\n)'","",$this->accesshash);
  161.     $authstr $this->user ":" $cleanaccesshash;
  162.     $this->cpanelaccterr "";
  163.  
  164.     if (function_exists("curl_init")) {
  165.       $ch curl_init();
  166.       if ($this->usessl) {
  167.         curl_setopt($chCURLOPT_SSL_VERIFYPEER,0);                
  168.         curl_setopt($chCURLOPT_SSL_VERIFYHOST,0);
  169.         curl_setopt($chCURLOPT_URL"https://".$this->host.":2087" $request);
  170.       }
  171.       else {
  172.         curl_setopt($chCURLOPT_URL"http://".$this->host.":2086" $request);
  173.       }
  174.       curl_setopt($chCURLOPT_HEADER0);
  175.       curl_setopt($chCURLOPT_RETURNTRANSFER,1);
  176.       $curlheaders[0] = "Authorization: WHM $authstr";
  177.       curl_setopt($ch,CURLOPT_HTTPHEADER,$curlheaders);
  178.       $data=curl_exec ($ch);
  179.       curl_close ($ch);
  180.     }
  181.     elseif (function_exists("socket_create")) {
  182.       if ($this->usessl) {
  183.         $this->cpanelaccterr "SSL Support requires curl";
  184.         return;
  185.       }
  186.       $service_port 2086;
  187.       $address gethostbyname($this->host);
  188.       $socket socket_create (AF_INETSOCK_STREAM0);
  189.       if ($socket 0) {
  190.         $this->cpanelaccterr "socket_create() failed";
  191.         return;
  192.       }
  193.       $result socket_connect ($socket$address$service_port);
  194.       if ($result 0) {
  195.         $this->cpanelaccterr "socket_connect() failed";
  196.         return;
  197.       }
  198.       $in "GET $request HTTP/1.0\n";
  199.       socket_write($socket,$in,strlen($in));    
  200.       $in "Connection: close\n";
  201.       socket_write($socket,$in,strlen($in));    
  202.       $in "Authorization: WHM $authstr\n\n\n";
  203.       socket_write($socket,$in,strlen($in));    
  204.  
  205.       $inheader 1;
  206.       while(($buf socket_read($socket512)) != false) {
  207.         if (!$inheader) {
  208.           $data .= $buf;
  209.         }
  210.         if (preg_match("'\r\n\r\n$'s"$buf)) {
  211.           $inheader 0;
  212.         }
  213.         if (preg_match("'\n\n$'s"$buf)) {
  214.           $inheader 0;
  215.         }
  216.         if (preg_match("'\r\n$'s"$buf)) {
  217.           $inheader 0;
  218.         }
  219.       }
  220.     }
  221.     else {
  222.       $this->cpanelaccterr "php not compiled with --enable-sockets OR curl";
  223.       return;
  224.     }
  225.     return $data;    
  226.   }
  227. }
  228. ?>
Для работы с этими функциями требуется доступ с правами администратора, и только для chgpassword требуется рутовый доступ. PHP должен быть собран с модулем curl или enable-sockets. При наличии навыков класс можно легко расширять другими функциями, доступными через web-интерфейс WHM/cPanel.

Читать статью целиком »
Просмотров: 5313 | Комментариев: 9

Проверка похожести двух слов

11.10.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Точное сравнение двух символьных строк, даже регистронезависимое, выполнить нетрудно. А как быть, если в одной их них встречаются символы другого алфавита, похожие по написанию? Так, буква "E" в русской и английской раскладке имеет одинаковое написание, или вместо русской "Н(н)" можно написать английскую "H(h)". Этим могут воспользоваться всякие ублюдки, например оставить сообщение на форуме якобы от администрации, зарегистрировав ник, внешне похожий на ник одного из админов. Для проверки похожести двух строк я использую следующую функцию:
  1. // -----------------------------------------------------
  2. // Функция проверки похожести двух слов
  3. // Параметры: $name1 и $name2 - слова для проверки
  4. // $register = TRUE - проверка регистронезависима
  5. //           = FALSE - проверка с учетом регистра
  6. // На выходе: TRUE - слова похожи, FALSE - отличаются
  7. // -----------------------------------------------------
  8. function chk_similarity($word1$word2$register=false) {
  9.   // Очистить слова от служебных символов
  10.   $word1=eregi_replace("[^0-9a-zа-я]","",$word1);
  11.   $word2=eregi_replace("[^0-9a-zа-я]","",$word2);
  12.  
  13.   // Возврат FALSE если длина слов различается
  14.   // или хотя бы одно из них пустое
  15.   if ((strlen($word1)!==strlen($word2)) || strlen($word1)*strlen($word2)==0) {
  16.     return false;
  17.   }
  18.  
  19.   // Заполнить таблицу соответствий
  20.   $pattern1="";
  21.   $pattern2=Array();
  22.  
  23.   $pattern1.="aа";
  24.   $pattern2[]="[аa]";
  25.   $pattern2[]="[аa]";
  26.  
  27.   $pattern1.="AА";
  28.   $pattern2[]="[АA]";
  29.   $pattern2[]="[АA]";
  30.  
  31.   $pattern1.="BВ";
  32.   $pattern2[]="[BВ]";
  33.   $pattern2[]="[BВ]";
  34.  
  35.   $pattern1.="bь";
  36.   $pattern2[]="[bь]";
  37.   $pattern2[]="[bь]";
  38.  
  39.   $pattern1.="cс";
  40.   $pattern2[]="[cс]";
  41.   $pattern2[]="[cс]";
  42.  
  43.   $pattern1.="CС";
  44.   $pattern2[]="[CС]";
  45.   $pattern2[]="[CС]";
  46.  
  47.   $pattern1.="eе";
  48.   $pattern2[]="[eе]";
  49.   $pattern2[]="[eе]";
  50.  
  51.   $pattern1.="EЕ";
  52.   $pattern2[]="[EЕ]";
  53.   $pattern2[]="[EЕ]";
  54.  
  55.   $pattern1.="HН";
  56.   $pattern2[]="[HН]";
  57.   $pattern2[]="[HН]";
  58.  
  59.   $pattern1.="iI1l";
  60.   $pattern2[]="[iI1l]";
  61.   $pattern2[]="[iI1l]";
  62.   $pattern2[]="[iI1l]";
  63.   $pattern2[]="[iI1l]";
  64.  
  65.   $pattern1.="kк";
  66.   $pattern2[]="[kк]";
  67.   $pattern2[]="[kк]";
  68.  
  69.   $pattern1.="KК";
  70.   $pattern2[]="[KК]";
  71.   $pattern2[]="[KК]";
  72.  
  73.   $pattern1.="MМ";
  74.   $pattern2[]="[MМ]";
  75.   $pattern2[]="[MМ]";
  76.  
  77.   $pattern1.="nп";
  78.   $pattern2[]="[nп]";
  79.   $pattern2[]="[nп]";
  80.  
  81.   $pattern1.="oо0";
  82.   $pattern2[]="[oо0]";
  83.   $pattern2[]="[oо0]";
  84.   $pattern2[]="[oо0]";
  85.  
  86.   $pattern1.="OО0";
  87.   $pattern2[]="[OО0]";
  88.   $pattern2[]="[OО0]";
  89.   $pattern2[]="[OО0]";
  90.  
  91.   $pattern1.="pр";
  92.   $pattern2[]="[pр]";
  93.   $pattern2[]="[pр]";
  94.  
  95.   $pattern1.="PР";
  96.   $pattern2[]="[PР]";
  97.   $pattern2[]="[PР]";
  98.  
  99.   $pattern1.="rг";
  100.   $pattern2[]="[rг]";
  101.   $pattern2[]="[rг]";
  102.  
  103.   $pattern1.="TТ";
  104.   $pattern2[]="[TТ]";
  105.   $pattern2[]="[TТ]";
  106.  
  107.   $pattern1.="uи";
  108.   $pattern2[]="[uи]";
  109.   $pattern2[]="[uи]";
  110.  
  111.   $pattern1.="xх";
  112.   $pattern2[]="[xх]";
  113.   $pattern2[]="[xх]";
  114.  
  115.   $pattern1.="XХ";
  116.   $pattern2[]="[XХ]";
  117.   $pattern2[]="[XХ]";
  118.  
  119.   $pattern1.="yу";
  120.   $pattern2[]="[yу]";
  121.   $pattern2[]="[yу]";
  122.  
  123.   $pattern1.="YУ";
  124.   $pattern2[]="[YУ]";
  125.   $pattern2[]="[YУ]";
  126.  
  127.   $pattern1.="З3";
  128.   $pattern2[]="[З3]";
  129.   $pattern2[]="[З3]";
  130.  
  131.   $pattern1.="ч4";
  132.   $pattern2[]="[ч4]";
  133.   $pattern2[]="[ч4]";
  134.  
  135.   $pattern1.="Ч4";
  136.   $pattern2[]="[Ч4]";
  137.   $pattern2[]="[Ч4]";
  138.  
  139.   // Составить регулярное выражение для проверки
  140.   $tmp="^";
  141.   for ($i=0$i<strlen($word1); $i++) {
  142.     $letter=$word1[$i];
  143.     $pos=strpos($pattern1,$letter);
  144.     if ($pos===false) {
  145.       $tmp.=$letter;
  146.     }
  147.     else {
  148.       $tmp.=$pattern2[$pos];
  149.     }
  150.   }
  151.   $tmp.="$";
  152.  
  153.   // Возврат TRUE - слова похожи или равны
  154.   // FALSE - слова отличаются
  155.   return($register?eregi($tmp,$word2):ereg($tmp,$word2));
  156. }
Примеры использования:

Читать статью целиком »
Просмотров: 4138 | Комментариев: 14

Защита PHP-скриптов от анализа и модификации

06.10.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Все программные продукты для защиты PHP-скриптов подразделяются на две категории: требующие установки на сервер дополнительных модулей и работающие с обычной конфигурацией web-серверов. Первые более надежны в плане безопасности, так как переводят PHP-скрипты из текстового вида в специальный байт-код, но требуют доступа к серверу с правами администратора. Вторые могут работать практически на всех хостингах с поддержкой PHP, в том числе и бесплатных, но не представляют большой сложности для взлома. В отдельную подгруппу можно выделить обфускаторы исходного кода, не использующие шифрование или сжатие.

Защиты на уровне сервера:

Zend Encoder / Zend SafeGuard Suite - наиболее популярная коммерческая защита, модули для поддержки Zend обычно установлены на всех платных хостингах. Zend предоставляет привязку скриптов к доменам и ip, установку времени триальной работы скриптов и мощную обфускацию. Поддерживаются все операционные системы. В публичном доступе имеется несколько вариантов утилит для снятия Zend'а, все они представляют собой модифицированный PHP 4-й и 5-й версии. Старые версии Zend'а снимаются без проблем, в последних возникают сложности из-за обфускации исходного кода.

NuSphere NuCoder. Новая, активно развивающаяся коммерческая защита. На уровне собственных API предоставляет взаимодействие с защищаемыми скриптами, поддерживаются операционные системы Windows и Linux. Вследствие малой распространенности не устанавливается на обычных виртуальных хостингах, но вполне может быть установлена пользователями на выделенных серверах. Публичных декодеров нет.

SourceGuardian for PHP. Коммерческая защита, практически не встречается, на виртуальных хостингах не устанавливается. Позволяет устанавливать триальный срок работы скриптов с проверкой даты по внешним серверам точного времени, делать привязку защищаемых скриптов к серверам, ip-адресу, MAC-адресу сетевой карты, причем эти данные используются для расшифровки. Поддерживаются все операционные системы. Публичных декодеров нет.

Читать статью целиком »
Просмотров: 39599 | Комментариев: 36

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.12 сек. / MySQL: 2 (0.003 сек.) / Память: 4.75 Mb
Наверх