За последние 24 часа нас посетили 25266 программистов и 1736 роботов. Сейчас ищут 916 программистов ...

Написание непрозрачного кода на основе OOP PHP

Тема в разделе "Прочие вопросы по PHP", создана пользователем titch, 18 дек 2010.

  1. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    Доброе время суток
    Столкнулся с проблемой, ответ на который не смог найти на просторах интернета.

    Сразу к делу. Поставили передо мной задачу написать непрозрачный объектно-ориентированный код на php.
    Есть система, которая работает с некоторыми секретными данными. Данные хранятся в xml, и закрыты ассиметричным ключом. Закрытый ключ хранится в коде внутри финализированного метода внутри класса. Класс накрыт зендом и поднимается только через дизасм. Скрепя сердце начальство признало этот способ безопасным. Доступ к классу осуществляется через https соединение. Столкнулся с проблемой, которая разорвала мне мозги: вся эта система ходит по рукам, но всё время остается закрытой для сторонних разработчиков за исключением того, что у системы есть документированное API. А значит на эту систему вешаются сторонние модули.

    Не смотря на то, что сам класс, который парсит xml с секретными данными финализированный и всё, что можно находится в private, добрые люди намекнули, что эта система пробиваема на Ура. Способ обхода очень странный: самый верхний объект прогоняется через var_dump, результат вывода кэшируется, а затем кэш парсится. Получается, что если мой объект расшифровал секретный xml, то он хранит распарсированные конфиги у себя в private свойствах, потом его сканирует сторонний модуль через var_dump или print_r и грабит секретную статическую информацию производителя системы, которая одинакова на всех копиях системы. На сколько мне известно, var_dump и print_r могут получить доступ к всем свойствам (в том числе private и protected). Уязвимостью это язык не поворачивается, это дыра, в которую можно пешком пройти.

    Пока что для себя нашёл только один способ, как можно хранить хоть сколько-нибудь непрозрачную информацию - использовать константную строку в теле финализированного private метода. Но это подходит только для статики.

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

    Прошу помощи у сообщества. 1) Проконсультируйте на счёт возможностей ClassKit. Так ли всё ужасно? 2) Что делать с var_dump? 3) Как вообще бы вы решали проблему такого рода?

    Если я не очень понятно объяснил суть проблемы, спрашивайте - я всё что можно рассказать расскажу и покажу.
     
  2. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    я не понял смысла, почему для API отдается объект? парсит пусть сервак, а клиентский код только получает ограниченную инфу в свой объект так на пример /api/getsomething/1/ или я что то не так понял?
     
  3. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    система купле-продажная. т.е. клиент покупает у нас код, который накрыт зендом и дописывает модули под свои нужды. клиент и сторонний разработчик для нас - это один и тот же человек. у нас задача защитить секретные данные, которые хранятся внутри файлов конфигурации, от других разработчиков. если я пишу API, то получается, что мой код и код стороннего разработчика исполняется параллельно. мой объект имеет открытые методы, через которые он взаимодействует с чужими объектами. напрямую сторонний код не может распарсить мои файлы конфигурации, потому что он не знает мой закрытый ключ (который хранится в финализированном private методе моего класса в виде константы). но если я уже распарсил конфиг и передаю управление чужому модулю, то чужой модуль может через var_dump распотрошить меня и получить секретную информацию. вот в этом и проблема
     
  4. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    titch
    может глупая идея, но, как насчет того чтобы сделать методы статическими, запретить создание и клонирование объекта?
    к слову, расшифруют все равно, если захотят
     
  5. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    это вопрос времени, не спорю.

    м... если можно, пример в студию. упрощенно текущая схема:

    PHP:
    1.  
    2. class c_Center
    3.     {
    4.         private $DOM_Secret;
    5.        
    6.         final private function f_Key ()
    7.         {
    8.             return "1234567890"; //очень упрощенно
    9.         }
    10.         final private function f_ParseSecret()
    11.         {
    12.             //открываем при помощи f_Key конфиг, парсим его и записываем в $this->DOM_Secret
    13.         }
    14.         public function f_MakeProfit($input)
    15.         {
    16.             //используя $this->DOM_Secret и $input приносим пользу другому классу
    17.         }
    18.     }
    19.  
    20. $center = new c_Center();
    21.  
    22. $charlie->cash_var_dump($center); //получаем доступ извне к $DOM_Secret
    23.  
    получается, что не имеет значения, кто создает объект center.
    еще хуже, если ClassKit дает возможность сразу скопировать $center->f_Key() в чужой класс
    как видно, такой подход к f_Key не дает сразу получить доступ к ключу. если записать ключ как private $key, то он вынимается через тот же самый $charlie->cash_var_dump($center);
    функция хотя бы не вскрывается так просто. но значение там статично. а файлы конфигурации для того и нужны, чтобы через какое-то время можно было без внедрения в код обновить ключи протекции
     
  6. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    PHP:
    1. <?php
    2. final class Center {
    3.     private static $domSecret = 'DOM';
    4.    
    5.     public function makeProfit($a){
    6.         return self::$domSecret.$a;
    7.     }
    8.    
    9.     public function __construct(){
    10.         exit("error");
    11.     }
    12. }
    13.  
    14. echo Center::makeProfit('::Profit');
    15.  
    16.  
    17. //а тут хрен
    18. $c = new Center();
     
  7. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    выше всяких похвал!)
    посмотрел со всех сторон, вроде пока не придумал способ пробить. спасибо!
    если всё же что-то появится, то буду писать в эту же тему.
     
  8. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    titch
    насчет класс кита
    http://www.php.net/manual/en/function.c ... import.php
    он похоже просто парсит файл, если все зашифровано то ничего не получится, проще проверить, а расшифровать точно расшифруют, если приспичит
     
  9. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    класскит больше пугает не своим импортом, сколько вот этим методом:
    http://www.php.net/manual/en/function.c ... d-copy.php
    попробовать в самое ближайшее время не смогу, но если руки дойдут, то проверю его на прочность

    upd: кроме прочего прошу заметить, что уязвимость в нестатических классах осталась
     
  10. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    безобъектные классы - палка о двух концах. нет объекта - нельзя зарегистрировать как переменную сессии. а значит, что при переходе со страницы на страницу, класс Center нужно перестраивать заново даже для одного и того же пользователя (и конфиг парсить заново). операция вместе с расшифровыванием дорогостоящая по ресурсам (хотя там в моем контексте хранить в сессии секретную инфу вообще нельзя). не торт. но в моём случае это оправдано.
     
  11. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    а чего так сложно? класс, который наследуется от вашего, не сможет переопределить private-метод, потому что он private.
    мне для общего развития: можете показать "var_dump верхнего объекта, доступ к классу которого осуществляется через https соединение"?
     
  12. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    PHP:
    1. private function __construct(){}
    корректнее
    вы считаете это безопасным??
     
  13. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    Найстройки сервера позволяют передавать php-файлы через https соединение, а не только исполнять их. var_dump производится уже по созданному объекту на стороне сервера нашего клиента. Прошу еще заметить, что сам php код не открыт, а скомпилирован под zend.
     
  14. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    Вы не находите, что я сказал то же самое?
     
  15. LeoK

    LeoK Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    43
    Симпатии:
    0
    titch Решили задачку?
    А почему бы например не хранить сами секретные данные зашифрованными? И сделать зазенденый декодер?
    т.е. нам придётся уже скрывать только алгоритм, что вроде легче, нет?
     
  16. karlozzz

    karlozzz Активный пользователь

    С нами с:
    24 окт 2010
    Сообщения:
    430
    Симпатии:
    0
    Адрес:
    Y-OLA
    А разве сериалайзом не пробивается?))) Магия вам в помощь))

    ПС
    Пробивать сериалайзом не пробовал тк на текущей оси серв не стоит)
     
  17. LeoK

    LeoK Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    43
    Симпатии:
    0
    сериалайз не трогает статические свойства, только состояние объекта
     
  18. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    На сколько я знаю, сериализация не может быть применена к классу. А здесь как раз тот случай, когда объекта класса не существует. На счет хранения в сессии секретных значений тоже проблема решилась достаточно банально - используется MCrypt, и написана система для управления переменными, которые нужно хранить в сессиях зашифрованными. Решил, что лучше один раз разделаться с этим вопросом, и больше никогда к этому не возвращаться. Кстати, сама эта система работает на принципе, описанном сколько-то постов выше. Еще раз спасибо, всё работает идеально.

    ps: пробоем var_dump уже сам воспользовался несколько раз в практических целях и даже извлек из этого некоторую коммерческую выгоду, что и вам рекомендую ))

    Категорически не советую вам использовать криптографические методы, устойчивость которых зависит от сокрытия алгоритма. Сегодня ваша методика работает, а завтра дизасмом вас на части раскрошат. И если использовать шифрование для каждой переменной, получается слоупок-код. А я не люблю медленный код :Р
     
  19. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    PHP:
    1. <?php
    2. $r = new ReflectionClass('Center');
    3. print_r($r->getStaticProperties());
    4.  
    Правда вроде как зенд требует отключенного reflection, но вообще-то зенд ломается на ура, уж лучше ионкуб.
     
  20. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    проверил, реально пробивает. какие есть варианты, как проверить, чтобы reflection был отключен прямо в скрипте?
     
  21. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    titch
    class_exists ? правда, если нормально С знаешь можно переименовать его
     
  22. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    в том-то и проблема.. если бы у него был какой-либо идентификатор хитро-хитрый... или есть еще какой-либо обходной вариант?
    жэсть... дырявый php... ой, дырявый...

    ps: есть у меня предположение, что ионкуб вскроется точно также - через модуль перехвата кода в php. есть мысли на этот счёт?