...

суббота, 18 июня 2016 г.

Пишем расширение под PHP (7.0.7) без знаний о С/C++ и как это вообще работает

[unable to retrieve full-text content]

Можно ли написать свой модуль (расширение) к PHP без особых знаний, требующих большого времени изучения теории? Если умеешь программировать на самом PHP, то написать простейший код на С не составит особого труда, тем более, что PHP позволяет генерировать каркас под разрабатываемое расширение, в рамках которого потом пишешь код. Есть еще набирающий популярность зефир на хабре для этого вопроса. Данная публикация для тех, кто решил покопаться в исходниках PHP, немного посмотреть его внутренности, преследуя цель лишь поверхностного исследования. В данный момент я тот же самый исследовать без необходимых знаний. На собеседованиях по PHP часто просят написать код подсчета факториала. Вот такую функцию мы и напишем сейчас на С, которую потом можно вызывать из кода PHP. Я буду описывать действия, которые я сам делал и при этом ничего не знаю изначально по этой части. В интернете можно найти много статей по этому вопросу, большинство из них описывает информацию с использованием zval «старого» формата, но я не думаю, что будет хуже если и я еще добавлю от себя.
Читать дальше →

[Перевод] Когда программные продукты общаются с нами, должны ли они быть дружелюбными

image

В фильме Спайка Джонса 2013 года «Она» усатый Хоакин Феникс, переживший неудачную любовь, со всей страстью влюбляется в своего личного робота-помощника по имени Саманта.

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

Предназначение Саманты, как и любой технологии (особенно ботов), состоит в том, чтобы сделать жизнь пользователя легче. Мы желаем не нажимать кнопки и клавиши на сайте, а просто проговаривать вопросы и сразу же получать ответы. И поскольку научная фантастика — всё же фантастика, она, действительно, позволяет хотя бы очень приблизительно представить, как мир должен работать.

Быстрее — всегда лучше, и разговор, по мере совершенствования структуры общения, обработки естественного языка и ботов с искусственным интеллектом, всё больше вытесняет нажатие клавиш, становясь нашим предпочтительным методом нахождения информации.

На последней конференции по программным продуктам и технологиям компании Microsoft (Build developers conference) гендиректор Сатья Наделла провозгласил: «Боты являются новыми приложениями»; такую же позицию демонстрируют и действия других технических гигантов, таких как, например, Фейсбук, который вошёл в эту сферу, выпустив свои боты для Messenger Platform. Не будем забывать и про Telegram.

Даже Slack вводит боты в вашу рабочую среду, чтобы помогать во всём — от планирования встреч до нахождения новой красивой фотографии.

Чтобы убедиться в стремительном развитии разработки ботов, достаточно посмотреть через океан, где боты добились громадного успеха — в Азии, благодаря таким платформам как WeChat и Kik, на которые приходит более 650 миллионов пользователей в месяц.

Но, действительно, всё это и есть будущее? Отставим наши приложения и сайты и будем только разговаривать?

И если мы всё же сделаем так, то как оно всё должно работать?

Нам всем нужен кто-то, с кем можно поговорить


Чат-боты не являются чем-то новым.

Ещё в 1966 году программист Массачусетского технологического института Йозеф Вайценбаум опубликовал программу Eliza, которая анализировала слова, вводимые в компьютер, а затем подыскивала к ним ответ из подготовленного списка, имитируя человеческое общение.

Eliza была предназначена для моделирования работы психотерапевта — явно не для имитации человека вообще. Но Вайценбаум был обеспокоен увиденной реакцией пользователей программы Eliza.

image
Моё общение с Eliza…

Получив возможность свободного и открытого общения, пользователи начинали доверять программе Eliza свои самые сокровенные тайны.

В намерения Вайценбаума при разработке своего «чат-бота» ни в коем случае не входило создание «друга» или какой-то «личности», с которой можно было бы поддерживать контакт, он просто хотел сделать полезную утилиту. Ну, как какое-то приложение. Фактически в своей книге «Computer Power and Human Reason» («Мощь компьютера и мышление человека») он напрямую отверг идею, что компьютеры могли бы заменить человеческий интеллект.

По мысли Вайценбаума, тогда в конце 60-х, цель того «чат-бота» и всей той технологии, в действительности, состояла лишь в том, чтобы просто создать ещё один инструмент, расширяющий интеллектуальные возможности пользователя.

И, несмотря на подаваемое научной фантастикой утопическое видение будущего, заполненного мыслящими помощниками со свободной волей, большинство ботов в настоящее время является просто инструментами. Джаред Ньюман пишет в журнале Fast Company:

«Наилучшим подходом к ботам является думать о них, как о новом виде модели взаимодействия. Так же как мобильные приложения сокращают длинные меню ПО настольных компьютеров, так и чат-боты направляют пользователей в узкий набор взаимодействий, одинаковых для разных ботов.»

«Осуществляется ли такое действие путём ввода текста, отдачи команд голосом или остроумными шутками — вторично.»

Как всякий хороший продукт разработки опыта взаимодействия, бот предназначен для того, чтобы сделать взаимодействие легче, чем оно есть сейчас. Он предназначен устранять «трение» — т.е. такие взаимодействия, которые мешают людям интуитивно и легко выходить на их цели, и устранять любые барьеры, возникающие при использовании вашего продукта.

И для этого есть серьёзные основания.

Вспомним, что, когда компания Amazon ввела оплату в один клик, её годовой доход увеличился прим. на 2,4 млрд. долларов.

Или как приложение Bilingual Child утроило свой доход, когда предложило опцию «Купить всё» вместо покупки пользователем каждой «книги» отдельно.

Боты ориентированы на обеспечение результатов именно такого типа для каждого взаимодействия.

Бизнес знает, что люди, в основном, не имеют желания загружать какие-то инструкции и изучать их, чтобы использовать некоторое новое приложение для чтения новостей или заказа еды. В то время как у каждого отдельного приложения есть свой собственный процесс адаптации и своя кривая обучения, с чат-ботом не требуется обучение его использованию. Если вы в состоянии вводить с клавиатуры или говорить, то вы в состоянии сразу же начать взаимодействовать с ботом.

Требуется ли индивидуальность для программы-утилиты?


Всё сказанное выше порождает интересный вопрос: если полезность и лёгкость использования являются целью, то требовать ли от ботов «дружественности»?

Дэн Гровер, разработчик WeChat, в своём недавнем посте на тему «почему боты не заменят приложения», исследует, как Microsoft представляет себе работу ботов, рассматривая одну из самых основных (и, вне всяких сомнений, самых важных!) задач человечества: заказ пиццы.

image

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

Утилита — вычёркиваем.

Индивидуальность — может быть, немного подсушено, но немного.

Дэн затем сравнивает вышеуказанный процесс с его опытом заказа пиццы на боте Пицца-Хат сервиса WeChat:

image
ИТОГО: 16 нажатий (6 из которых — ввод моего PIN-кода для платежа)

Бот Пицца-Хат меньше похож на дружелюбного помощника; он, скорее, квалифицированный приёмщик заказа, только предоставляющий вам возможности реализовать ваше желание — заказать пиццу.

По мнению Дэна, трудность взаимодействия можно охарактеризовать количеством нажатий на кнопки — сколько раз требуется нажать кнопки на экране, чтобы получить желаемый результат?

Если считать так, то сдержанный бесстрастный бот Пицца-Хат убедительно выигрывает у дружелюбного Пицца-бота от Microsoft. Чем меньше нажатий, тем меньше затруднений. Но обязательно ли это значит улучшенное взаимодействие?

Дэн полагает, что «диалоговый» аспект дизайна, реализуемый компанией Microsoft и другими разработчиками ботов, является просто некоторой формой скевоморфизма, т.е. декоративным аспектом дизайна, который был необходим в оригинальном продукте, но в новом продукте функционально больше не требуется.

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

Вспомните, что некоторые из ваших приложений, такие как календарь или список контактов, имеют тот же внешний вид, что и их физические аналоги:

image

Разработчики продуктов полагали, что пользователь будет ментально не в состоянии перейти к хранению контактов на своём телефоне или в компьютере, если это не будет похоже на то, с чем он уже знаком.

Для ботов, утверждает Дэн, индивидуальность является тем же самым — в «диалоговом дизайне» не требуются элементы классического общения, такие как утончённость обращения, приветствия, подшучивание и т.д. Если такие элементы создают затруднения, то почему вы будете использовать бот, а не приложение? Когда новизна проходит, остаётся только имеющая значение полезность.

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

Задать вопрос, получить ответ. Всё!

Что же, в будущем нет места дружественности?


С другой стороны, разве перспектива взаимодействия с пользователем, обеспечиваемая персональным помощником, наподобие Samantha, не то, чего мы все желаем? И поскольку боты не разрабатываются всё же, как устройства с искусственным интеллектом «на все руки», перспектива более естественного взаимодействия представляется привлекательной.

Поскольку большинство ботов функционирует в среде, в которой мы взаимодействуем с другими людьми — например, Messenger, Slack и другие чат-сервисы, мы не можем не проецировать человеческие ценности на них. Поэтому, почему бы не придать им индивидуальность?

Но, как отмечает Эммет Коннолли, директор по разработке продукта в Intercom, наличие индивидуальности не подразумевает права претендовать на то, чтобы быть человеком:

«Не сбивайте с ног собственных пользователей (или, иначе, — не дурачьте их). Это означает — не используйте индикаторы „идёт набор на клавиатуре“ или искусственные задержки, чтобы заставить бот казаться больше похожим на человека. Наоборот, сообщения бота должны иметь особый стиль и быть чётко маркированы, показывая, что их генерирует не человек. Но это не исключает предоставление боту какой-то индивидуальности.»

У индивидуальности есть свои цели за пределами простого «действовать как человек».

Себастиан Крумхаузен, разработчик Sure (бота Facebook Messenger, ориентированного на помощь при поиске предложений для поддержки устойчивого бизнеса), предполагает, что индивидуальность помогает, в целом, улучшать взаимодействие с пользователем.

«Индивидуальность бота не улучшает взаимодействие с позиции эффективности или лёгкости использования, но она делает такое взаимодействие более приятным. Если у бота есть индивидуальность, то пользователи оказываются более терпимыми к ситуации при каком-то сбое.»

image

Вместо того чтобы действовать полностью по сценариям (скриптам), бот Sure использует то, что называют «ИИ (искусственный интеллект) с участием человека»: члены команды могут плавно входить в общение, если возникает вопрос, не вписывающийся в рамки текущей функциональности бота.

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

«Первоначально люди обращались к нам довольно грубо, особенно когда работа не ладилась,» — разъясняет Крумхаузен. «Однако когда мы добавили к реакциям немного причудливости, люди стали более открытыми и более дружелюбными.»

Специалисты по маркетингу называют такое явление «антропоморфизмом бренда», и компании давно используют этот метод.

Как разъясняет Тайлер Кауэн в The New Yorker, за десятилетия до того, как боты типа Sure показали нам свои причудливые индивидуальности, предназначенные для обеспечения взаимодействия, Scrubbing Bubbles от компании Dow Chemical втолковывали потребителям, как «мы делаем всю работу, поэтому вам не придётся делать её», мультяшная музыкальная группа California Raisins пела: «До меня дошли слухи …», а рисованный пекарь компании Pillsbury, хихикая, рассказывал о печенье, рулетах и булочках.

«Корпорации создают такие образы по простой причине: они знают, что потребители лучше реагируют на продукты, которые, как представляется потребителям, взаимодействуют с ними на персональном уровне.»

С ботами, однако, общение является двусторонним. Это означает, что бот не просто создаёт персональную связь с брендом, но отвечает за обслуживание и, как объясняет Крумхаузен, за совершение взаимодействия.

«Точно так же, как в ситуации, когда вы создаёте какой-то продукт, очень важно то, что он должен быть предельно сфокусирован с самого начала. Поэтому общение, действительно, находится в центре внимания. Мы обнаружили важность того, чтобы бот в известной степени подталкивал или вёл общение в желаемом нами направлении.»

Почти совершенным примером этого является новое приложение Quartz.

Точно так же как Sure, это приложение использует комбинирование сценариев (скриптов) и письменных вмешательств человека. Сами сюжеты и контент полностью написаны журналистами Quartz в стиле и тоне их бота и голоса их бренда.

image

Здесь имеется присущий Quartz налёт причудливости с множеством смайликов, с шутками и элементами лёгкого «трёпа», но маршрут движения «выбери сам» решительно является аспектом взаимодействия, предлагая только две возможности для каждого сюжета: читать дополнительно или двигаться дальше.

Как отмечает Джаред Ньюман в своей статье в журнале Fast Company, здесь имеет место не то взаимодействие, которое обеспечивает компьютер; здесь действуют пока ещё сценарии. Наши ответы также.

Риск наделения бота индивидуальностью


Приложение Quartz, будучи одним из лучших примеров комбинирования в боте полезности и индивидуальности, также показывает некоторые необычные проблемы.

Здесь точно так же, как иногда в ситуации, когда приходится вступать в общение с кем-то на вечеринке, нет никакой гарантии, что вам понравится персона, с которой вы вступили в разговор. И даже при том, что большинство разработчиков ботов пытается создать необычного и забавного собеседника, с которым легко ладить — он может быстро наскучить.

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

Возможно, в этом больше из эпизода, в котором Эммет Коннолли призывал не «дурачить» ваших пользователей.

Индивидуальность — это, конечно, прекрасно, но мы всё время знаем, что говорим не с другим человеком. Они не знают нас. Они не могут считать социальные признаки. Бесхитростное использование смайликов является просто иной формой индикаторов «набор на клавиатуре идёт» при «очеловечивания» общения.

Также, как давний подписчик на ежедневную новостную рассылку Quartz, я нашёл это приложение более привлекательным, чем прокручивание просто ещё одного списка статей. Но, поскольку оно — автономное приложение, а не бот в Messenger, я задавался вопросом, стал бы я входить в это приложение, чтобы гарантировать его сохранение (сами сохранение и открытие автономного приложения могут быть просто слишком затруднительными для меня).

И именно здесь скрывается «подводный камень», как разъясняет Крумхаузен применительно к Sure:

«Важно, чтобы было эффективно и чтобы люди получали ожидаемый быстрый ответ сразу же. Как и любое другое онлайн-взаимодействие с пользователем он должен быть быстрым и эффективным. И если результат не лучше или не быстрее, чем при существующем взаимодействии — в нашем случае что-нибудь вроде Google Maps или Yelp, то люди не будут использовать рассматриваемый продукт.»

Далее, такой быстрый ответ означает нахождение человека уже в нужном окружении. Сама процедура загрузки приложения и действия по его открытию (а не простое прочитывание сообщений электронной почты в среде, в которой я часто нахожусь) представляют собой больше затруднений, чем того заслуживает результат.

Оставляя в стороне аргументы по индивидуальности — закрепятся ли боты вместо приложений?


Всё вышесказанное сводится к главному вопросу применительно к ботам: заменят ли они известные нам на сегодня приложения?

Для большинства ответ — нет!

Боты — то ли дружелюбный разговорчивый «друг», то ли чистая утилита — являются просто частью технической экосистемы. Они дают возможность уменьшить затруднения в ключевых местах вашего продукта, будь то поддержка, предложения или продажи.

И, в конце концов, то, что они делают, может быть более важным, чем то, что они говорят.

Комментарии (0)

    Let's block ads! (Why?)

    Особенности кэширования компонентов в Unity3D

    Python: ListDlls и Handles

    пятница, 17 июня 2016 г.

    Device Lab от Google: маячки с технологией Eddystone

    Комментарии (0)

      Let's block ads! (Why?)

      Security Week 24: черный рынок угнанных RDP, зиродей в Flash, GMail отказывается от SSLv3 и RC4

      Одна из самых резонансных новостей этой недели посвящена черному рынку удаленного доступа к серверам. Эксперты «Лаборатории» исследовали сервис, на котором любой желающий может недорого приобрести информацию для доступа к одному из 70 с лишним тысяч серверов по всему миру по протоколу RDP. Взломанные серверы достаточно равномерно распределены по земному шару, примерно треть приходится на страны, где выбор — максимальный: Бразилию, Китай, Россию, Индию и Испанию.

      Ничего не подозревающим владельцам этих серверов наверное будет интересно узнать, что с ними могут сделать злоумышленники, но тут я даже затрудняюсь в выборе, с чего начать. Если коротко — сделать можно все. Дальнейший взлом инфраструктуры жертвы — без проблем. Рассылка спама, DDoS-атаки, криминальный хостинг, кража информации, таргетированные атаки с эффективным заметанием следов — тоже можно. Кража данных кредиток, денег со счетов, бухгалтерской отчетности — да, если взломанный сервер имеет доступ к такой информации. Все это — по смешным ценам: 7-8 долларов за учетку.

      XDedic и подобные сервисы (можно предположить, что он такой не один) — это криминальный екоммерс и финтех, он объединяет преступников разного профиля, крутых и не очень, использует современные технологии, предоставляет качественный сервис. Сами украденные данные предоставляют больше 400 продавцов — тут вам и конкуренция, и борьба за увеличение количества взломов. Самый подходящий момент напомнить — вас могут взломать, даже если вам кажется, что ваши данные никому не нужны. Во-первых, нужны, и вам в любом случае не понравится, как их используют. Во-вторых, ресурсы тоже стоят денег, а когда цена вопроса — три копейки, под удар попадают все вплоть до малого бизнеса. Украдут деньги со счета, или дампы кредиток, или хотя бы контакты клиентов для рассылки спама, атакуют через вас другую компанию, а если вообще ничего не выйдет — ну поставят генератор биткоинов и сожрут электричество.

      С такими эволюциями киберкриминала трудно бороться, но данное исследование позволяет примерно понять, как это делать.
      Все выпуски сериала — тут.

      Не исключено, что у многих жертв xDedic и взлома никакого не происходило, а пароль к RDP был добыт простым перебором. Потенциальным солдатам этой подпольной армии даже не обязательно осваивать такие примитивные скиллы: приложение для брутфорс-атаки на RDP предоставляется там же. Еще одна утилита — по сути своей троян — помогает поддерживать актуальность базы серверов и собирать информацию о доступных ресурсах. Она же сканирует систему на наличие интересного для криминала софта. Ищут инструменты для массовой рассылки сообщений (для спама), приложения для доступа к сервисам азартных игр (чтобы красть оттуда деньги), финансовое ПО (аналогично). Отдельно идет длинный список софта для платежных терминалов и кассовых аппаратов: в общем тоже понятно для чего.

      Как бороться с этим — не очень понятно, если смотреть с точки зрения потенциальных жертв. Традиционный подход, уже устаревший, но повсеместно применяемый — пытаться закрыть угрозу технологией, то есть софтом. Но в данном случае это просто не работает — нельзя закрыть софтом склонность киберпреступников объединяться для совместного заработка. ОК, подозреваю, что многие жертвы xDedic не выполняли простые рекомендации по защите доступа по RDP. Но дело не в RDP, если закрыть эту дырку, останется еще сотня других.

      А вот получение информации о подобной криминальной активности, и не просто в формате увлекательного чтива, а с готовыми индикаторами взлома (наличие утилиты-анализатора, подключение к характерным C&C итд), чем раньше, тем лучше — вполне позволит стереть пару ноликов из чека на восстановление после взлома. Добро пожаловать в будущее информационной безопасности, где работают и ценятся прежде всего знания и способы их применения на практике.

      Zero-day уязвимость во Flash, ждем патч
      Новость. Advisory Adobe. Исследование «Лаборатории».

      За последнее время уязвимостей Flash было немало, в том числе критических, в том числе уязвимостей нулевого дня — которые активно эксплуатируются в отстутствие патча. Отличием уязвимости CVE-2016-4171 стало то, что эксперты «Лаборатории» одним махом и баг нашли, и расследовали операции сравнительно молодой APT-группировки, известной как Starcruft. Исследование дает несколько больше технических деталей об уязвимости, чем обычно. Эксплойт использует один из модулей обработки метаданных, где производится чтение данных без контроля границ, что естественно может привести к переполнению буфера. Несколько последовательных операций записи данных, и атакующие получают возможность выполнения произвольного кода.


      Виновник торжества обведен рамочкой

      Помимо этого в арсенале Starcruft была обнаружена интересная схема обхода защитных решений. Для этого используется баг (возможно правильно будет назвать это недокументированной фичей) библиотеки Windows DDE, в результате чего последняя используется как прослойка между операциями выполнения эксплойта и запуском вредоносного кода. Так как Adobe Flash — известный источник проблем, защитное решение может отслеживать подозрительные операции выполнения кода от имени процесса, но в данном случае может такой хитрый ход и пропустить. Самое время сказать, что антивирус — не торт, но нет. Новая уязвимость была обнаружена в апреле с помощью автоматизированной системы детектирования эксплойтов, использующейся в наших продуктах.

      Как бы то ни было, патча уязвимости от Adobe пока нет, хотя возможно он появится прямо в ближайшее время (обещали 16 июня).

      Gmail прекращает поддержку протоколов SSLv3 и RC4 для подключения по IMAP/POP
      Новость. Анонс Google.

      Google последовательно ликвидирует поддержку небезопасных протоколов шифрования данных для собственных сервисов, в первую очередь — для GMail. Оба протокола давно признаны небезопасными и легко взламываемыми, и хотя в Google говорят, что абсолютное большинство клиентов забирают почту с помощью протокола TLS 1.2, некоторое ограниченное количество почтового софта может перестать работать — начиная с 16 июня, но поддержка будет постепенно отключаться еще месяц.

      В общем у пользователей древних смартфонов и антикварного компьютерного ПО могут возникнуть проблемы. Действия Google, как и предыдущие инициативы по отказу от SSLv3 в браузерах, можно назвать превентивными: информации об атаках для плохо защищенные соединения пока не было (возможно те, кто слушают — особо это не афишируют). Несмотря на то, что RC4 был объявлен небезопасным еще в 2001 году (первые работы вообще были в 1995-м), его продолжают исследовать, так как, увы, его по-прежнему используют. Одно из свежих исследований (PDF) показывает возможность частичной расшифровки трафика за 52 часа.

      Что еще произошло:
      Очередные hardcoded ключи нашлись в роутерах Netgear.

      Новый криптолокер написан на чистом Javascript.

      Древности:
      «Warrior-1024»

      Нерезидентный очень опасный вирус. Стандартно записывается в EXE-файлы. На время работы файла-носителя вирус остается в памяти, перехватывает int 21h и при записи в файл (ah = 40h) вместо записываемой информации подставляет текст: "… and justice for all! (US constitution) Dream Over… And the alone warrior is warrior. The powerfull WARRIOR!".

      Цитата по книге «Компьютерные вирусы в MS-DOS» Евгения Касперского. 1992 год. Страницa 94.

      Disclaimer: Данная колонка отражает лишь частное мнение ее автора. Оно может совпадать с позицией компании «Лаборатория Касперского», а может и не совпадать. Тут уж как повезет.

      Комментарии (0)

        Let's block ads! (Why?)

        Деньги не пахнут: скандально обанкротившееся издание Gawker начинают растаскивать по частям

        imageКак говорят пессимисты, все хорошее когда-нибудь кончается. Как говорят оптимисты, все плохое обязательно подходит к концу. Некоторые мудрецы утверждают, что между плохим и хорошим особой разницы нет.

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

        Президент «Сколково» Виктор Вексельберг решил вернуть свои инвестиции в медиакомпанию Gawker после банкротства издателя. «Мы рассчитываем, что процедура банкротства завершится «справедливо», в рамках действующего законодательства, и мы сможем продать свою долю в этих активах без потерь», — рассказал Вексельберг.

        Изображение usatoday

        Вексельберг стал совладельцем американского издания Gawker недавно – 21 января 2016. Он выкупил миноритарный пакет акций за неназванную сумму. Продажа была вынужденной: по данным Forbes, из-за постоянной необходимости оплачивать услуги адвокатов и судебные издержки у издания скопился многомиллионный долг.

        10 июня издатель Gawker подал заявление о банкротстве. Последней каплей стал проигранный рестлеру Халку Хогану иск на $140 миллионов.

        В интервью The New York Times 22 мая основатель Gawker Питер Дентон высказал подозрение, что иск Халка Хогана и другие иски против издания финансировал некий влиятельный бизнесмен из Кремниевой долины, недовольный редакционной политикой издания. 24 мая Forbes сообщил, что этот человек — основатель PayPal и инвестор Facebook Питер Тиль.

        Скандалы, интриги, расследования


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

        Издание появилось в 2003 году как блог. Но с тех пор вокруг Gawker выросла целая система онлайн-изданий (в нее входят в числе прочих Gizmodo, Kotaku и Jezebel). Gawker специализируется на публикации сведений личного характера о звездах шоу-бизнеса и деятелях IT-индустрии.

        В 2007 году Valleywag — одно из изданий Gawker Media — опубликовало статью «Питер Тиль — точно гей…». В статье и серии последующих материалов приводились факты и рассуждения автора о сексуальной ориентации Тиля и нескольких людей из его окружения.

        image
        Изображение ksi-finance.com

        Материалы были написаны Оуэном Томасом, который на тот момент был редактором Valleywag. По словам Томаса, который сейчас работает редактором бизнес-рубрики издания The San Francisco Chronicle, тон статьи был не агрессивным и даже «антигомофобным»:

        image
        «Как я уже говорил, я не занимался разглашением информации о сексуальной ориентации человека Питера Тиля. Я рассуждал о его сексуальной ориентации, которая и так была известна широкому кругу людей. Я считаю, что отношение к гомосексуальности ретроградно и гомофобно, и старался показать это в своих материалах».

        Более того, материалы, посвященные Тилю, были далеко не самыми громкими в истории Valleywag. Издание, которое запустилось в 2006 году и закрылось зимой 2015, писало о секретной переписке Хиллари Клинтон и сексуальных домогательствах актера Билла Косби. Немало было и скандальных видео, но ни Оуэн, ни Valleywag не предполагали, что именно история, связанная с Питером Тилем, станет одним из событий, практически поставивших на издании крест.

        image
        «Несомненно, были случаи, когда мы в своих публикациях заходили слишком далеко, – пишет Дентон. – Но эта мстительная ответная кампания, длящаяся десятилетие, совершенно неадекватна тому ущербу, который, как вы утверждаете, был нанесен».

        Иск Халка Хогана


        В октябре 2012 года Gawker опубликовали фрагмент домашнего видео актёра и рестлера Терри Боллеа, более известного под псевдонимом Халк Хоган.

        В марте 2016 года суд обязал издание выплатить Хогану $55 миллионов в качестве покрытия материального ущерба, $60 миллионов за моральный ущерб и $25 миллионов штрафа. Общая сумма, которую должен выплатить издательский дом, составляет $140 миллионов.

        image
        Изображение ria.ru

        24 мая издание Forbes опубликовало статью, в которой приводились анонимные комментарии людей из окружения Тиля. По их словам, предприниматель играл ключевую роль в финансировании судебного иска Хогана. Тиль оказал ему помощь на $10 миллионов. Спустя несколько дней предприниматель подтвердил эту информацию в интервью The New York Times. По его словам, он руководствовался не местью, а желанием защитить личную жизнь людей в будущем и Хогана в частности.

        Я могу защитить себя. Но большая часть людей, которых атакуют подобным образом — нет. Чаще всего, это гораздо менее обеспеченные люди, у которых нет нужных средств. Даже такие медийные люди, как миллионер Терри Боллеа, не могут этого сделать.

        Основатель Gawker Дентон подозревает, что новые иски против Gawker также финансируются Тилем — по крайней мере все дела ведет тот же адвокат.

        По мнению Тиля, журналистика, подобная Gawker, не заслуживает права на жизнь. «То, что они делают, чрезвычайно болезненно сказывается на любом человеке. Я считаю, что с этим нужно бороться», — сказал предприниматель.

        «Желтой прессе необходимо преподать урок», – пишет в твиттере Винод Хосла, миллиардер и венчурный капиталист. «Gawker – это бич, задевающий людей без какого-либо повода, – говорит Уэсли Чан, управляющий директор венчурной фирмы Felicis Ventures. – В этой ситуации я согласен с Тилем. Правда, тут мы вступаем в опасную область, где влиятельные и могущественные люди могут преследовать журналистов за небольшие причиненные ими неудобства».

        О Питере Тиле


        С самого детства Питер Тиль слыл гением. В 1998 году Тиль и Макс Левчин основали платёжную систему PayPal, которая, после объединения с X.com Элона Маска, была продана eBay за $1,5 миллиарда.

        В 2004 году Тиль купил 10,2% компании Facebook, инвестировав в социальную сеть $500 тысяч. Через 8 лет, когда предприниматель продал почти все акции компании, они оценивались уже более чем в $1 миллиард. Сейчас Тиль руководит несколькими венчурными фондами, занимает место в совете директоров Facebook и является одним из 10 ключевых менеджеров стартап-акселератора Y Combinator.

        По-другому характеризуют Тиля его остальные филантропическое вложения. Созданная им организация The Thiel Fellowship, даёт студентам и школьникам старших классов деньги, чтобы те бросили учебу и открыли свой бизнес.

        image
        Изображение brodude.ru

        Вместе с тем, он инвестировал большие суммы в научные проекты, которые ищут способы продления человеческой жизни. Тиль также является сооснователем проекта The Seastedaing Institute, цель которого заключается в создании плавающих городов со своим правительством и законодательной системой.

        Эффективнее лоббизма


        По мнению аналитиков, опрошенных Forbes, успех иска Хогана наверняка подстегнет других состоятельных людей последовать примеру Питера Тиля. Финансирование подобных исков позволит миллиардерам если не закрывать издания, то по меньшей мере держать их в постоянном страхе: перед лицом многомиллионных издержек не каждый редактор отважится опубликовать критическую заметку или расследование о бизнесмене. При этом финансирование исков можно осуществлять анонимно, то есть ничем не рискуя:

        «Миру уже сейчас не нравится, что миллиардеры безответственно пользуются своей властью, что Кремниевая долина прибирает к рукам такие богатства, что технологические компании получили такое влияние на СМИ… Лучшее средство для поддержания свободы высказываний – побольше высказываний».

        Солидарность с Gawker в этом конфликте проявили даже некоторые участники рынка, становившиеся мишенью для публикаций этой компании. Так, предприниматель и блогер Дейв Уайнер соглашается, что Gawker ужасна, но это не оправдывает действий Тиля: «Перед нами отличный пример явления, которое заслуживает презрения, но нуждается в нашей защите. Именно для этого и существует Первая поправка».

        Журналист и аналитик Джош Маршалл считает, что потенциально таким образом богатейшие люди получают даже больше влияния, чем с помощью лоббизма.

        image
        «Вам может не нравиться Gawker, — пишет Маршалл. — Они публиковали вещи, которые лично я публиковать постыдился бы. Но если богачи смогут, даже не раскрывая своих имен, уничтожать неугодные СМИ — это станет самой серьезной угрозой свободе слова за всю историю».

        Бизнес и ничего личного


        Как сообщается на сайте Gawker, компания обсуждает соглашение о приобретении активов с медиа-конгломератом Ziff Davis. Компания и ее основные бренды будут выставлены на аукцион. Ожидается, что в нем примут участие еще несколько потенциальных покупателей, помимо Ziff Davis.

        image
        Изображение whitehurst-ma.com

        Известно, что последний еще с 2012 года присматривался к Gawker. Дело в том, что в этом же году Хоган подал тот самый иск, который «добил» компанию. В 2012 году Ziff Davis хотел сбить цену Gawker на фоне данного иска, предполагая, что кончится все плачевно. Вопрос о том, имеет ли какое-то отношение Ziff Davis к Хогану или Тилю, остается открытым.

        В последние несколько лет этот медиа-конгломерат активно поглощает более мелкие, в том числе иностранные, медиакомпании. К концу 2015 года количество читателей изданий Ziff Davis достигло 117 миллионов. Медиа-конгломерат был представлен в 100 странах. Среди его изданий – 47 международных. Несколько новых изданий готовятся к выходу в этом году.

        По оценкам экспертов, стоимость активов Gawker находится в диапазоне $90-100 миллионов.

        Материнская компания Gawker Media Group (GMG) заявляет, что такой шаг должен сохранить работу журналистов и других сотрудников компании.

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

        Вероятно, сторонники жестокой расправы с подобными изданиями во главе с Питером Тилем ценят принцип «разделяй и властвуй». Еще один известный принцип, на который мог бы опираться Тиль, звучит так: «Месть – это блюдо, которое подают холодным». Однако, раз он утверждает, что руководствовался исключительно желанием защитить личную жизнь людей в будущем и Хогана в частности, история получается менее захватывающей.

        Довольно странно звучит другая версия случившегося: издание само довело себя до банкротства, запутавшись в исках и обвешавшись долгами. А Хоган и Тиль были всего лишь последней каплей.

        Как бы там ни было, активы Gawker имеют какую-то ценность, а потенциальные покупатели имеют виды на них и не вникают в этические вопросы.

        Комментарии (0)

          Let's block ads! (Why?)

          VIM: зачем, если есть IDE, и как?

          [Перевод] Распутывая историю Ады Лавлейс (первого программиста в истории)

          [Перевод] Чем полезен мономорфизм?

          Выступления и посты в блогах о производительности JavaScript часто обращают внимание на важность мономорфного кода, однако обычно не дается внятного никакого объяснения, что такое мономорфизм/полиморфизм и почему это имеет значение. Даже мои собственные выступления зачастую сводятся к дихотомии в стиле Невероятного Халка: «ОДИН ТИП ХОРОШО! ДВА ТИП ПЛОХО!». Неудивительно, что когда люди обращаются ко мне за советом по производительности, чаще всего они просят объяснить, что на самом деле такое мономорфизм, откуда берется полиморфизм и что в нем плохого.

          Ситуацию осложняет еще и то, что само слово «полиморфизм» имеет множество значений. В классическом объектно-ориентированном программировании полиморфизм связан с созданием дочерних классов, в которых можно переопределить поведение базового класса. Программисты, работающие с Haskell, вместо этого подумают о параметрическом полиморфизме. Однако полиморфизм, о котором предупреждают в докладах о производительности JavaScript – это полиморфизм вызовов функции.

          Я объяснял этот механизм столькими различными путями, что наконец-то собрался и написал данную статью: теперь можно будет не импровизировать, а просто дать на нее ссылку.

          Я также попробовал новый способ объяснять вещи – изображая взаимодействие составных частей виртуальной машины в виде коротких комиксов. Кроме того, данная статья не покрывает некоторые детали, которые я посчитал незначительными, излишними или не связанными напрямую.

          Динамический поиск для чайников



          Ради простоты изложения мы будем преимущественно рассматривать самые элементарные обращения к свойствам в JavaScript, как например o.x в коде ниже. В то же время важно понимать, что всё, о чем мы говорим, относится к любой операции с динамическим связыванием, будь то обращение к свойству или арифметический оператор, и применимо не только в JavaScript.
          function f(o) {
              return o.x
          }
          
          f({ x: 1 })
          f({ x: 2 })
          
          

          Представьте на минуту, что вы собеседуетесь на отличную должность в ООО «Интерпретаторы», и вам предлагают придумать и реализовать механизм обращения к свойству в виртуальной машине JavaScript. Какой ответ был бы самым банальным и простым?

          Сложно придумать что-то проще, чем взять готовую семантику JS из спецификации ECMAScript (ECMA 262) и переписать алгоритм [[Get]] слово в слово с английского языка на C++, Java, Rust, Malbolge или любой другой язык, который вы предпочли использовать для собеседования.

          Вообще говоря, если открыть случайный интерпретатор JS, скорее всего можно увидеть нечто наподобие:

          jsvalue Get(jsvalue self, jsvalue property_name) {
            // 8.12.3 здесь реализация метода [[Get]]
          }
          
          void Interpret(jsbytecodes bc) {
            // ...
            while (/* остались необработанные байткоды */) {
              switch (op) {
                // ...
                case OP_GETPROP: {
                  jsvalue property_name = pop();
                  jsvalue receiver = pop();
                  push(Get(receiver, property_name));
                  // TODO(mraleph): выкинуть исключение в strict mode, как сказано в 8.7.1 шаг 3.
                  break;
                }
                // ...
              }
            }
          }
          
          

          Это абсолютно правильный способ реализовать обращение к свойству, однако у него есть один значительный недостаток: в сравнении с современными виртуальными машинами JS наша реализация очень медленная.

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


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

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

          Эти техника оптимизации называется инлайн-кешированием и я уже писал про нее раньше. Для данной статьи не будем вдаваться в детали реализации, а обратим внимание на две важные вещи, о которых я раньше умалчивал: как и любой другой кеш, инлайн-кеш имеет размер (количество закешированных элементов в данный момент) и емкость (максимальное количество элементов, которое может быть закешировано).

          Вернемся к примеру:

          function f(o) {
              return o.x
          }
          
          f({ x: 1 })
          f({ x: 2 })
          
          

          Сколько записей будет в инлайн-кеше для значения o.x?

          Поскольку {x: 1} и {x: 2} имеют одинаковую форму (она иногда называется скрытый класс), ответ — 1. Именно это состояние кеша мы называем мономорфным, потому что нам попадались объекты только одной формы.

          Моно («один») + морф («форма»)

          А что случится, если мы вызовем функцию f с объектом другой формы?

          f({ x: 3 })
          // кеш o.x все еще мономорфен
          f({ x: 3, y: 1 })
          // а теперь?
          
          

          Объекты {x: 3} и {x: 3, y: 1} имеют разную форму, поэтому наш кеш теперь содержит две записи: одну для {x: *} и одну для {x: *, y: *}. Операция стала полиморфной с уровнем полиморфизма, равным двум.

          Если мы продолжим передавать в f объекты различных форм, уровень полиморфизма будет расти, пока не достигнет предела емкости для инлайн-кеша (например, в V8 для обращения к свойствам предел емкости будет равен четырем). После этого кеш перейдет в мегаморфное состояние.

          f({ x: 4, y: 1 }) // полиморфизм, уровень 2
          f({ x: 5, z: 1 }) // полиморфизм, уровень 3
          f({ x: 6, a: 1 }) // полиморфизм, уровень 4
          f({ x: 7, b: 1 }) // мегаморфизм
          
          


          Мегаморфное состояние нужно для того, чтобы не дать кешу бесконтрольно разрастись, и по сути означает «Здесь слишком много форм, отслеживать их дальше бесполезно». В виртуальной машине V8 кеши в мегаморфном состоянии могут все равно продолжать что-то кешировать, но уже не локально, а в глобальную хеш-таблицу. Она имеет фиксированный размер и при коллизиях значения перезаписываются.

          Небольшое упражнение для проверки понимания:

          function ff(b, o) {
            if (b) {
              return o.x
            } else {
              return o.x
            }
          }
          
          ff(true, { x: 1 })
          ff(false, { x: 2, y: 0 })
          ff(true, { x: 1 })
          ff(false, { x: 2, y: 0 })
          
          

          1. Сколько инлайн-кешей обращения к свойству объявлены в функции ff?
          2. В каком они состоянии?

          Ответы
          Кешей два и оба мономорфны, поскольку в каждый из них попадали только объекты одной формы.

          Влияние на производительность


          На данном этапе производительность различных состояний инлайн-кеша становятся очевидными:
          • Мономорфное — самое быстрое, если вы каждый раз обращаетесь к значению из кеша (ОДИН ТИП ХОРОШО!)
          • Полиморфное — линейный поиск среди значений кеша
          • Мегаморфное — обращение к глобальной хеш-таблице. Самый медленный вариант из кешированных, но все равно быстрее, чем промах кеша
          • Промах кеша — обращение к полю, которого нет в кеше. Приходится платить за переход в рантайм и использование самого общего алгоритма

          На самом деле, это только половина правды: кроме прямого ускорения кода, инлайн-кеши также работают шпионами на службе у всемогущего оптимизирующего компилятора, который рано или поздно придет и ускорит ваш код еще больше.

          Спекуляции и оптимизации


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

          function g(o) {
            return o.x * o.x + o.y * o.y
          }
          
          g({x: 0, y: 0})
          
          

          В примере выше инлайн-кешей аж семь штук: два на .x, два на .y, еще два на * и один на +. Каждый действует самостоятельно, проверяя объект o на соответствие закешированной форме. Арифметический кеш оператора + проверит, являются ли оба операнда числами, хотя это можно было бы вывести из состояний кешей операторов *. Кроме того, в V8 есть несколько внутренних представлений для чисел, так что это тоже будет учтено.

          Некоторые арифметические операции в JS имеют присущий им конкретный тип, например a | 0 всегда возвращает 32-битное целое, а +a — просто число, но для большинства остальных операций таких гарантий нет. По этой причине написание AOT-компилятора для JS является безумно сложной задачей. Вместо того, чтобы компилировать JS-код заранее один раз, большинство виртуальных машин JS имеет несколько режимов исполнения.

          Например, V8 сначала компилирует всё обычным компилятором и сразу же начинает исполнять. Позже часто используемые функции перекомпилируются с применением оптимизаций. С другой стороны, Asm.js использует неявные типы операций и с их помощью описывает очень строго ограниченное подмножество Javascript со статической типизацией. Такой код можно оптимизировать еще до его запуска, без спекуляций адаптивной компиляции.

          «Прогрев» кода нужен для двух целей:

          • Сокращает задержку при старте: оптимизирующий компилятор включается только в том случае, если код был использован достаточное количество раз
          • Инлайн-кеши успевают собрать информацию о формах объектов

          Как уже было сказано выше, написанный людьми код на JavaScript обычно содержит недостаточно информации для того, чтобы его можно было полностью статически типизировать и провести AOT-компиляцию. JIT-компилятору приходится строить догадки о том, как ведет себя ваша программа, и выдавать оптимизированный код, который подходит только при определенных допущениях. Иными словами, ему нужно знать, какие объекты используются в оптимизируемой функции. По счастливому стечению обстоятельств, это именно та информация, которую собирают инлайн-кеши!
          • Мономорфный кеш говорит: «Я видел только тип A»
          • Полиморфный кеш говорит: «Я видел только типы А1, ..., AN»
          • Мегаморфный кеш говорит: «Да я много чего видел...»


          Оптимизирующий компилятор анализирует информацию, собранную инлайн-кешами, и по ней строит промежуточное представление (IR). Инструкции IR обычно более специфичные и низкоуровневые, нежели операции в JS. Например, если кеш для обращения к свойству .x видел только объекты формы {x, y}, тогда компилятор может сгенерировать IR-инструкцию, которая получает значение по фиксированному смещению от указателя на объект. Разумеется, использовать такую оптимизацию для любого приходящего объекта небезопасно, поэтому компилятор также добавит проверку типа перед ней. Проверка типа сравнивает форму объекта с ожидаемой, и если они отличаются — оптимизированный код выполнять нельзя. Вместо этого вызывается неоптимизированный код и исполнение продолжается оттуда. Этот процесс называется деоптимизацией. Несовпадение типа — не единственная причина, по которой деоптимизация может произойти. Она также может случиться, если арифметическая операция была «заточена» под 32-битные числа, а результат предыдущей операции вызвал переполнение, или при обращении к несуществуюшему индексу массива arr[idx] (выход за пределы диапазона, разреженный массив с пропусками и т.д.).


          Становится понятно, что оптимизация нужна для устранения описанных выше недостатков:

          Неоптимизированный код Оптимизированный код
          Каждая операция может иметь неизвестные побочные эффекты и реализует полную семантику Специализация кода устраняет или ограничивает неопределенность, побочные эффекты строго известны (например, у обращения к свойству по смещению их нет)
          Каждая операция сама по себе, обучается самостоятельно и не делится опытом с соседями Операции раскладываются на низкоуровневые IR-инструкции, которые оптимизируются вместе, что позволяет устранить избыточность


          Разумеется, построение IR под конкретные формы объектов — это только первый шаг в цепочке оптимизации. Когда промежуточное представление сформировано, компилятор будет пробегаться по нему несколько раз, обнаруживая инварианты и вырезая лишнее. Этот тип анализа обычно ограничен областью процедуры и компиляторы вынужден учитывать самые худшие из возможных побочных эффектов на каждом вызове. Следует помнить, что вызов может скрываться в любой неконкретизированной операции: например, оператор + может вызвать valueOf, а обращение к свойству вызовет его getter-метод. Таким образом, если операцию не получилось конкретизировать на первом этапе, об нее будут спотыкаться все последующие проходы оптимизатора.

          Один из наиболее распространенных видов избыточных инструкций — это постоянные проверки на то, что один и тот же объект имеет одну и ту же форму. Вот так изначальное промежуточное представление может выглядеть для функции g из примера выше:

              CheckMap v0, {x,y}  ;; shape check 
          v1  Load v0, @12        ;; load o.x 
              CheckMap v0, {x,y} 
          v2  Load v0, @12        ;; load o.x 
          i3  Mul v1, v2          ;; o.x * o.x 
              CheckMap v0, {x,y} 
          v4  Load v0, @16        ;; load o.y 
              CheckMap v0, {x,y} 
          v5  Load v0, @16        ;; load o.y 
          i6  Mul v4, v5          ;; o.y * o.y 
          i7  Add i3, i6          ;; o.x * o.x + o.y * o.y
          
          

          Здесь форма объекта в переменной v0 проверяется 4 раза, хотя между проверками нет операций, которые могли бы вызвать ее изменение. Внимательный читатель также заметит, что загрузка v2 и v5 также избыточна, поскольку никакой код их не перезаписывает. К счастью, последующий проход глобальной нумерации значений удалит эти инструкции:
          ;; После ГНЗ 
              CheckMap v0, {x,y} 
          v1  Load v0, @12 
          i3  Mul v1, v1 
          v4  Load v0, @16 
          i6  Mul v4, v4 
          i7  Add i3, i6 
          
          

          Как уже было сказано выше, убрать эти инструкции стало возможно только потому, что между ними не было операций с побочными эффектами. Если бы между загрузками v1 и v2 был вызов, нам пришлось бы допускать, что он может изменить форму объекта в v0, а следовательно проверка формы v2 была бы обязательна.

          Если же операция не мономорфна, компилятор не может просто взять ту же самую связку «проверка формы и конкретизированная операция», как в примерах выше. Инлайн-кеш содержит информацию о нескольких формах. Если взять любую из них и завязаться только на нее, то все остальные будут приводить к деоптимизации, что нежелательно. Вместо этого компилятор будет строить дерево решений. Например, если инлайн-кеш обращения к свойству o.x встречал только формы A, B и C, то развернутая структура будет аналогична следующему (это псевдокод, на самом деле будет построен граф потока управления):

          var o_x
          if ($GetShape(o) === A) {
            o_x = $LoadByOffset(o, offset_A_x)
          } else if ($GetShape(o) === B) {
            o_x = $LoadByOffset(o, offset_B_x)
          } else if ($GetShape(o) === C) {
            o_x = $LoadByOffset(o, offset_C_x)
          } else {
            // в o.x попадали только A, B, C
            // поэтому мы предполагаем, что *ничего* иного быть не может
            $Deoptimize()
          }
          // Здесь мы знаем только то, что o имеет одну
          // из форм - A, B или C. Но мы уже не знаем,
          // какую именно
          
          

          У мономорфных обращений есть одно очень полезное свойство, которого нет у полиморфных: до следующей операции с побочным эффектом существует гарантия того, что форма объекта осталась неизменной. Полиморфное обращение дает только слабую гарантию «объект имеет одну из нескольких форм», с помощью которой мало что можно оптимизировать (в лучшем случае, можно было бы убрать последнее сравнение и блок с деоптимизацией, но V8 так не поступает).

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

          // Проверяем, что форма о является одной из A, B или C - иначе деоптимизируем
          $TypeGuard(o, [A, B, C])
          // Загружаем свойство, поскольку во всех трех формах смещение одинаковое
          var o_x = $LoadByOffset(o, offset_x)
          
          

          Если между двумя полиморфными проверками нет операций с побочными эффектами, вторая может также быть удалена за ненадобностью, как и в случае с мономорфными.

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

           var o_x
          if ($GetShape(o) === A) {
            o_x = $LoadByOffset(o, offset_A_x)
          } else if ($GetShape(o) === B) {
            o_x = $LoadByOffset(o, offset_B_x)
          } else if ($GetShape(o) === C) {
            o_x = $LoadByOffset(o, offset_C_x)
          } else {
            // Мы знаем, что обращение к o.x мегаморфно.
            // Во избежание деоптимизации оставим лазейку
            // для случайных объектов:
            o_x = $LoadPropertyGeneric(o, 'x')
            //    ^^^^^^^^^^^^^^^^^^^^ неизвестные побочные эффекты
          }
          // В этот момент о форме объекта "о"
          // больше ничего не известно, и могли
          // произойти побочные эффекты
          
          

          В некоторых случаях компилятор может вообще отказаться от затеи конкретизировать операции:
          • Нет способа эффективно ее конкретизировать
          • Операция полиморфна и компилятор не знает, как построить дерево решений (такое раньше происходило с полиморфным обращением к arr[i], но уже исправлено)
          • Нет информации о типе, которым операция может быть конкретизирована (код ни разу не выполнялся, сборщик мусора удалил собранную информацию о формах и т.д.)

          В этих (довольно редких) случаях компилятор выдает обобщенный вариант промежуточного представления.

          Влияние на производительность


          В итоге имеем следующее:
          • Мономорфные операции оптимизируются легче всего и дают оптимизатору простор для действий. Как сказал бы Халк — "ОДИН ТИП БЛИЗКО К ЖЕЛЕЗУ!"
          • Операции с небольшим уровнем полиморфизма, требующие проверку формы, или дерево решений, медленнее мономорфных:
            • Деревья решений усложняют поток исполнения. Компилятору сложнее распространять информацию о типах и убирать лишние инструкции. Условные переходы дерева также могут запороть производительность, если попадут в нагруженный цикл.
            • Полиморфные проверки форм не так сильно препятствуют оптимизации и все еще позволяют удалять некоторые излишние инструкции, но все равно медленнее мономорфных. Влияние на производительность зависит от того, как хорошо ваш процессор работает с условными переходами.
          • Мегаморфные или высокополиморфные операции не конкретизируются вообще, и в промежуточном представлении будет вызов, со всеми вытекающими последствиями для оптимизации и производительности CPU.

          Примечание переводчика: автор давал ссылку на микробенчмарк, однако сам сайт больше не работает.

          Необсужденное


          Я умышленно не стал вдаваться в некоторые детали реализации, чтобы статья не стала слишком обширной.

          Формы


          Мы не обсуждали, как формы (или скрытые классы) устроены, как они вычисляются и присваиваются объектам. Общее представление можно получить из моей предыдущей статьи или выступления на AWP2014.

          Нужно только помнить, что само понятие «формы» в виртуальных машинах JS — это эвристическое приближение. Даже если с точки зрения человека у двух объектов форма одинакова, с точки зрения машины она может быть разной:

          function A() { this.x = 1 }
          function B() { this.x = 1 }
          
          var a = new A,
              b = new B,
              c = { x: 1 },
              d = { x: 1, y: 1 }
          
          delete d.y
          // a, b, c, d - четыре разных формы для V8
          
          

          Поскольку объекты в JS беззаботно реализованы в виде словарей, можно применить полиморфизм по случайности:
          function A() {
            this.x = 1;
          }
          
          var a = new A(), b = new A(); // форма одинакова
          
          if (something) {
            a.y = 2;  // форма a больше не совпадает с формой b
          }
          
          

          Умышленный полиморфизм


          Во многих языках, где форма созданного объекта не может быть изменена (Java, C#, Dart, C++ и т.д.), полиморфизм также поддерживается. Возможность написать код, основанный на интерфейсах и выполняющихся в зависимости от конкретной реализации — очень важный механизм абстракции. В статически типизированных языках полиморфизм влияет на производительность аналогичным образом.

          Неудивительно, что JVM использует инлайн-кеши для оптимизации инструкций invokeinterface и invokevirtual.

          Не все кеши одинаково полезны


          Следует иметь в виду, что некоторые кеши основаны не на формах объектов, и\или имеют меньшую емкость по сравнению с другими. Например, инлайн-кеш вызова функции может иметь только три состояния: неинициализированное, мономорфное или мегаморфное. Промежуточного полиморфного состояния у него нет, потому что для вызова функции форма объекта не имеет значения, а кешируется сам объект функции.
           function inv(cb) {
            return cb(0)
          }
          
          function F(v) { return v }
          function G(v) { return v + 1 }
          
          inv(F)
          // инлайн-кеш мономорфный, указывает на F
          inv(G)
          // инлайн-кеш становится мегаморфным
          
          

          Если функция inv оптимизирована и инлайн-кеш находится в мономорфном состоянии, оптимизатор может встроить тело функции в место вызова (что особенно важно для коротких функций в часто вызываемых местах). Если же кеш в мегаморфном состоянии, оптимизатор не знает, тело какой именно функции можно встраивать, и поэтому оставит обобщенный оператор вызова в промежуточном представлении.

          С другой стороны, вызовы методов вида o.m(...) работает аналогично обращению к свойству. Инлайн-кеш вызова метода также может иметь промежуточное полиморфное состояние. Виртуальная машина V8 может встроить вызов такой функции в мономорфном, полиморфном, или даже мегаморфном виде тем же способом, как со свойством: сначала проверка типа или дерево решений, после которого располагается само тело функции. Есть только одно ограничение: метод должен содержаться в форме объекта.

          На самом деле, o.m(...) использует сразу два инлайн-кеша — один для загрузки свойства, другой для непосредственно вызова функции. Второй имеет только два состояния, как в примере выше у функции cb. Поэтому его состояние игнорируется при оптимизации вызова и используется только состояние инлайн-кеша обращения к свойству.

           function inv(o) {
            return o.cb(0)
          }
          
          var f = {
            cb: function F(v) { return v },
          };
          
          var g = {
            cb: function G(v) { return v + 1 },
          };
          
          inv(f)
          inv(f)
          // инлайн-кеш в мономорфном состоянии,
          // видел только объекты типа f
          inv(g)
          // а теперь в полиморфном, потому что 
          // кроме f видел еще и g
          
          

          Может показаться неожиданным, что в примере выше f и g имеют разную форму. Так происходит потому, что когда мы присваиваем свойству объекта функцию, V8 старается (если возможно) привязать ее к форме объекта, а не к самому объекту. В примере выше f имеет форму {c: F}, то сама форма ссылается на замыкание. Во всех примерах до этого формы содержали только признак наличия определенного свойства — в данном же случае сохраняется и его значение, а форма становится похожа на класс из языков наподобие Java или C++.

          Конечно, если потом перезаписать свойство другой функцией, V8 посчитает, что это больше не похоже на взаимоотношение класса и метода, поэтому форма изменится:

          var f = {
            cb: function F(v) { return v },
          };
          
          // Форма f равна {cb: F}
          
          f.cb = function H(v) { return v - 1 }
          
          // Форма f равна {cb: *}
          
          

          Про то, как V8 строит и поддерживает формы объектов, стоило бы написать отдельную большую статью.

          Представление пути к свойству


          К этому моменту создается впечатление, что инлайн-кеш обращения к свойству o.x — это такой словарь, сопоставляющий формы и смещение внутри класса, наподобие Dictionary<Shape, int>. На самом деле такое представление не передает глубину: свойство может принадлежать одному из объектов в цепочке прототипов, или же иметь методы доступа. Очевидно, что свойства с геттерами-сеттерами считаются менее конкретизированными, чем обычное свойства с данными.

          Например, объект o = {x: 1} можно представить как объект, свойство которого загружает и сохраняет значение в специальный скрытый слот с помощью методов виртуальной машины:

          // псевдокод, описывающий o = { x: 1 }
          var o = {
            get x () {
              return $LoadByOffset(this, offset_of_x)
            },
            set x (value) {
              $StoreByOffset(this, offset_of_x, value)
            }
            // геттер/сеттер сгенерированы виртуальной машиной
            // и невидимы для обычного JS-кода
          };
          $StoreByOffset(o, offset_of_x, 1)
          
          

          Кстати, примерно так реализованы свойства в Dart VM

          Если смотреть так, то инлайн-кеш должен быть скорее представлен в виде Dictionary<Shape, Function> — сопоставляя формы с функциями-аксессорами. В отличие от наивного представления со смещением, так можно описать и свойства из цепочки прототипов, и геттеры-сеттеры, и даже прокси-объекты из ES6.

          Премономорфное состояние


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

          Финальный совет по производительности


          Самый лучший совет касательно производительности можно взять из названия книги Дэйла Карнеги «Как перестать беспокоиться и начать жить».

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

          И только тогда, если в середине вашего нагруженного цикла вы увидите инструкцию под названием XYZGeneric или что-то будет помечено атрибутом changes [*] (то есть «меняет всё»), тогда (и только тогда) можно начинать волноваться.

          Комментарии (0)

            Let's block ads! (Why?)

            [Из песочницы] Relinx — ещё одна реализация .NET LINQ методов на C++, с поддержкой «ленивых вычислений»

            Программе Android Security Rewards исполнился 1 год

            Привет, Хабр! Год назад в программе Google Vulnerability Rewards появилась новая номинация — Android Security Rewards. За обнаружение лазейки в системе безопасности Android мы предлагали до 38 000 долларов США. С помощью таких поощрений нам удалось обнаружить и устранить множество ошибок и уязвимостей — и улучшить защиту наших пользователей.

            Это было достойное начало — и вот результаты первого года работы программы:

            • Вы прислали более 250 отчетов об ошибках, отвечающих нашим требованиям.
            • 82 исследователя получили более 550 000 долларов США в качестве вознаграждений. В среднем на одно вознаграждение пришлось 2200 долларов, а на человека — 6700 долларов.
            • Наш лучший исследователь, Питер Пи (@heisecode) из Trend Micro, получил $75 750 долларов США за 26 отчетов.
            • Пятнадцати исследователям мы заплатили не менее чем по $10 000.
            • Никому не удалось описать удаленную атаку, состоящую из цепочки уязвимостей, которая компрометирует Android TrustZone или Verified Boot. Так что главный приз остался невостребованным.

            Спасибо всем, кто в принял участие в программе, прислал качественные отчеты об ошибках и помог нам улушчить Android. Теперь защита системы стала надёжней, так что с 1 июня 2016 года мы поднимаем ставки!

            Найти уязвимость стало сложнее, так что теперь мы платим ещё больше!
            • Вознаграждение за качественный отчет об ошибке с инструкцией по ее воспроизведению увеличилось на 33%. Например, поощрение за обнаружение критической уязвимости с подтверждением теперь составляет $4000 вместо $3000.
            • Вознаграждение за отчет об ошибке с инструкцией по воспроизведению, который включает в себя CTS-тест или патч, выросло на 50%.
            • За обнаружение уязвимости ядра (из установленного приложения или с помощью физического доступа к устройству) мы платим $30 000 вместо $20 000.
            • За описание атаки, состоящей из цепочки уязвимостей, которая компрометирует Android TrustZone или Verified Boot, мы предлагаем $50 000 вместо $30 000.

            Все изменения и дополнительные условия программы подробно описаны в наших правилах.

            Хотите помочь нам найти уязвимости в системе безопасности? На сайте Bug Hunter University рассказано, как создать отчет, отвечающий всем требованиям. Помните, что чем лучше будет отчет, тем выше окажется вознаграждение. Не забудьте также просмотреть наш обновленный рейтинг критичности ошибок.

            Спасибо всем, кто помогал нам сделать ОС Android ещё защищеннее. Мы многому научились за этот год и с интересом смотрим в будущее.

            Комментарии (0)

              Let's block ads! (Why?)

              Проверка проекта OpenJDK с помощью PVS-Studio

              DevConf 2016 — шпионское видео — как и обещали — мы остановили WEB-разработку в Рунет

              SЯP wrong эncяyptioи или как скомпрометировать всех пользователей в SAP JAVA

              Всем привет, меня зовут Ваагн Варданян (тут нет опечатки, как многие думают :) ), работаю я в DSec исследователем безопасности SAP-систем, и в этой небольшой статье расскажу о связке уязвимостей в SAP, использование которых может привести к компрометации системы и как результат – доступу к критичной бизнес информации.


              С каждой новой версией SAP NW, приложения становятся все более защищёнными, и уязвимости не дают скомпрометировать систему полностью. Но бывают ситуации, когда несколько проблем безопасности, используемых вместе, все же позволяют атакующим добиться своих целей. Сегодня мы расскажем о том, как скомпрометировать SAP NW с помощью связки уязвимостей.


              В статье сначала мы поговорим о возможности получения информации из системы, об эксплуатации уязвимости, основанной на утечке информации, далее — об эскалации привилегий. Все уязвимости были найдены в последних (на момент исследования) версиях SAP (SAP NW AS JAVA 7.4). Ну что ж, понеслось.




              Введение
              На сервере SAP AS JAVA есть множество стандартных приложений, которые хранятся в папке C:\usr\sap\%SID%\J00\j2ee\cluster\apps\sap.com, где %SID% — это SID SAP-системы. Так, наша тестовая система имеет SID DM0.
              Из приведенного ниже скриншота можно понять, что в стандартной сборке SAP NW присутствует более 1400 компонентов (если установить полную сборку, то выйдет и более 2000), которые могут быть вызваны пользователями SAP'a с различными правами.



              Каждый компонент, который можно вызвать, имеет некий уровень доступа, описанный в файлах web.xml, portalapp.xml. Всего существует 4 вида прав доступа к компонентам:



              Естественно, нас будут интересовать сервлеты, приложения и компоненты, которые имеют права no_safety, либо такие, у которых права вообще не предопределены, поскольку они доступны извне, и любой неавторизованный пользователь может получить к ним доступ.
              Перейдем к первой уязвимости.


              Уязвимость разглашения информации
              После поиска файлов конфигураций файл дескрипторов, в которых есть описание прав доступа


              <property name="SafetyLevel" value="no_safety"/>
              

              или оно полностью отсутствует. Был найден webdynpro компонент tc~rtc~coll.appl.rtc~wd_chat. Вот его конфигурационный файл:



              К данному сервису можно обратится по следующему адресу:
              http:/SAP_IP:SAP_PORT/webdynpro/resources/sap.com/tc~rtc~coll.appl.rtc~wd_chat/Chat#


              Oткрываем страницу и видим некоторый функционал по отправке сообщений. Среди прочего, в нем есть возможность добавления адресатов (пользователей):



              Нажав на запись add participant, можем увидеть окно, которое предлагает поискать пользователя без авторизации.



              Очень интересно, что в списке был найден пользователь с именем Jon Snow и логином J.Snow.
              Гмм… Похоже, используя данную уязвимость, можно получить список логинов пользователей SAP. Однако, этого недостаточно для компрометации системы, поскольку после того, как 3 – 5 раз будет введет неправильный пароль, учетная запись будет блокирована. Так что давайте поищем другие уязвимости.


              SQL injection


              Следующий анонимный сервис, в котором была найдена уязвимость – UDDISecurityService.
              На сервере SAP данный сервис находится по адресу: C:\usr\sap\DM0\J00\j2ee\cluster\apps\sap.com\tc~uddi\servlet_jsp\UDDISecurityService\
              Как видно из конфигурационного файла, сервис также доступен анонимно:



              Тег servlet-class показывает, что доступ к данному сервлету можно получить с помощью SOAP-запросов. Теперь перед нами стоит задача найти структуру SOAP-запроса. Известно, что структуру запросов можно узнать, найдя wsdl-файл, в котором описан данный сервис. Получается, что нам надо найти wsdl файл, содержащий запись UDDISecurityImplBean. Используя total commander, запустим поиск.



              На сервере нашелся файл, содержащий нужную нам информацию. Поскольку он имеет wsdl-структуру, преобразовать его в SOAP-запрос можно, используя специальную утилиту. Мы выяснили, что в данном файле описано 2 метода: applyPermission и deletePermissionById.



              Выберем второй метод (deletePermissionById), сгенерируем SOAP-запрос и отправим его на сервер SAP.



              В ответе получим:



              Ответ вернул 200-ый код, но логика обработки отправленных данных непонятна. Чтобы «познакомиться» с полным функционалом данной программы, надо найти на сервере JAVA-код, обрабатывающий SAOP-запрос. И мы обнаруживаем jar-файл, в котором есть описание обработки данного запроса, и расположенный на сервере по адресу:
              C:\usr\sap\%SID%\J00\j2ee\cluster\apps\sap.com\tc~uddi\EJBContainer\applicationjars\tc~esi~uddi~server~ejb~ejbm.jar


              После декомпиляции файла можем увидеть следующие классы:



              Сама обработка запроса происходит в классе UDDISecurityBean.



              Когда мы отправляем запрос deletePermissionById, видно, как появляется конструктор PermissionsDao(), который вызывает функцию deletePermision. Переходим в класс PermissionsDao.



              Данные, передаваемые через SOAP-запрос, используются для обращения к базе данных сервера SAP без фильтрации. Можно предположить, что тут есть SQL injection. Чтобы наверняка убедиться в этом, необходимо отправить специальный запрос для SQL injection и посмотреть логи базы данных сервера SAP. Файлы логов базы данных находятся по умолчанию в папке C:\usr\sap\%SID%\J00\j2ee\cluster\server0\log\system\ и называются по умолчанию database_NN.N.log, где N – число от 0 до 9 включительно.
              Отправим следующий запрос:



              В ответе также получим 200-ый код:



              Но в логах базы данных можно заметить следующее:



              Теперь точно можно говорить о том, что у нас есть анонимная SQL-инъекция в базу данных SAP. Удалим логи с сервера и отправим следующий запрос. Если на сервере в логах не возникнут ошибки, то структура SQL-запроса правильная.



              Ошибок нет.



              Теперь новая задача — найти запрос, который поможет получить критичные данные из базы данных SAP, например, хеш пароля Jon Snow. Из документации SAP NW AS JAVA известно, что данные о пользователях (логин, именa, хеши пароля) хранятся в таблице UME_STRINGS.
              Запрос для получения всех данных из UME_STRINGS имеет следующий вид:




              Как видно, данная SQL injection vulnerability не error based, а адаптер, который используется в этом сервлете и не поддерживает sleep() функцию. Будем использовать метод умножения таблиц для увеличения времени обработки запроса и превратим данную уязвимость в time-based SQL injection. Для этого надо найти таблицу, в которой всегда во всех SAP-серверах будут содержаться данные. Такая таблица — J2EE_CONFIG, в которой хранится информация о конфигурации компонентов.


              Oправим следующий запрос:



              Сервер, получая запрос, пробует извлечь данные из БД, предварительно умножив 2 таблицы — UME_STRINGS и J2EE_CONFIG. Поскольку в таблицах хранятся данные большого объёма, произойдет временная нагрузка на сервер.



              А ответ мы получаем спустя 32 секунды. И – готово: time-based SQL injection.



              Получение хеша администратора
              Как уже говорилось выше, захешированные пароли хранятся в таблице UME_STRINGS, которая имеет следующую структуру:



              В таблице UME_STRINGS.PID хранятся имена пользователей.
              UME_STRINGS.ATTR = 'j_password' показывает, что пользователь создан и присутствует в SAP AS JAVA стеке.
              UME_STRINGS.VAL хранит хеши паролей от пользователей, логины которых записаны в UME_STRINGS.PID.
              Выходит, что надо подобрать данные, содержащиеся в поле UME_STRINGS.VAL. Базовый SQL-запрос для injection выглядит так:


              SELECT COUNT(*) FROM  J2EE_CONFIG, UME_STRINGS WHERE UME_STRINGS.ATTR='j_password' AND UME_STRINGS.PID LIKE '%J.Snow%' AND UME_STRINGS.VAL LIKE '%'
              

              Известно, что пароль хранится в базе данных SAP в захешированном виде, алгоритм хеширования может быть следующим:
              SAPSHA
              SSHA
              SHA
              SHA-512


              Т.е. в хеше паролей могут быть такие символы:


              1234567890QWERTYUIOPASDFGHJKLZXCVBNM*.,{}#+:-=qwertyuiopasdfghjklzxcvbnm/{SPACE}
              

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



              Ответ будет задержан на 1 секунду.



              Автоматизируя этот процесс, получим хеш от пользователя Jon Snow.


              {SHA-512, 10000, 24}YXNkUVdFMTIzzbAIcuqnw5RzpmdgZ38PWjhBeaGzHkV6XINN7ZDqxqgr0nYxfCaE5ncdK7kzzkzryJAn42qv9YlY034Llr4b8Rv1534chnIf1i8jZE6ylzTV5XuzvUlaXQ== 
              


              Как видно, пароль захеширован алгоритмом SHA-512. На этом исследование бы закончилось, если бы не третья уязвимость.


              Криптографическая ошибка, эскалации привилегий
              Эта уязвимость была найдена случайно :-)
              С помощью SQL injection получили хеш пароля пользователя Jon Snow:


              {SHA-512, 10000, 24}YXNkUVdFMTIzzbAIcuqnw5RzpmdgZ38PWjhBeaGzHkV6XINN7ZDqxqgr0nYxfCaE5ncdK7kzzkzryJAn42qv9YlY034Llr4b8Rv1534chnIf1i8jZE6ylzTV5XuzvUlaXQ== 
              

              Хммм. Как видно, в конце хеша есть символы ==. А что будет, если мы сделаем base64decode?




              Что? Как? Пароль? Есть единственный способ проверить, действительно ли это пароль от Jon'a — зайти на портал, используя логин J.Snow и пароль asdQWE123.



              Ура! Я администратор! Но как? Надо разобраться, с чем связан тот факт, что пароль находится в формате base64 в БД.


              В результате поска, мы нашли файл sap.com~tc~sec~ume~core~impl.jar, который находится в папке: C:\usr\sap\DM0\J00\j2ee\cluster\bin\ext\com.sap.security.core.sda\lib\private. Он содержит функции, которые отвечают за хеширование пароля пользователей, проверку их валидности, блокировку пользователей и т.д. Один из основных классов — PasswordHash. Рассмотрим этот класс подробнее.



              Он имеет 2 конструктора, один из которых


                public PasswordHash(String user, String password) 
                { 
                  this._user = user; 
                  this._password = password; 
                  this._extra = null; 
                } 
              

              Как мы видим, он инициализирует внутренние переменные user и password.
              Чтобы из пароля получить хеш, используется другая функция getHash класса PasswordHash.



              Как видно из строки 114, эта функция вызывает createHashWithIterations функцию, которая принимает случайное значение на вход в качестве соли для генерации хеша. Перейдем в функцию createHashWithIterations(salt)



              На строке 184 инициализируется переменная output, хранящая байты введенного пароля пользователя.
              В строке 185 создается новая переменная pass_n_salt, состоящая из байтов пароля и случайной соли, сгенерированной в строке 112.
              Далее в строке 191 вызывается функция hashWithIterations, принимающая на вход 2 параметра — output и pass_n_salt. Заметим, что в output хранится пароль asdQWE123 в байтах.



              Так, интересно. Рассмотрим каждую строку по отдельности:
              Строка 238 инициализирует переменную output, в которой записываются данные из переменной data (первые байты переменной data – пароль asdQWE123).
              Строка 241 инициализируется переменная md класса MessageDigest, которая будет отвечать за хеширование данных.
              Строка 243 начинает цикл для хеширования, _iterations = 10000.
              Строки 244-245 хешируют данные по алгоритму SHA-512 и записываются в переменную data.
              Строка 246, переменная output обнуляется.
              Строка 247, в переменную output записываются данные из переменной pass (asdQWE123).
              Строка 248, в конец переменной output записываются данные из data.


              Получатся, что переменная output будет иметь следующую структуру:



              Вся эта логика будет исполнена 10 000 раз, и в последнем шаге цикла в начало переменной output будет добавлен пароль, после пароля – захешированные данные. Тем самым, первые байты переменной output будут состоять из незахешированого пароля.
              Блок-схема уязвимого участка кода:


              pass = plain_pass
              output = [plain_pass]+[random_byte]


              i=0
              data = sha_512(output)
              output = [NULL]
              output = [plain_pass]+[data]
              for(i)i = i + 1
              if i==10000
              exit_from_loop


              output == «asdQWE123blablabla»


              Ошибка программистов состояла в том, что они не хешируют данные в последнем шаге цикла for. Данная уязвимость уже закрыта, и исправление выглядит вот так:


              pass = plain_pass
              output = [plain_pass]+[random_byte]


              i=0
              output = [plain_pass]+[data]
              data = sha_512(output)
              for(i)i = i + 1
              if i==10000
              exit_from_loop



              Как мы видим, SAP поменял порядок шагов, теперь сначала происходит инициализация переменной оutput, а затем хеширование данных переменной.


              Заключение


              Итак, давайте посмотрим, какие ноты безопасности выпустил SAP для исправления данных уязвимостей.


              Разглашение пользователей, логинов – SAP nota 2255990, уязвимость была исправлена 8-ого мая 2016-ого года. Имеет уже CVE-шку CVE-2016-3973 (CVSS v3 7.5).
              Список уязвимых версий SAP:



              Для исправления SQL injection была выпущена SAP security note 2101079, была исправлена 9-ого февраля 2016-ого года, CVE-2016-2386 (CVSS v3 9.1).
              Список уязвимых версий SAP:



              Уязвимость с неправильной реализацией хеширования паролей лечится нотой 2191290. Нота выпущена 12 января 2016-ого, CVE-2016-1910 (CVSS v3 5.3).
              Список уязвимых версий SAP:



              Конечно, кто-то из вас может сказать, мол, установили какой-то «кривой сервер» и нашли баги, но и для этого есть статистика только по разглашению списка пользователей SAP-a. Сканирование проводилось по 7348 SAP-серверам, которые доступны через Интернет.



              Статистика по каждому порту



              В сумме выходит, что, к уязвимости разглашения информации подвержены около 1013 серверов (~14%)



              Ну и еще одна табличка по статистике ДОСТУПНОСТИ сервлета в котором может быть уязвимость SQL injection (если еще не установлен патч)



              Суммарно – 2174 серверов, что составляет ~30%


              Выходит, что нужно делать?
              Нужно патчиться, товарищи администраторы.
              Да, и напоследок: хочешь у нас работать и находить еще более крутые баги – присылай свое резюме сюда

              Комментарии (0)

                Let's block ads! (Why?)