[Программирование под WEB от Kairos] 2) mail регер rambler.ru.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Kairos, 14 Jan 2011.

  1. Kairos

    Kairos Elder - Старейшина

    Joined:
    5 Oct 2009
    Messages:
    37
    Likes Received:
    21
    Reputations:
    21
    Эта статья входит в цикл статей о том как легко научиться писать свои регеры, парсеры, спамеры, накрутчики опросов и прочий софт, автоматизирующий действия в сети. Вобщем-то в этом нет ничего сложного. Писать будем на C#. Нам понадобятся Visual Studio, Firefox, Firebug, Fiddler и ViKing.Engine, который можно скачать тут

    Следующая статья: продвинутый регер rambler.ru
    Предыдущая статья: парсер прокси.


    Сегодня мы напишем регистратор почты на rambler.ru. Этот пример поможет научиться использовать сниффер для анализа запросов, которые посылает браузер. А еще мы научимся скачивать картинки и разгадывать капчу. К тому же на этот раз у нас будет windows-приложение, а не консольное. Итак, поехали.

    Создаем в Visual Studio проект Windows Application, подключаем ViKing.Engine.dll, добавляем сверху код
    Code:
    using ViKing.Engine;
    using ViKing.Engine.GUI;
    using System.IO;
    using System.Text.RegularExpressions;
    На этот раз мы также добавили строку using ViKing.Engine.GUI, она нам пригодится для того чтобы было просто отображать капчу на экране, в общем сами увидите чуть позже. Теперь откроем firefox и fiddler. Не забудьте включить фидлер в статусной строке фаерфокса (должно быть написано «Fiddler: ForceOn»). Перейдем на рамблер, ткнем зарегистрироваться и заполним форму регистрации:

    Скриншот

    Для удобства желательно пометить запрос, который появился в сниффере при открытии формы регистрации клавишей «insert» (на скриншоте у меня он красный). Дальше жмем зарегистрироваться и смотрим что за запрос отправился на сервер:

    Скриншот

    Ага, отправился POST-запрос на http://id.rambler.ru/script/newuser.cgi с параметрами
    Code:
    skin 	id
    back 	
    back_immediate 	
    uniq_id 	6b9f763008ed2b609110f6d50eb92f50
    action 	register
    user.fname 	firstname
    user.lname 	lastname
    user.gender 	1
    user.bday 	1
    user.bmonth 	1
    user.byear 	1950
    user.login 	mail1245
    user.domain 	rambler.ru
    x.emailfree 	mail1245@rambler.ru
    user.password1 	qweqwe
    user.password2 	qweqwe
    user.question 	own.question
    user.own_question 	question
    user.answer 	answer
    user.email2 	
    user.captcha 	cfmrnf
    Мы видим что почти все эти параметры – поля только что заполненной нами формы. Особый интерес для нас представляют
    user.login – его мы должны сделать случайным
    user.captcha – нужно будет найти где располагается соответствующая картинка
    uniq_id – какой-то уникальный id, давайте выясним подробнее что это такое. Для этого посмотрим в сниффер на несколько строк выше, на запрос который браузер сделал при открытии формы регистрации. В ответ на него нам пришел код страницы регистрации. Откроем код страницы в блокноте и поищем там интересующий нас id 6b9f763008ed2b609110f6d50eb92f50. Он находится в 3 местах:

    Code:
    Set-Cookie: rrc=6b9f763008ed2b609110f6d50eb92f50; domain=.rambler.ru; path=/; httponly
    <input name="uniq_id" type="hidden" value="6b9f763008ed2b609110f6d50eb92f50" />
    <img id="secimage" title="Введите показанные на картинке символы" src="http://id.rambler.ru/captcha/6b9f763008ed2b609110f6d50eb92f50.jpg" border="0" alt="Введите показанные на картинке символы" width="300" height="60" />
    Первая строка располагается в заголовках и устанавливает куки. Возможно если не отправить этот кук в запросе на регистрацию, то он выдаст ошибку. Но для начала попробуем обойтись без куков, вдруг и так сойдет. Вторая строка находится на веб-форме и как-раз она и добавляет наш id в POST-запрос. Третья строка – как это ни удивительно, это тег img с изображением капчи. Адрес по которому он берет картинку содержит наш uniq_id. Это очень удобно, значит можно найти адрес картинки и из него-же вытащить id. Ну чтож, похоже мы нашли все что нам нужно для регистрации, приступим к написанию софта. Последовательность действий должна быть такая

    1. Качаем форму регистрации
    2. Находим там uniq_id, он же адрес картинки с капчей
    3. Качаем картинку
    4. Отгадываем капчу
    5. Отправляем заполненную форму на серер
    6. Все!

    1. Скачать форму – проще простого! Смотрим в фидлер на адрес и пишем код:
    Code:
    string page = VkRequest.Request("http://id.rambler.ru/script/newuser.cgi").Content;
    2. Теперь нужно выдернуть id. Делаем вот так:
    Code:
    string id = Regex.Match(page, @"http://id.rambler.ru/captcha/(?<id>\w+).jpg").Groups["id"].Value;
    Это регулярное выражение, мы с таким уже сталкивались. Оно ищет адрес картинки с капчей, но вместо набора букв в названии картинки, который все время меняется мы написали (?<id>\w+). «\w»означает любую букву или цифру, «+» означает что «\w » нужно повторить 1 или более раз. «(?<id>)» присваивает получившейся комбинации имя «id». Затем команда «.Groups["id"].Value» выдергиает из получившейся комбинации только кусок с названием «id». Таким образом мы получили значение uniq_id.

    3. Теперь скачаем картинку с капчей:
    Code:
    Image captchaImage = VkRequest.Request("http://id.rambler.ru/captcha/" + id + ".jpg").GetImage();
    Обычный GET-запрос, только «.GetImage()» в конце означает что ответ сервера нужно воспринимать как картинку.

    4. Для отгадывания картинки можно использовать класс CaptchaWindow из дижка викинга. Перед использованием его нужно инициализировать в конструкторе формы
    Code:
    public Form1()
    {
        InitializeComponent();
        CaptchaWindow.Initialize(this);
    }
    Терерь его можно использовать вот так:
    Code:
    string captchaAnswer = CaptchaWindow.Show(captchaImage);
    5. Теперь давайте сформируем POST-запрос для сервера. Для этого скопируем запрос который мы отправляли через браузер и изменим значения uniq_id, user.login и user.captcha:
    Code:
    string post = string.Format(
    "uniq_id={0}&user.login={1}&user.captcha={2}&user.password1=qweqwe&user.password2=qweqwe&skin=id&back=&back_immediate=&action=register&user.fname=firstname&user.lname=lastname&user.gender=1&user.bday=1&user.bmonth=1&user.byear=1950&user.domain=rambler.ru&x.emailfree=mail1245%40rambler.ru&user.question=own.question&user.own_question=question&user.answer=answer&user.email2=",
    id, email, captchaAnswer);
    Я переставил важные параметры в начало запроса для удобства, это можно делать, так как порядок ни на что не влияет. В переменной еmail должен содержаться случайный логин. Самый быстрый способ его сделать такой:
    Code:
    string email = Path.GetRandomFileName().Replace(".", "");
    Теперь отправим наш запрос на сервер. Для этого вызовем функцию Request с 2 параметрами:
    Code:
    var result = VkRequest.Request("http://id.rambler.ru/script/newuser.cgi", post);
    После этого наша почта должна быть зарегистрирована. Давайте на последок сделаем проверку, успешно ли она зарегалась. Ответ для успешной регистрации у нас в сниффере уже есть, это редирект на проверку куков:

    Code:
    HTTP/1.1 302 Found
    Server: nginx/0.8.52
    Date: Thu, 13 Jan 2011 20:55:59 GMT
    Content-Type: text/html; charset=windows-1251
    Connection: keep-alive
    Keep-Alive: timeout=20
    P3P: CP="NON DSP NID ADMa DEVa TAIa PSAa PSDa OUR IND UNI COM NAV"
    Set-Cookie: rsid=d7869f1f48cfdf521adaf5898dae6821; domain=.rambler.ru; path=/; httponly
    Set-Cookie: rlogin=mail1245@rambler.ru; domain=.rambler.ru; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/
    Set-Cookie: rup=MXbkSZD38i7rheLADZysFSU_; domain=.rambler.ru; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/
    Pragma: no-cache, no-store
    Cache-Control: no-cache
    Expires: Thu, 01 Jan 1970 00:00:01 GMT
    Location: http://id.rambler.ru/script/auth.cgi?mode=checkcookie;sid=d7869f1f48cfdf521adaf5898dae6821;back=http%3A%2F%2Fid.rambler.ru%2Fscript%2Fnewuser.cgi%3F%26amp%3Baction%3Dnew_user%26amp%3Bskin%3Did%26amp%3Bback%3D
    Content-Length: 0
    Теперь давайте зарегистрируемся неудачно, например неверно едем капчу. Получим такой ответ:

    Code:
    HTTP/1.1 200 OK
    Server: nginx/0.8.52
    Date: Thu, 13 Jan 2011 20:55:59 GMT
    Content-Type: text/html; charset=utf-8
    Connection: keep-alive
    Keep-Alive: timeout=20
    Pragma: no-cache, no-store
    Cache-Control: no-cache
    Expires: Thu, 01 Jan 1970 00:00:01 GMT
    Content-Length: 19382
    
    <!-- This comment will put IE 6, 7 and 8 in quirks mode -->
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
     "http://www.w3.org/TR/html4/loose.dtd">
    <html lang="ru">
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8>">
     <meta http-equiv="X-UA-Compatible" content="IE=8">
     <link rel="stylesheet" type="text/css" href="/css/id.css" media="all">
     <link rel="icon" href="/favicon.ico" type="image/x-icon">
     <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    
     <script type="text/javascript"><!--
    
     rg_errors_text = {
    
    БЛА-БЛА-БЛА
    Получается, что когда регистрация неуспешная, нам просто выдают форму регистрации со списком ошибок. Давайте тогда будем считать что если редирект произошел, то все ок, а если нет то была ошибка:
    Code:
    if (result.Headers["Location"].Length > 0) textBox1.AppendText(email + " зарегистрирован!\r\n");
    else textBox1.AppendText("Ошибка\r\n");
    
    Вот и все! Регистратор готов. Пробуем зарегистрировать программой аккаунт и зайти в него через браузер (пароль «qweqwe»). Все работает! Скачать файл с исходниками можно тут: http://kairos-blog.ru/?p=177
     
    #1 Kairos, 14 Jan 2011
    Last edited: 18 Jan 2011
    4 people like this.
  2. Gra4PRO

    Gra4PRO New Member

    Joined:
    8 Jan 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    а почему именно на с ?
     
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 Gra4PRO
    1) на C# а не на Си.
    2) А почему должно быть на делфи?
     
  4. Gra4PRO

    Gra4PRO New Member

    Joined:
    8 Jan 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    я имел ввиду пхп
     
  5. X-rus

    X-rus Member

    Joined:
    22 Dec 2010
    Messages:
    88
    Likes Received:
    22
    Reputations:
    4
    Пару советов.

    1. Зачем сохранять капчу? Не проще ли передать через конструктор ссылку на капчу, установить ссылку в свойство ImageLocation и она автоматически загрузится. Плюс, можно установить анимацию загрузки и другие 'эффекты'.

    2. Если использовать свою библиотеку для работы с Web, то можно сделать работу с Post запросами поудобнее.
    Допустим так:
    Code:
    HttpRequest.PostParameters postParams = new HttpRequest.PostParameters();
    
    postParams["login"] = "John";
    postParams["password"] = "smith";
    postParams["nobody"] = string.Empty;
    
    HttpRequest.Post("http://agent.ru/test.php", postParams);
    Тоже касается и отправки MIME-данных.

    3.
    Я для этих целей использую браузер Chrome. В нём можно быстро открыть код страницы, всё будет удобно подсвечено и есть поиск, опять же, с подсветкой. И ещё много других возможностей, помогающих в этом деле.


    Вообще, интересный цикл статей. ;)
     
  6. Kairos

    Kairos Elder - Старейшина

    Joined:
    5 Oct 2009
    Messages:
    37
    Likes Received:
    21
    Reputations:
    21
    Для того чтобы в следующих уроках разгадывать ее через антигейт.

    Тут фишка в том, что мы узнали что мы хотим искать уже после того как отправили форму. Браузер отобразит уже другую страницу, а фидлер запоминает все запросы. Я понимаю что можно было искать input с именем uniq_id, но не все знают что такое форма на html и откуда браузер берет параметры которые отправляются в post.
     
  7. X-rus

    X-rus Member

    Joined:
    22 Dec 2010
    Messages:
    88
    Likes Received:
    22
    Reputations:
    4
    Дак смотри. Открыл ты страницу регистрации, тут же открыл её исходный код, там же, в браузере. Все параметры сохранились. Регистрируешься, ловишь сниффером данные и тут же можешь посмотреть, откуда взялся тот или иной параметр, тем же методом поиска. :p
     
    1 person likes this.
  8. Kairos

    Kairos Elder - Старейшина

    Joined:
    5 Oct 2009
    Messages:
    37
    Likes Received:
    21
    Reputations:
    21
    Тоже вариант. Тут уже вопрос удобства, я сам тоже чаще исходником страницы пользуюсь.