После весьма болезненного перехода на нового провайдера Интернет, появилась задача написать авторизатор. Дело в том что провайдер дает возможность доступа к сети двумя способами:
- с помощью специальной программки, которая написана для ОС Windows. Програмка совсем неплохая и даже отлично работает под Wine (разве что криво русские шрифты отображаются).
- с помощью авторизаци через web browser. Происходит это примерно так: пользователь заходит на сайт провайдера (который всегда доступен), вводит в нужные формы логин и пароль. В последствии загружается страница, что обновляется через каждые 40 сек. Конечно же если мы закроем страницу, то по истечении 40 сек. доступ в Интернет оборвется.
Задача
Необходимо написать скрипт, который бы автоматически генерировал ссылку для авторизации (по данным взятым с страници провайдера) и каждые 40 секунд делал запрос по этой ссылке.
Разбор полетов
После того как в нужные формы пользователь ввел данные формируется ссылка следующего формата:
http://stat.pautina-nau.net/cgi-bin/stat.pl?ses=11111111&a=98&uu=111111&pp=123456789abcdef123456789abcdef00? - указывает конец ссылки и дальше передаются переменные.
& - разлелитель между переменными.
Какие выводы?
- скрипт который обрабатывает данные stat.pl
- переменная с именем пользователя (логином) uu.
- Переменная котороая содержит пароль pp.
- Неизвестная переменная со значением a=98
- Неизвестная переменная со значением ses=11111111
страницу в которой находятся формы для логина и пароля:
<form method=get action='/cgi-bin/stat.pl' onsubmit='pp.value=hex_md5(ses.value+" "+pp.value); return true'> <input type=hidden name=ses value=201110> <table class='tbg1'><tr class='head'><td align=center colspan=3> <input type=hidden name=a value=98>Если вы хотите получить доступ в интернет без авторизатора - авторизуйтесь в этом окне. После авторизации не закрывайте окно - оно будет периодически авторизовываться на сервере и поддерживать открытым доступ в интернет</td></tr> <tr class=row2><td align=right width='33%'>Логин:</td><td><input type=text name=uu size=25 value='' tabindex=4></td> <td rowspan=2 class=row2> <input type=submit value=' Авторизоваться ' tabindex=6></td></tr><tr class=row2> <td align=right>Пароль:</td> <td><input type=password name=pp size=25 value='' tabindex=5></td></tr></table>Этот кусок исходного кода страницы содержит информацию о интересных для нас формах: логин, пароль и формирователья запросов. Рассматривать код начнем с конца:
<td align=right>Пароль:</td> <td><input type=password name=pp size=25 value='' tabindex=5></td>видно что переменная которая содержит пароль называется pp.
Логин:<input name="uu" size="25" tabindex="4" type="text" value="" />аналогично, переменная с логином называется uu.
<input type=hidden name=ses value=111111>А в hiden спрятана переменная ses=111111
<input type=hidden name=a value=98>Аналогично спрятана в hiden другая переменная a =98
С остальными переменными понятно, но что же означают ses и а ?
Формирование запроса
<form method=get action='/cgi-bin/stat.pl' onsubmit='pp.value=hex_md5(ses.value+" "+pp.value); return true'>
Для запроса используется метод GET, а формирование ссылки происходит с помощью некой функции hex_md5(), при чем как аргумент пересылается ему строка формата:
[ses] [pp]
То есть состоит из таинственной для нас переменной ses через пробел с паролем pp.
Что такое md5?
MD5 (англ. Message Digest 5) — 128-битный алгоритм хеширования, разработанный профессором Рональдом Л. Ривестом из Массачусетского технологического института (Massachusetts Institute of Technology, MIT) в 1991 году. Предназначен для создания «отпечатков» или «дайджестов» сообщений произвольной длины. Является улучшенной в плане безопасности версией MD4. Зная MD5-образ (называемый также MD5-хеш или MD5-дайджест), невозможно восстановить входное сообщение, так как одному MD5-образу могут соответствовать разные сообщения.Проще говоря шифрует пароль, да так что в обратную сторону потчти невозможно расшифровать.
Механизм формирования ссылки более-менее понятен: через командную строку отправляются данные о логине пароле, переменная ses, переменная а.
Понаблюдав за переменными, можно сделать вывод:
ses — изменяющая свое значение переменная, правда не чаcто гдето 1-2 раза в сутки, используется для шифрования пароля.
a — статическая, не меняется, скорее всего отвечает за идентификацию необходимой формы.
Теперь самое время уточнить задачу:
- Получить код страници с формой для авторизации;
- Выделить значение переменной ses;
- Сформировать строку для зашифровки;
- Используя алгоритм md5 зашифровать строку;
- сформировать и выполнить запрос по ссылке.
Вот что у мну получилось:
#!/usr/bin/env python
import re
import urllib
import hashlib
import logging
import sys
uu=11111 #user name
pp=1111 #password
a=98 #static variable
#intit dictionary of debug levels
LEVELS = {'-debug': logging.DEBUG,
'-info': logging.INFO,
'-warning': logging.WARNING,
'-error': logging.ERROR,
'-critical': logging.CRITICAL}
#Check for programmed arguments (arguments passed through command line)
if len(sys.argv) > 1:
level_name = sys.argv[1]
level = LEVELS.get(level_name, logging.NOTSET)
logging.basicConfig(level=level)
#logging.basicConfig(level=logging.DEBUG)
# Get a file-like object for the Python Web site's home page.
f = urllib.urlopen(u"http://stat.pautina-nau.net/cgi-bin/stat.pl?a=101&a=99")
# Read from the object, storing the page's contents in 'html_page'.
html_page = f.read()
f.close()
logging.debug(html_page)
logging.debug("\n ***********************************************")
#find needed value from hidden form using regular expression
match = re.search( ur"name=ses[\s]+value=([0-9]{2,8})", html_page )
ses = match.group(1).encode( "cp1251" )
logging.debug("ses = "+ ses)
#encode password with md5 algorithm
pp_value = hashlib.new('md5')
pp_value.update(str(ses)+" "+str(pp))
pp = pp_value.hexdigest()
logging.debug(pp)
#form executable url
params = urllib.urlencode({'ses': ses, 'a': 98, 'pp': pp})
f = urllib.urlopen("http://stat.pautina-nau.net/cgi-bin/stat.pl?%s" % params)
f.read()
html_page_resp = f.read()
f.close()
Как по мну полезный пример, только не содержит функции обновления каждые 40 секунд. Позже разберусь с таймерами и уже в следующей статье дам более подробное описание кода скрипта.








