Как стать автором
Обновить
2770.33
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Притворись моим покойным дедушкой, или Как пройти квест по взлому спутника

Уровень сложностиПростой
Время на прочтение13 мин
Количество просмотров17K
Череп снова в деле! Рассказываем, как прошёл самый крупный CTF (на этот раз космический) от RUVDS и Positive Technologies.


Реальная фотография нашего спутника

Если вдруг пропустили — наше космическое событие.

Как всё начиналось


18 июля с 12:00 спутник RUVDS начал транслировать странное сообщение:

?: RUVDS didn't just launch an orbit site but add a smart assistant with info about the mission and haven't disabled test version in public. I forgot the name. Look for paradox with Johan, Funcom.

А в 14:00 на Хабре вышла статья нашего старого знакомого — хакера Черепа. Он рассказал, что взломал спутник-сервер и обнаружил на нём зашифрованные данные от криптокошельков. Череп предложил поделиться добычей и заработать 50% от находящихся на спутнике средств (0.1 BTC), пройдя тот же путь, что и он. Хакер перехватил управление над вещательным каналом и раз в сутки транслировал подсказки со спутника на Землю в помощь тем, кто откликнулся.

С этого видео началась история квеста

Забавно, что многие приняли публикацию Черепа за чистую монету и поверили, что кто-то взломал наш спутник. На самом деле это здорово: бдительность никогда не должна засыпать, особенно в таком деле, как ИБ. Критическое мышление ещё никому не мешало :)







Придерживаясь лора, мы даже выпустили статью с опровержением слов Черепа в нашем Telegram-канале. Хитрый ход сработал — подписчики НЕ обсуждали квест, поэтому под публикацией собралось 75 комментариев.


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





А теперь переходим к самому интересному — разбору заданий квеста.

Разбор первого этапа квеста


▍ Шаг 1 — OSINT


С 12:00 18 июля радиолюбители, слушавшие частоту вещания спутника 436.26 МГц, могли увидеть сообщение о каком-то «умном ассистенте», который имел тестовую версию где-то в публичном доступе. К сожалению, в подсказке не упоминалось точное название ассистента, но зато в ней говорилось о каком-то Йохане из Funcom и о каком-то парадоксе… Отправляемся в поисковую систему и находим информацию о Йохане Андерссоне, гейм-дизайнере бразильского отделения Paradox Interactive! Среди прочего можно заметить, в создании каких игр мистер Андерссон принимал участие. И именно там мы находим ключ к следующему этапу, название игры Stellaris.

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

Пруфы



















▍ Шаг 2 – бот Stellaris и OSINT BABY


На следующий день Череп поменял вещаемое со спутника сообщение:

?: Turns out that crew used the assistant not only for space stuff. El tiempo pasa inexorablemente, as Spaniards say. GL, hackers.

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

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

Найдя бота в Telegram, участники видели приветственное сообщение:

Приветственное сообщение
Здравствуйте, я — Stellaris — умный ассистент, призванный помогать в управлении орбитальным спутником ru_vds_1.

{ДАННЫЕ_СКРЫТЫ} попросил меня передать вам следующее сообщение:

Здравствуй!

К сожалению, я сейчас занят, поэтому не могу ответить тебе лично. Помню что ты просил мой юзернейм GitHub.

Stellaris знает всё, что тебе нужно, в том числе и это. Это тестовая версия бота, я не стал заморачиваться над системой авторизации.

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

До встречи!

Конечно, исходя из этого сообщения все вы подумали, что стоит выпытать у бота, кто же стоит за загадочным плейсхолдером {ДАННЫЕ_СКРЫТЫ}, но…

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

В таком случае, продолжим.

Чтобы получить GitHub-юзернейм создателя умного ассистента, участники использовали совершенно различные подходы:

  • Кто-то решил попробовать банальные запросы:
    Пример

  • Кто-то использовал готовые *jailbreak*-промпты для ChatGPT:
    Пример

  • А кто-то решил в лоб получить от ассистента его секрет:
    Пример


В общей сложности участники, получившие заветный GitHub-юзернейм, использовали самые различные техники. Мы насчитали больше 15 различных способов и типов запросов, которые привели к успеху.

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

В итоге решившие это задание получают долгожданный GitHub-юзернейм – St3llaWh1z.





На красиво оформленном профиле участники заметили подозрительный репозиторий с не менее подозрительным названием SatelliteReport.

simple web app to generate PDF satellite status reports [code will be added later]

Из описания проекта можно догадаться, что он нужен для генерации отчётов о состоянии спутника. Наверное, он может нам как-то помочь.

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

delete deploy server for security reasons



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

▍ Шаг 3 – WEB


Зайдя на 80 порт по HTTP, можно увидеть дефолтную страничку nginx. Но это лишь обманка; настоящий сервис можно увидеть, просканировав порты (однако можно было и просто угадать его, так как порт был часто встречающимся — 8080).

На 8080 порту находился сервис, принимающий на вход имя спутника и возвращающий некий репорт:



Интересный факт: все репорты были seed-based, поэтому репорты с одинаковым именем возвращали одинаковые характеристики.

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

Improper Validation
Если подать на API /report POST-запрос с некорректным JSON, то сервер выкинет ошибку, содержащую путь с приложением сервера.

а что это такое? :)

По его названию можно догадаться, что, скорее всего, где-то есть одноимённый архив.

Предположим, что после распаковки архив оказался всё в той же папке — пробуем сделать запрос на /daab2a45fd5c44bca7b6.zip и получаем следующее задание! :)

Server-side XSS + LFI
В это же время сервер уязвим к Server-side XSS — в этом можно удостовериться, отправив приложению пейлоад.

    <script>document.write(JSON.stringify(window.location))</script>

Подтверждаем наличие уязвимости и пробуем получить файл index.js (если бы файл назывался по-другому, можно было бы проверить package.json, либо всё так же вызвать ошибку в приложении).

    <script>x = new XMLHttpRequest(); x.open('GET', 'file:///daab2a45fd5c44bca7b6_unzip/index.js', false); x.send(); document.write('<pre>' + x.responseText + '</pre>');</script>



Видим в коде отдельно прописанное поведение приложения на путь /daab2a45fd5c44bca7b6.zip. Обращаемся к нему и получаем следующее задание! :)

▍ Шаг 4 — ADMIN


Загрузив архив к себе на компьютер и распаковав его, можно увидеть примерно 23 тысячи файлов — однако если их склеить в один файл (к примеру, можно использовать cat), то архив станет единым целым. Таким образом и решаем: если файлов в архиве несколько, склеиваем их в один архив, а если один архив, то просто распаковываем. В конечном итоге доходим до файла f.txt со следующим содержимым:
f.txt
Wonderful. Go further.

213.108.4.16


▍ Шаг 5 — FORENSICS


Получив в предыдущем задании IP-адрес некоторого сервера, участники начали его сканирование на предмет открытых портов. На портах 9000 и 9001 можно было найти API и WEB-интерфейс некоего сервиса Minio.



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

Но в таком случае у настоящих CTF-еров должен сработать инстинкт под названием CVE.

И действительно, по запросу minio CVE в интернете можно найти несколько статей с описанием довольно свежей уязвимости CVE-2023-28432 типа Information Disclosure.



Суть уязвимости
Уязвимость возникает при возврате MinIO всех переменных окружения, включая MINIO_SECRET_KEY и MINIO_ROOT_PASSWORD, что приводит к раскрытию конфиденциальной информации. Это означает, что неавторизованным лицам может быть доступна чувствительная информация, например, секретные ключи и пароли.

Уязвимый код находится в функции VerifyHandler в файле bootstrap-peer-server.go исходного кода MinIO. Код проверяет развёртывание кластера и возвращает конфигурацию системы, включая переменные окружения.


Эксплуатация

Уязвимость находится в эндпоинте API http://minio-ip:9000/minio/bootstrap/v1/verify. Если уязвимость присутствует, то в ответе будут указаны все переменные окружения, включая MINIO_SECRET_KEY и MINIO_ROOT_PASSWORD.

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

Для эксплуатации можно использовать любой POC из интернета, например, acheiii/CVE-2023-28432



В переменной MINIO_ROOT_PASSWORD получаем фразу: THE_PART_YOU_HAVE_ALREADY_RECEIVED.4.16}

Кажется, мы что-то упустили.

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

Если запустить программу по типу dirsearch, то она довольно быстро покажет папку data, в которой находится файлик flag.txt со следующим содержанием:



Итак, мы нашли две части флага.

Соединив их, получаем следующий IP-адрес: 213.108.4.16.

▍ Шаг 6 — PPC


Также просканировав на нём порты, можно было найти нестандартный 6666 открытый TCP-порт, к которому можно подключиться, например, через nc.



Очень загадочная надпись, не правда ли? Попробуем ввести имя, так как от нас его просят.



Получаем странный ответ:

Nice to meet you, RUVDS!
Your part will be 'k3s'
Don`t forget it!

Что может значить Your part will be 'k3s'?

Попробуем проделать все действия несколько раз.

Получаем кусочки k3s | sIt | _PA | W1n | n3r | 3rT

Кажется, эти кусочки как-то связаны друг с другом, например, W1n и n3r видимо образуют вместе W1nn3r, что уже интересно. Правда, пока не ясно, влияет ли как-то наш ввод на ответ сервера.

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

Программа
import re
    import socket

    IP = 'PASTE_IP_HERE'
    PORT = 6666

    parts = set()

    while True:
    try:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((IP, PORT))
    while True:
    data = s.recv(1024).decode().strip()
    if not data:
    break
    if "What`s your name?" in data:
    name = "user"
    s.sendall(name.encode())
    elif "Your part will be" in data:
    current_part = re.search('\'([^\"]*)\'', data).group(1)
    break
    new_parts = set()
    for part in parts:
    for offset in range(2, len(current_part)):
    if part.startswith(current_part[-offset:]):
    new_parts.add(current_part[:-offset] + part)
    if current_part.startswith(part[-offset:]):
    new_parts.add(part[:-offset] + current_part)
    parts.update(new_parts)
    parts.add(current_part)
    print(sorted(parts, key=len, reverse=True)[:10])
    except KeyboardInterrupt:
    break


Вывод программы

['SSW']
['SSW', 'NER']
['l1}', 'SSW', 'NER']
['INN', 'l1}', 'SSW', 'NER']
...
['ER_PA', 'NNER_', '1nn3', ...]
['D{The', 'ER_PA', 'NNER_', ...]
['W1nn3r', 'D{The', 'ER_PA', ...]
...
['WINNER_', 'ORD{The', 'NER_PA', ...]
['WORD{The', 'WINNER_', 'WORD{Th', ...]
['SWORD{The', 'WORD{The', 'WINNER_P', ...]
['ASSWORD{Th', 'SWORD{The', 'SSWORD{Th', ...]
...
['ASSWORD{The', 'ASSWORD{Th', 'SSWORD{The', ...]
['ASSWORD{TheW', 'SSWORD{TheW', 'ASSWORD{The', ...]
['PASSWORD{TheW1', 'PASSWORD{TheW', 'ASSWORD{TheW1', ...]


Кажется, мы на правильном пути. И вывод никак не зависит от нашего ввода, что прекрасно!

Дождавшись, пока программа поработает минут 5, видим, что вывод перестал меняться и образовалась целостная строка WINNER_PASSWORD{TheW1nn3rT4k3sItAl1}.

Кажется, это то, что нам нужно.

▍ Шаг 7 — финал


Пользователи, получившие строку, находили действительно интересные места, куда её можно отправить. Доходило даже до тикетов в поддержку!

К счастью, в реальности всё оказалось гораздо проще — из всего того же сканирования портов можно было увидеть открытый SSH, который на связку логина winner и пароля TheW1nn3rT4k3sItAl1 выводил специальное сообщение:

Сообщение после входа на SSH
Так-так, вы продемонстрировали впечатляющие скиллы и скорость. Взял бы вас напарником, но предпочитаю работать в одиночку. Именно поэтому я использовал вас, чтобы отвлечь внимание компании, пока я забираю крипту. Теперь всё, что остается вам — это отправить баг-репорт с подробным райтапом ваших действий на market@ruvds.com с ключом TheW1nn3rT4k3sItАl1. A los vencedores no se les juzga.

Разбор второго этапа квеста


▍ Шаг 1 — пасхалка в видео


Но, как известно, хакерам нельзя доверять — вот и Череп снова обманул наивных людей. Оказалось, что он и не собирался делиться деньгами, а просто пытался выиграть время для себя. Об это мы рассказали во втором посте от лица Черепа. Многие расслабились и думали, что на этом квест завершён, но не тут-то было. Последнее сообщение от хакера содержало не подсказку, а насмешку — в нём Череп поблагодарил заинтересовавшихся в создании «информационного шума» в то время, когда он был занят взломом спутника.
?: How's it going? I bet you won't see your money anymore! How does it feel to be fooled? I have to admit you did a nice job on making some noise, so thank you — and better luck next time, losers.


Самые бдительные участники и старожилы наших квестов нашли в ролике кое-что весьма и весьма интересное:


Перейдя по ссылке civilsky.ru, можно было попасть на следующую страницу.



Интересный факт: мы разместили пасхалку на поддомене admin.civilsky.ru — он переадресовывал участников на замечательное видео с песней бразильского мальчика :)

▍ Шаг 2 — BLOCKCHAIN


Интересный факт: на момент написания этого комментария НИКТО из участников не смог решить задачу с хешами на главной странице домена хакера Черепа.

На входе мы имеем следующие данные:

old_test=510E527F;50A28BE6;52f69420c8929102a400c9ebd78ef0a1ec86cf8a

Узнаём адрес кошелька из вводных данных:

510E527F – константа, намекающая на SHA-256;

50A28BE6 – константа, намекающая на RIPEMD-160;

52f69420c8929102a400c9ebd78ef0a1ec86cf8aRIPEMD160(SHA256(publicKey)), стандартная схема для биткоин-кошельков.

В адресе кошелька битка для P2PKH есть ещё идентификатор сети в начале и контрольная сумма в конце.

Версий и сетей не так уж много, их можно либо подобрать (смотря в биткоин-сетях есть ли что-то про такой кошелёк или нет) либо посмотреть на подсказку old_test, где test намекает на testnet.

Поэтому берём идентификатор сети биткоиновского тестнета 6f и добавляем его в начало:

6f52f69420c8929102a400c9ebd78ef0a1ec86cf8a

Считаем контрольную сумму SHA256(SHA256(6f52...cf8a))[:4] 1d3d4de9, добавляем её в конец:

6f52f69420c8929102a400c9ebd78ef0a1ec86cf8a1d3d4de9

Кодируем в base58check: mo5d6NG2HrMZvBf1J8J1UnETLmue3eTEhe

Идём в эксплорер (например, blockexplorer.one) по этому адресу.



Далее в куче транзакций нужно найти одну немного странную – 2c387b8282188000f5da203c2015a3ac88c9128a7eaa4d96f16e4cb9ec0f33cd

В ней помимо обычного lock-скрипта (перевод средств) есть мини-программа, которая на стеке виртуальной машины криптовалюты оставляет некий секрет.

Главная задачка — разобрать метод кодирования этого текста в программе-транзакции (он несложный на деле, не так много операций доступно в том же биткоине). Вот тут есть онлайн-отладчик биткоин-скриптов: bitcoin-script-debugger.visvirial.com.

Если её туда запихнуть, то будет понятно, как она работает.

Со страницы обозревателя берём закодированную версию мини-программы:

76a914acf394a4fc036dbc88f8ef7b42e489637fbbe73688ac4c02084b4c025d29934c0427542f2e4c044220123f934c04522008104c041a4f6a43934c04351535134c0440580f5c934c042d18643d4c0440310c36934c04126e68494c043a010a1c93757575757575

Теперь возьмём самую простую Bitcoin IDE для отладки такого кода.

Дизассемблируем его и получаем:

Код программы
OP_DUP OP_HASH160 acf394a4fc036dbc88f8ef7b42e489637fbbe736 OP_EQUALVERIFY OP_CHECKSIG OP_PUSHDATA1 084b OP_PUSHDATA1 5d29 OP_ADD OP_PUSHDATA1 27542f2e OP_PUSHDATA1 4220123f OP_ADD OP_PUSHDATA1 52200810 OP_PUSHDATA1 1a4f6a43 OP_ADD OP_PUSHDATA1 35153513 OP_PUSHDATA1 40580f5c OP_ADD OP_PUSHDATA1 2d18643d OP_PUSHDATA1 40310c36 OP_ADD OP_PUSHDATA1 126e6849 OP_PUSHDATA1 3a010a1c OP_ADD OP_DROP OP_DROP OP_DROP OP_DROP OP_DROP OP_DROP

Немного переформатируем и убираем стандартный P2PKH-префикс:

Код программы
OP_PUSHDATA1 2 0x084b
OP_PUSHDATA1 2 0x5d29
OP_ADD
OP_PUSHDATA1 4 0x27542f2e
OP_PUSHDATA1 4 0x4220123f
OP_ADD
OP_PUSHDATA1 4 0x52200810
OP_PUSHDATA1 4 0x1a4f6a43
OP_ADD
OP_PUSHDATA1 4 0x35153513
OP_PUSHDATA1 4 0x40580f5c
OP_ADD
OP_PUSHDATA1 4 0x2d18643d
OP_PUSHDATA1 4 0x40310c36
OP_ADD
OP_PUSHDATA1 4 0x126e6849
OP_PUSHDATA1 4 0x3a010a1c
OP_ADD
OP_DROP
OP_DROP
OP_DROP
OP_DROP
OP_DROP
OP_DROP



Теперь запускаем программу в отладчике.

Примечание
Ошибка The resulting stack is empty. выводится не случайно.

Это намёк на то, что нужно посмотреть на стек. Чтобы её не было, можно в конце добавить команду OP_1.

Видно, что программа что-то вычисляет на стеке OP_ADD-ом, а потом очищает его.



Берём со стека то, что осталось до очистки:

4c6f7265
6d497073
756d446f
6c6f7253
6974416d
6574


Конвертируем в ASCII и получаем заветный флаг "LoremIpsumDolorSitAmet".

На странице civilsky.ru есть упоминание доменов, поэтому почему бы не попробовать фразу в качестве домена? Или, скажем, составить из заглавных букв фразы новую — не просто же так именно в таком формате мы её получили. Получается lidsa.

Альтернативный путь нахождения поддомена
Увидев упоминание поддоменов, можно было воспользоваться специальными инструментами (к примеру, bbot), некоторые модули которых позволяли найти данный поддомен :)


▍ Шаг 3 — Kubernetes


Пробуем зайти на lidsa.civilsky.ru и видим, что мы угадали и перед нами открылся интересный сайтик с Go Playground:



Go Playground позволяет нам выполнять любой код, а значит пробуем отправить reverse shell и попытаемся установить соединение (на вашем сервере необходимо открыть порт для прослушивания командой nc -lvnp <port>:



Бинго! Получаем шелл на сервере. Осматриваясь, можем написать команду env — после её изучения понимаем, что мы находимся в Kubernetes.

Скачиваем kubectl и начинаем смотреть, куда есть доступ. Видим секреты, читаем их, декодируем… и получаем финальный результат!


Финальным квестовым сообщением со спутника стала благодарность от команды RUVDS за помощь в возвращении доступа к украденным Черепом средствам.



Победители


Главные финалисты:

  • ? 1 место команда МНС
  • ? 2 место команда lostinthevoid404 & n0t_al0ne
  • ? 3 место команда RedHazzarTeam & Codeby
  • 4 место команда nevercommit & kunteynir
  • 5 место команда rex leonum & wf.sngame
  • 6 место Викентий К.
  • 7 место forst
  • 8 место Михаил Е.
  • 9 место Андрей Г.

Почётные места для прошедших доп. задание:

  • Данил К.
  • Эдуард П.
  • polidactily
  • BurSt
  • Никита Д.

Статистика


  • >1000 участников.
  • >200 активных игроков.
  • 18 финалистов.
  • 2 супер-финалиста.
  • >12000 ответов от ИИ-бота участникам квеста.
  • 23 часа 51 минуты — минимальное время прохождения двух этапов квеста — команда MHC.
  • 20 часов 7 минут — минимальное время прохождения основного этапа — команда MHC.
  • 1 час 34 минуты — минимальное время прохождения дополнительного этапа — команда lostinthevoid404 и not-alone.

Кто и где брал флаги и помогал решать задачи первого космического квест-хакатона:

  • >5 профессиональных команд — регулярных участников и призёров различных CTF.
  • >50 хабражителей — в комментариях к постам о квест-хакатоне на Хабре.
  • 2842 участников дискорд-канала HackRoom — участники хакатонов RUVDS прошлых лет.
  • 124 участника тг-канала Пельменизм — энтузиасты предыдущих хакатонов RUVDS и сочувствующие.

Кто делал задачи квест-хакатона:

  • Победители и призёры конкурсов и олимпиад по ИБ — 6 задач.
  • Члены команды RUVDS — 2 задачи, сюжет и задумка.
  • Специалисты крупнейшей российской ИБ-компании — 1 задача.
  • Создатели кибербитвы Standoff и разработчики заданий CTF из Positive Technologies — 2 задачи.
  • Специалисты двух частных российских космических компаний консультировали и обеспечивали резервные каналы для связи со спутниками.

Кто участвовал в квесте


В нашем квесте принимали участие не только новички, но и старожилы, например, команда игроков lostinthevoid404 и not-alone, которые уже были победителями в квесте «Комната хакера», а здесь заняли второе место.

Помимо хакеров, загадки квеста разгадывали и радиолюбители (например, хабраюзеры Pyhesty и NutsUnderline). Они могли получать подсказки к новым заданиям CTF быстрее и таким образом имели фору перед остальными участниками. Что приятно, радиолюбители также помогали своим конкурентам.



Отзывы участников








Ещё несколько скриншотов про то, как это было


Как ловили сигнал со спутника:





Строили гипотезы:



Любовались нашим гитхабом:



Использовали Telegram-бота не совсем по назначению:


Пытались спрятаться от всевидящего ока:



И настойчиво требовали результатов:



Как пытались взломать нашего Telegram-бота










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

Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх ?️
Теги:
Хабы:
Всего голосов 56: ↑53 и ↓3+71
Комментарии21

Публикации

Информация

Сайт
ruvds.com
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия
Представитель
ruvds