Порой появляется необходимость отправки анонимного сообщения нужному адресату, не используя при этом своего телефона или тогда, когда под рукой только компьютер, работающий интернет и открытая консоль.
Во многих фильмах есть момент, когда хакеру, взламывающего человека, нужно отправить сообщение на его номер, чтобы его отвлечь или напугать и в таких ситуациях самое важное, чтобы, когда человек позвонит на номер с которого пришло СМС у вас не загорелся экран смартфона и не заиграла музыка. Упс… Неловкая ситуация. В этой теме мы напишем программу на C++, которая позволит отправить СМС не используя вашего номера, сим-карты и души.
Слово “Анонимность” подразумевает собой то, что кто отправил сообщение на самом деле не узнается, но не всё так хорошо. При разбирательстве этот факт выяснится, так что при особо тяжких приколах я не приду навестить вас на испытательных работах.
Предупреждение. Поставленную задачу можно было решить более лёгкими путями. В данной теме приведено одно из решений именно на языке c++.
Приступим к делу.
Сервис bytehand – это решение для бизнеса, позволяющее делать как массовые рассылки сообщений, так и одиночные. Главная особенность сервиса и почему я его выбрал является доступное со всех платформ API, которое представляет собой HTTP Запрос-Ответ с очень простой системой авторизации.
Вот что нам понадобится:
- Аккаунт на bytehand
- 100 рублей на счету (А что вы хотели, СМС не бесплатные)
- Консольная программа c++
- Собранные библиотеки Boost.Asio и OpenSSL для https соединения
- Созданный через OpenSSL сертификат для защищённого обмена данными с сервисом bytehand.
Первым делом регистрируемся на сервисе bytehand. Регистрация представляет собой введённый e-mail и пароль. Этого уже достаточно. После этого создаётся ваш аккаунт и при пополнении счёта (минимум 100р) вы уже можете отправлять сообщения с заголовком SMS-INFO. У большинства операторов эта запись заменяется номером отправления. При желании можно придумать свой собственный текстовый псевдоним.
Далее лезем в API ресурса. И видим, что что бы отправить СМС нужно всего лишь сформировать следующий пакет данных:
POST /v2/sms/messages HTTP/1.1
Host: api.bytehand.com
Connection: close
Content-Length: *
Content-Type: application/json;charset=UTF-8
X-Service-Key: ab4db0b982dcd0ba63e44191e5d71ef8
{
"sender": "MyShop",
"receiver": "+79167654321",
"text": "Today only! 20% off for all goods!!"
}
Обращу ваше внимание на то, что X-Service-Key в заголовке http это и есть вся авторизация. Этот ключ можно посмотреть в настройках на сайте в разделе “безопасность”.
Думаю здесь всё понятно и можно приступить к написанию консольной программы на c++
Первым делом представляю вашему вниманию фрагмент кода, который с помощью Boost.Asio устанавливает соединение с сайтом по https протоколу
// Подключение библиотек Boost
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/bind.hpp>
// ---------------------------
// ---------- Include OpenSSL Lib ----------
#pragma comment (lib, "libeay32.lib")
#pragma comment (lib, "ssleay32.lib")
// -----------------------------------------
using namespace boost::asio;
// Функция верификации сертификата
bool verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx)
{
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
return preverified;
}
int main()
{
io_service service; // Класс, реализующий сокеты подключения
/*------------------------------------------------------------
- Устанавливаем соединение с сервером -
------------------------------------------------------------*/
ip::tcp::resolver resolver(service);
ip::tcp::resolver::query query("api.bytehand.com", "https");
ip::tcp::resolver::iterator iterator = resolver.resolve(query);
ssl::context context(boost::asio::ssl::context::sslv23);
context.load_verify_file("dh2048.pem");
ssl::stream<ip::tcp::socket> socket_(service, context);
socket_.set_verify_mode(ssl::context::verify_none);
socket_.set_verify_callback(boost::bind(verify_certificate, _1, _2));
connect(socket_.lowest_layer(), iterator);
socket_.handshake(boost::asio::ssl::stream_base::client);
//Здесь мы можем передавать данные серверу через функцию socket_.write_some()
}
В коде используется ссылка на файл сертификата dh2048.pem. Его вы замените своим.
Так же можно увидеть, что тут в качестве сервера используется доменное имя api.bytehand.com
Далее пример как формируется заголовок и тело http запроса для сервера.
int main()
{
/* Тут то, что было в предыдущем коде создания https соединения*/
// Эти переменные заменяются вводом текста с клавиатуры и проверку на ошибки
// Здесь код упращён для его понимания
string number = "+79180000000";
string signature = "SMS-INFO";
string text = "Today only! 20% off for all goods!!";
std::stringstream request_; // Хранит запрос к серверу
char sockBuffer[8192]; // Временное хранилище ответа от сервера
// Выносим тело в отдельную переменную, что бы посчитать длину для заголовка Content-Length
string reqTmp = "{"sender": "" + signature + "","receiver": "" + number + "","text": "" + text + ""}rn";
request_ << "POST /v2/sms/messages HTTP/1.1rn";
request_ << "Host: api.bytehand.comrn";
request_ << "Connection: closern";
request_ << "Content-Length: " << reqTmp.length() << "rn";
request_ << "Content-Type: application/json;charset=UTF-8rn";
request_ << "X-Service-Key: ab4db0b982dcd0ba63e44191e5d71ef8rn";
request_ << "rn";
request_ << reqTmp;
// Отправляем пакет на сервер
socket_.write_some(buffer(request_.str()));
memset(sockBuffer, NULL, 8192);
// Читаем ответ от сервера в буффер
socket_.read_some(buffer(boost::asio::buffer(sockBuffer)));
// Выводим ответ на экран
cout << endl << endl << sockBuffer << endl;
}
Напоминаю, что поле X-Service-Key вы заменяете на ваш ключ.
После выполнения этого кода и если всё прошло как надо, сервер возвращает ответ:
Status Code: 200
Content-Type: application/json;charset=UTF-8
Content-Language: en
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
{
"result": "created",
"count": 1
}
На этом моменте с вашего счёта списываются деньги за отправку сообщения. И сообщение идёт к адресату. Когда он его получит, то это будет номер компании или текстовый идентификатор и вряд ли человек поймёт от кого было это сообщение.
Вот что вышло у меня при написании этой программы:
Получилось коряво, но что есть. Всем удачи, возможно эта тема вам чем то помогла.
Это была моя вторая статья тут. Спасибо за прочтение. Удачи в разработке ваших приложений.
Автор: Андрей Селезнёв