Хакнули мой скрипт. Помогите узнать как

Kostyab

Новичок
Хакнули мой скрипт. Помогите узнать как

Привет всем!
У меня на сайте есть анкета для посетителей (типа закажите доп. инфу).
Есть обязательные для заполнения графы, ведется проверка не только факта заполнения, но и правильности e-mail и т.п.
Не заполнил -- вывожу сообщение об ошибке и форму снова.
Правильно -- спасибо+на мыло мне+в базу MySQL.
Так вот, сегодня я получил 6 странных писем.
Все графы заполнены как operations1961@******.ru (звездочки - это адрес моего сайта, правильный). Вроде бы от:
----------------------------------
Данные отправлены от: always
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: again. t
bcc: [email protected]
----------------------------------
Короче говоря, если кто готов помочь разобраться в чем дело, я могу прислать два файлика моего скрипта. Не хочу тут место занимать - код все-таки длинный.
Хостинг: Вальюхост, версия PHP 4.3.10
Спасибо всем. Пока
 

whirlwind

TDD infected, paranoid
>правильности e-mail

достаточно будет скинуть сюда:

1. регулярки (или что там) которыми выполняется валидация
2. код формирования запроса (данные квотятся или как всегда дальше " '$param' " дело не идет?)

и еще могу посоветовать грепнуть логи вебсервера на предмет update,insert,select
 

Kostyab

Новичок
Скрипт организван из двух файлов:
1) anketa.php -- стандартная html-форма для заполнения. Два <select> и несколько <input type=text>
Вот один из селектов:
<select name="exhibition">
<option value="stop">Выберите в меню:</option>
<option value="intourfest">Интурфест</option>
...
2) mail_anketa.php

Проверка e-mail:
if (!eregi("^.+@.+\\..+$",$email)){
$error6="<li>$no_email</li>";
$result=0;
}
Проверка селекта:
if ($exhibition=="stop"){
$result=0;
$error1="<li>$no_exhibition</li>";
}
Есть все остальные проверки делаются аналогично.
Далее:
if ($result==1){
$from="$SiteName <$AdminEmail>";
$headers="Content-Type: text/html; charset=windows-1251\n";
$headers.="From: $from\nX-Mailer";
mail($email, "$ThankYouMessage", $UserMessage, $headers);
.....
И записываем в базу данных:
$lang="RUS";
$date=date("d:m:Y H:i");
db_connect();
$query="insert into anketa values ('','$exhibition','$documents','$firm','$tel','$name','$email','$internet',
'$republic','$postindex','$gorod','$ulitsa','$dop','$date','$lang')";
$result = mysql_query($query);
if (!$result) echo "Беда!!!";
mysql_close();
++++++++++++++++++++++++++++
Проблема в том, что хакеры как-то обошли проверку <селектов> и на мыло пришли пустые строки, а все остальные поля заполнены как я уже говорил выше: типа [email protected]

Спасибо.

Бресь Сергей! За меня ничего делать не нужно, если нет желания помочь, просто не тратьте время. В конце концов у меня и так все работает. Просто хочу понять что я делаю не так и избежать ошибок в дальнейшем.
 

whirlwind

TDD infected, paranoid
греп логов делали? все ваши проверки - не проверки. от SQL-инжекта помогает mysql_escape_string.
 

Сергей123

Новичок
Бресь Сергей! За меня ничего делать не нужно, если нет желания помочь, просто не тратьте время. В конце концов у меня и так все работает. Просто хочу понять что я делаю не так и избежать ошибок в дальнейшем.
Вы меня, видимо, не так поняли. Я пошёл бы в любом случае, просто спрашивал где я нужен - слева или справа?

su1d уже всё подсказал.
Если вкратце, - не надо слать ничего никуда, если там, где не могло быть перевода строки, он был (например, email).

-~{}~ 10.02.06 14:51:

(например, любой email)
 

Kostyab

Новичок
Спасибо!
Насколько я понял, с помощью моего скрипта хакеры хотели рассылать спам якобы от моего имени... Вот беда-то, меня ж отключит злой провайдер.
Итак, я понял, что мне надо:
1) более чщательно проверять <select>. OK, понятно
2)
Если вкратце, - не надо слать ничего никуда, если там, где не могло быть перевода строки, он был (например, email).
Поясни пожалуйста подробнее, не понятно.

Я не знаю что такое греп логов, но логи изучал визуально: ничего не нашел. Правда, я не четко знал, что искать...

-~{}~ 10.02.06 16:33:

Перечитал еще раз статью про mail inject.

Видимо, у меня проверка
if (!eregi("^.+@.+\\..+$",$email)){
слабовата?

Надо проверять, чтобы адрес был один, но как?
 

Сергей123

Новичок
В $email, $ThankYouMessage и $AdminEmail не должно быть переводов строк. Есть хоть в одной перевод строки - не выполнять mail().
Как именно реализуешь это - всё равно.

-~{}~ 10.02.06 15:36:

и в $SiteName
 

Kostyab

Новичок
Понял, буду париться. Спасибо

-~{}~ 10.02.06 17:46:

Не выходит!
Как советует тот сайт про mail injecting:
if (eregi("\r",$email) || eregi("\n",$email)){
....
скрипт пропускает:
[email protected]\nCc: [email protected]; [email protected];

Помогите написать regexp, чтоб не пропускал...
 

Kostyab

Новичок
ВОО!!!
Отлично! Работает!
+++++++++++++++++++++
if (!eregi("^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$",$email)){
$error6="<li>$no_email</li>";
$result=0;
}
//mail injecting
if (preg_match('(\n|\r)',$email)){
$error6="<li>$no_email</li>";
$result=0;
}
++++++++++++++++++++++++++
Проверял, не пропускает вроде. Спасибо всем за помощь!
 

que_bunt

Новичок
ух, ты! если б не всплила эта тема то я так бы и писал скрипты уязвимые к "mail injecting", пока бы сам на этом где-нибудь не прокололся!

и отдельный сенкс demiurg за поучительную статью!


кстати Kostyab можно код заключать не в "++++++" а в теги [ php][/ php] он тогда ещо подсвечиваться будет ;-)
 

Kostyab

Новичок
Спасибо за участие, que_bunt!
Я тоже спешно все мои скрипты просматриваю.
Если честно, я очень волновался и торопился все исправить, так как в этот вопрос вмешалось начальство -- нас грозились отключить за спам. Про теги я в спешке не думал. Впредь внимательнее буду.

На самом деле я часто имел необходимость в помощи форума, но каждый меня раз выручал поиск. Это мое первое сообщение за очень долгое время; оно меня очень выручило, спасибо всме большое.
 

sage

Новичок
PHP 5.1.2:

PHP:
preg_match('#\n#', '[email protected]\nCc: [email][email protected][/email]; [email][email protected][/email];', $matches);

var_dump($matches);
Код:
array(0) {
}
PHP:
preg_match('#\\n#', '[email protected]\nCc: [email][email protected][/email]; [email][email protected][/email];', $matches);

var_dump($matches);
Код:
array(0) {
}
PHP:
preg_match('#\\\n#', '[email protected]\nCc: [email][email protected][/email]; [email][email protected][/email];', $matches);

var_dump($matches);
Код:
array(1) {
  [0]=>
  string(2) "\n"
}
-~{}~ 11.02.06 15:53:

причём, на 4.4.1 результат такой же, что и на 5.1.2

-~{}~ 11.02.06 16:03:

и как у вас всё работает?
 

serglt

Анус, ой, Ахтунг
Наверно надо поменять одинарные кавычки на двойные :)

'\n' == "\\n";
"\n" != '\n';
 
Сверху