DDOS любого сайта с помощью Google Spreadsheet

http://chr13.com/2014/03/10/using-google-to-ddos-any-website/
  • Перевод
Google использует своего «паука» FeedFetcher для кэширования любого контента в Google Spreadsheet, вставленного через формулу =image(«link»).

Например, если в одну из клеток таблицы вставить формулу
=image("http://example.com/image.jpg")
Google отправит паука FeedFetcher скачать эту картинку и закэшировать для дальнейшего отображения в таблице.

Однако если добавлять случайный параметр к URL картинки, FeedFetcher будет скачивать её каждый раз заново. Скажем, для примера, на сайте жертвы есть PDF-файл размером в 10 МБ. Вставка подобного списка в таблицу приведет к тому, что паук Google скачает один и тот же файл 1000 раз!
=image("http://targetname/file.pdf?r=1")
=image("http://targetname/file.pdf?r=2")
=image("http://targetname/file.pdf?r=3")
=image("http://targetname/file.pdf?r=4")
...
=image("http://targetname/file.pdf?r=1000")

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

Атакующему даже необязательно иметь быстрый канал. Поскольку в формуле используется ссылка на PDF-файл (т.е. не на картинку, которую можно было бы отобразить в таблице), в ответ от сервера Google атакующий получает только N/A. Это позволяет довольно просто многократно усилить атаку [Аналог DNS и NTP Amplification – прим. переводчика], что представляет серьезную угрозу.



С использованием одного ноутбука с несколькими открытыми вкладками, просто копируя-вставляя списки ссылок на файлы по 10 МБ, паук Google может скачивать этот файл со скоростью более 700 Мбит/c. В моем случае, это продолжалось в течение 30-45 минут, до тех пор, пока я не вырубил сервер. Если я все правильно подсчитал, за 45 минут ушло примерно 240GB трафика.

Я удивился, когда увидел объем исходящего трафика. Еще немного, и я думаю, исходящий трафик достиг бы 1 Гбит/с, а входящий 50-100 Мбит/с. Я могу только представить, что произойдет, если несколько атакующих будут использовать этот метод. Паук Google использует не один IP-адрес, и хотя User-Agent всегда один и тот же, редактировать конфиг веб-сервера может быть слишком поздно, если атака застанет жертву врасплох. Благодаря простоте использования, атака легко может продолжаться часами.

Когда обнаружился этот баг, я стал гуглить инциденты с его использованием, и нашел два:
Статья, где блогер описывает, как случайно атаковал сам себя и получил огромный счет за трафик. [Перевод на хабре – прим. переводчика].
Другая статья описывает похожую атаку с помощью Google Spreadsheet, но сначала, автор предлагает спарсить ссылки на все файлы сайта и запустить атаку по этому списку с использованием нескольких аккаунтов.

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

Вчера я отправил описание этого бага в Google и получил ответ, что это не уязвимость, и не проходит по программе Bug Bounty. Возможно, они заранее знали о нём, и действительно не считают это багом?

Тем не менее, я надеюсь, они пофиксят эту проблему. Просто немного раздражает, что любой может заставить паука Google доставить столько проблем. Простой фикс заключается в том, чтобы скачивать файлы пропуская дополнительные параметры в URL [На мой взгляд, это очень плохой фикс. Возможно, стоит ограничить пропускную способность или лимитировать количество запросов и трафик в единицу времени и при этом не скачивать файлы больше определенного размера – прим. переводчика].
Метки:
Поделиться публикацией
Похожие публикации
Комментарии 62
  • +55
    Ой зря мне кажется вы выложили это…
    • +41
      Это статья есть на Hacker News. Так что думаю от появляния ее на хабре гораздо хуже не будет
      • +1
        Этой статье несколько лет, читал давным давно где то. Уверен — ничего плохого от этой статьи не произойдет, кому надо и так об этом знал.
        • +4
          Не знаю, совпадение или нет, у меня сейчас Хабр был не доступен около получаса
      • +18
        В сочетании Google Apps Script это просто готовая «машина DDoS»
        Теперь фраза «Do more with Google.» раскрывается в новом свете:)
        • +13
          интересно, если вставить ссылку на картинку, хостящуюся на google, он сам себя заддосит? :)
          • +1
            Не думаю, что даже при сильном желании можно хоть как-то заддосить Google :)
            • +3
              По ходу чтения строк
              это не уязвимость, и не проходит по программе Bug Bounty.

              тоже подумал о том, чтобы заставить гугл ддосить себя, до тех пор пока не сочтут это багом. :)
              • +1
                Гугл высосет сам себя и сколлапсирует в черную дыру.
              • –1
                Не на картинку, а на Google Chrome :)
              • –3
                Don't be evil
              • 0
                Вот Вы кому-то бизнесс накрыли :)
                PS. Если с 2012 года гугл об этом знает… возможно это кому-то нужно?
                • +5
                  Ну со стороны атакуемого источник атаки в данном случае достаточно легко обнаружить и зафильтровать
                  • 0
                    Их спредшит разве не умеет for?
                    • 0
                      И? Как это позволит обойти фильтр по рефереру или по IP (если запросы идут через сервер гугла)?
                      • 0
                        Нет, по рефереру и IP не поможет так как можно создать 1000и запросов сразу (for i in 1000000 do =image:http://google.com?=i done грубо говоря). Не знаю сколько их клиент сможет понаоткрывать соединений правда.
                • –1
                  Меня лично в этой истории больше всего напрягает, что feed fetcher игнорирует robots.txt (why, godgoogle, why?!)
                  • +6
                    robots.txt — это ж для поиска только.
                    А тут прямые ссылки.
                    • –1
                      Скажем так, я не против того чтобы «неиндексирующие» боты «по-особому» читали robots.txt

                      Но было бы удобнее если бы они его все же читали и могли получать из него особые указания (можно было и предусмотреть для этого бота особые команды. Тогда эта проблема с DDOS решалась бы довольно просто)
                      • +3
                        Да, было бы удобнее, но если запрашивает _не поисковик_, зачем его читать?
                        • +10
                          запрашивает «робот». В конце концов файл называется robots.txt а не searchbots.txt :)
                          • –1
                            Однако, директивы его, на текущий момент, предназначены именно для поисковых роботов.
                            • 0
                              Так я ж разве сие отрицаю?

                              Я лишь считаю что такое положение дел видится менее удобным.
                              • 0
                                Тогда, боюсь, ваш комментарий был воспринят не так, как вы ожидали, в том числе и мной
                                • 0
                                  Я же пишу "было бы удобнее"… то есть могло бы быть — но не сбылось :(
                            • 0
                              Возьмём другую ситуацию. К примеру, у ВКонтакте есть свой парсер статей со сторонних сайтов. Допустим, у вас встала задача написать что-нибудь похожее на такое. Придет ли вам в голову анализировать robots.txt прежде чем обрабатывать ссылку, которую оставил ваш пользователь? Осмелюсь предположить, что скорее всего, нет.
                              • +1
                                Это — не самая плохая идея.

                                Нет, конечно, there is more than one way to skin a cat, но продумать простой и доходчивый вариант управления доступом со стороны хозяев внешнего сайта — стоит.

                                А еще стоит все-таки подумать о возможности превращения такого изделия в инструмент «мелкого дедоса»
                            • +1
                              Robots.txt поддерживают не только поисковики, но и некоторые программы (типа Xenu или Teleport Pro). Поэтому, например, для защиты от парсинга имеет смысл добавлять туда соответствующие директивы.
                              • 0
                                Действительно вежливо со стороны любой автоматики его читать.
                        • +2
                          Насколько помню, robots.txt — лишь рекомендация индексирования, к тому же связана с поисковой выдачей.
                          • +2
                            Yahoo pipes не делает fetch страниц с сайта, закрытого с помощью robots.txt
                            В принципе, схожая ситуация.
                        • 0
                          А этот FeedFetcher ходит с разных ip? Разве нельзя его тупо забанить? Или он ходит оттуда же, откуда и индексатор гугла?
                          • 0
                            С разных, но пишут, что User-Agent всегда один и тот же, так что заранее забанить, думаю, можно…
                            • +5
                              К варианту «как сломать» в пост стоит, в таком случае, добавить «как лечить», думаю…
                          • +1
                            Интересно, сколько своих серверов ляжет из-за тестов?
                            • +8
                              Сделал по примеру *.pdf файл, замену адреса на *.php файл и получил такой запрос от гугла

                              10.03.2014 16:34:12
                              Array
                              (
                              [REDIRECT_STATUS] => 200
                              [HTTP_HOST] => ***
                              [HTTP_X_SHINDIG_DOS] => on
                              [HTTP_CACHE_CONTROL] => no-cache, no-store
                              [HTTP_CONNECTION] => Keep-alive
                              [HTTP_USER_AGENT] => Mozilla/5.0 (compatible) Feedfetcher-Google; (+http://www.google.com/feedfetcher.html)
                              [HTTP_ACCEPT_ENCODING] => gzip,deflate
                              [PATH] => /usr/local/bin:/usr/bin:/bin
                              [SERVER_SIGNATURE] =>
                              [SERVER_SOFTWARE] => Apache
                              [SERVER_NAME] => ***
                              [SERVER_ADDR] => ***
                              [SERVER_PORT] => 80
                              [REMOTE_ADDR] => 66.249.81.232
                              [DOCUMENT_ROOT] => /var/www/***/www
                              [SERVER_ADMIN] => [no address given]
                              [SCRIPT_FILENAME] => /var/www/***/www/somepdf.php
                              [REMOTE_PORT] => 54687
                              [REDIRECT_URL] => /some.pdf
                              [GATEWAY_INTERFACE] => CGI/1.1
                              [SERVER_PROTOCOL] => HTTP/1.1
                              [REQUEST_METHOD] => GET
                              [QUERY_STRING] =>
                              [REQUEST_URI] => /some.pdf
                              [SCRIPT_NAME] => /somepdf.php
                              [PHP_SELF] => /somepdf.php
                              [REQUEST_TIME] => 1394454852
                              )

                              А что если на уровне системы блокировать по USER_AGENT?
                              • –3
                                Так и надо сделать, вероятно.
                              • +23
                                nginx. Первая ссылка в гугле.

                                http {
                                 
                                     map $http_user_agent $limit_bots {
                                         default '';
                                         ~*(google|bing|yandex|msnbot|Feedfetcher-Google) $binary_remote_addr;
                                     }
                                 
                                     limit_req_zone $limit_bots zone=bots:10m rate=1r/m;
                                 
                                     server {
                                         location / {
                                             limit_req zone=bots burst=5 nodelay;
                                         }
                                     }
                                 }
                                • +4
                                  '|Feedfetcher-Google' я зря дописал, ~* — регистронезависимый, так что этой строки не нужно.
                                  • 0
                                    Вы вообще зря его редактировали, добавление поиска feedfetcher-google дублирует поиск просто робота google (1ый в списке).
                                • 0
                                  Как проверить, что моя таблица на гугл.докс с запросами на картинку + параметр, работает?
                                  Спортивный интерес, Вы не подумайте ничего лишнего: О
                                  • 0
                                    Я запускал синатру, она в консоль пишет все запросы и ip (изменить адрес и порт на свои):

                                    ruby -rsinatra -e'set :public_folder, "."; set :bind, "192.168.0.102"; set :port, 8080;'
                                    

                                    Вывод части теста:

                                    Скрытый текст
                                    66.249.83.56 — - [10/Mar/2014 19:04:06] «GET /__sinatra__/157 HTTP/1.1» 404 457 0.0031
                                    66.249.83.56 — - [10/Mar/2014 19:04:06] «GET /__sinatra__/158 HTTP/1.1» 404 457 0.0015
                                    66.249.83.56 — - [10/Mar/2014 19:04:06] «GET /__sinatra__/159 HTTP/1.1» 404 457 0.0008
                                    66.249.83.56 — - [10/Mar/2014 19:04:07] «GET /__sinatra__/160 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:07] «GET /__sinatra__/161 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:07] «GET /__sinatra__/162 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:07] «GET /__sinatra__/163 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:08] «GET /__sinatra__/164 HTTP/1.1» 404 457 0.0012
                                    66.249.83.56 — - [10/Mar/2014 19:04:08] «GET /__sinatra__/165 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:08] «GET /__sinatra__/166 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:08] «GET /__sinatra__/167 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:09] «GET /__sinatra__/168 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:09] «GET /__sinatra__/169 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:09] «GET /__sinatra__/170 HTTP/1.1» 404 457 0.0015
                                    66.249.83.56 — - [10/Mar/2014 19:04:09] «GET /__sinatra__/171 HTTP/1.1» 404 457 0.0016
                                    66.249.83.56 — - [10/Mar/2014 19:04:09] «GET /__sinatra__/172 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:10] «GET /__sinatra__/173 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:10] «GET /__sinatra__/174 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:10] «GET /__sinatra__/175 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:10] «GET /__sinatra__/176 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:11] «GET /__sinatra__/177 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:11] «GET /__sinatra__/178 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:11] «GET /__sinatra__/179 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:11] «GET /__sinatra__/180 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:11] «GET /__sinatra__/181 HTTP/1.1» 404 457 0.0013
                                    66.249.83.56 — - [10/Mar/2014 19:04:12] «GET /__sinatra__/182 HTTP/1.1» 404 457 0.0014
                                    66.249.83.56 — - [10/Mar/2014 19:04:12] «GET /__sinatra__/183 HTTP/1.1» 404 457 0.0015
                                    ^C66.249.83.56 — - [10/Mar/2014 19:04:12] «GET /__sinatra__/184 HTTP/1.1» 404 457 0.0013
                                  • +4
                                    А если сюда еще и функцию GOOGLECLOCK() добавить…
                                    • +1
                                      Подскажите а такая схема поможет?

                                      RewriteCond %{HTTP_REFERER} !^$
                                      RewriteCond %{HTTP_REFERER} !^http://(www\.)?masite\.ru/ [nc]
                                      RewriteRule .*\.(gif|jpe?g|png|bmp|pdf|zip|rar|mp3|js)$ — [F]
                                      • +23
                                        Никто не любит апач. :)
                                        • +9
                                          Во-первых, есть мнение, что при неблагоприятном стечении обстоятельств апач рискует умереть еще до выполнения mod_rewrite.
                                          Во-вторых, эта схема защищает только картинки — но злоумышленник не обязан загружать именно их. Ведь ему не нужен результат в виде картинки на экране — ему нужен запрос к серверу. А значит, он вполне может поставить ссылки на главную страницу сайта.
                                          В-третьих, Referer — это необязательный заголовок. Браузеры для параноиков не будут передавать его вам.
                                      • 0
                                        А неужели нет никакого заголовка, который бы сообщал браузеру о том, что «данный файл неизменен относительно query-части в location»?
                                        • 0
                                          Теоретически можно делать редирект на урл без параметра запроса. А тот урл уже будет говорить not-modified
                                          • 0
                                            Нет, таких способов нет. Есть редиректы, есть canonical url, но оба способа работают только после того, как запрос с новой query-частью уже был отправлен. Еще я где-то видел альтернативные url — но там можно указать лишь конечное число записей, злоумышленник же всегда придумает что-то еще.
                                          • 0
                                            Надеюсь, писатели облачных хостингов добавят защиту от этого в свои конфиги. Иначе действительно можно высосать сколько угодно трафика (который в облаках оплачивается помегабайтно), и владелец аккаунта получит счет на десятки тысяч баксов.
                                            • –1
                                              google уважает robots.txt, не? можно запретить там все большие файлы.
                                              • +3
                                                FeedFetcher не является поисковым роботом, он, фактически, загружает для пользователя указанные пользователем же материалы.
                                              • –2
                                                Почти такой же баг есть и у поискового робота
                                                • +1
                                                  > Вчера я отправил описание этого бага в Google и получил ответ, что это не уязвимость, и не проходит по программе Bug Bounty. Возможно, они заранее знали о нём, и действительно не считают это багом?

                                                  Надо тогда натравить Spreadsheet на сервисы Google, пусть отрабатывают фичу :)
                                                  • +2
                                                    К слову говоря — вконтакте тоже забират своим сервером картинки с сайтов…
                                                    Вероятно и им можно уложить сайт, чуть позже даже проверю

                                                    Даже проверил:
                                                    87.240.182.189 — - [11/Mar/2014:12:49:38 +0300] «GET /images/index.jpg HTTP/1.1» 206 80802 "-" «Mozilla/5.0 (compatible; vkShare; +http://vk.com/dev/Share)»
                                                    • 0
                                                      И фейсбук тоже должен.
                                                      • +1
                                                        И gmail с недавних пор выкачивает картинки из писем.
                                                        • +3
                                                          Теперь идеальный DDoS будет выглядеть как публикация картинки в спредшит, отправления ссылки на неё в гмайл и запощиванием в свой фейсбук и вконтакт.

                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.