После весьма болезненного перехода на нового провайдера Интернет, появилась задача написать авторизатор. Дело в том что провайдер дает возможность доступа к сети двумя способами:
- с помощью специальной программки, которая написана для ОС 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 секунд. Позже разберусь с таймерами и уже в следующей статье дам более подробное описание кода скрипта.
No comments:
Post a Comment