Кто-то взломал мою базу данных - как?

Кто-то взломал мою базу данных и сбросил таблицу.

На моей странице PHP есть один единственный запрос, в котором я использую mysql_real_escape_string:

$db_host="sql2.netsons.com";
$db_name="xxx";
$username="xxx";
$password="xxx";    

$db_con=mysql_connect($db_host,$username,$password);    

$connection_string=mysql_select_db($db_name);
mysql_connect($db_host,$username,$password);    
mysql_set_charset('utf8',$db_con); 

$email= mysql_real_escape_string($_POST['email']);
$name= mysql_real_escape_string($_POST['name']);
$sex= mysql_real_escape_string($_POST['sex']);    

if($_POST['M']!=""){  $sim = 1;  }else {  $sim = 0;   }

$query = "INSERT INTO `users` (`email`, `name`, `sex`, `M`) VALUES
( '".$email."', '".ucwords(strtolower($name))."', '".$sex."','".$sim."')";    

$res = mysql_query($query) or die("Query fail: " . mysql_error() );

mysql_close($db_con);

И register_globals отключен .

Итак, как была взломана моя база данных?

Ответ 1

mysql_real_escape_string

Соединение MySQL. Если идентификатор ссылки не указан, предполагается последняя ссылка, открытая mysql_connect(). Если такой ссылки не обнаружено, она попытается создать такую, как если бы mysql_connect() был вызван без аргументов. Если соединение не найдено или не установлено, генерируется ошибка уровня E_WARNING.

Как объяснять здесь: Действительно ли mysql_real_escape_string() ПОЛНОСТЬЮ защищает от SQL-инъекции?

Основываясь на фрагменте кода, вы дважды подключили базу данных.

$db_con=mysql_connect($db_host,$username,$password);    

$connection_string=mysql_select_db($db_name);
mysql_connect($db_host,$username,$password);    
mysql_set_charset('utf8',$db_con); 

И вы не указали идентификатор ссылки базы данных для:

$email= mysql_real_escape_string($_POST['email']);
$name= mysql_real_escape_string($_POST['name']);
$sex= mysql_real_escape_string($_POST['sex']); 

Следовательно, mysql_set_charset не влияет на реальный escape, предоставляемый $_POST для многобайтовых символов.

Предложение

  • удалите второй mysql_connect($db_host,$username,$password);
  • явно добавить $db_con при выполнении mysql_real_escape_string

Ответ 2

Это не похоже, что вложенный вами код обеспечивает подходящую атаку. То, как я буду исследовать это, - это сканирование бинарных журналов MySQL для соответствующего оператора DROP TABLE, чтобы дать мне временную метку. Затем вы можете использовать эту метку времени для поиска запросов Apache, которые вы можете с ней сопоставить.

Затем это всего лишь случай тщательного аудита кода в каждом запросе кандидата, пока вы его не пригвоздите: (

Ответ 3

Возможно, у вас есть пользователь MySQL со слабым паролем. Я бы сменил все пароли и проверил, кому разрешено подключаться к базе данных MySQL. Заблокируйте свой брандмауэр, чтобы открыть только необходимые порты (80 443?)

Вот несколько статей о блокировке вашего php-кода http://www.addedbytes.com/writing-secure-php/

С уважением. Асбьерн Морелл

Ответ 4

Тот факт, что ваша база данных была скомпрометирована, не означает, что была введена SQL-инъекция. Если вы хотите, вы можете предоставить доступ к журналу доступа, который должен содержать достаточные сведения о том, где находится злоумышленник. Мое предположение было бы включением локального файла, в котором он включал конфигурационный файл или, возможно, какую-то уязвимость выполнения кода. Без дополнительной информации это просто угадывает, хотя, возможно, это была хорошая работа в социальной инженерии или фишинг-атака...

Ответ 5

На первый взгляд, вы не оставили никаких открытий для атаки на SQL-инъекцию. Является ли этот фрагмент кода определенно тем, где происходит вторжение?

Единственное, что я могу найти, это неоднозначное объявление от хостинг-провайдера о ucwords: http://2by2host.com/articles/php-errors-faq/disabled_ucwords/

С

Ответ 6

Я думаю, что это делается через php shell (backdoor). Это общий хост? если это так, проверьте, атакован ли другой сайт на том же сервере или нет, это поможет вам узнать, попадает ли злоумышленник на ваш сайт из вашего района. Чтобы увидеть веб-сайты на своем сервере, вам нужно выполнить обратное ip-сканирование.