Я просмотрел весь Google, чтобы узнать, как можно обойти следующее (это от высокого уровня безопасности от DVWA):
$id = $_GET['id']; $id = stripslashes($id); $id = mysql_real_escape_string($id); if (is_numeric($id)){ $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"; $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' ); $num = mysql_numrows($result); $i=0; while ($i < $num) { $first = mysql_result($result,$i,"first_name"); $last = mysql_result($result,$i,"last_name"); echo '<pre>'; echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last; echo '</pre>'; $i++; } }
Можно ли это взломать?
Для тех, кто не знаком с DVWA, вот видео с YouTube: http://www.youtube.com/watch?v=oMV0JZVxvdQ
Кроме того, моя другая забота находится на среднем уровне. У него действительно работает mysql_real_escape_string()
, но когда вы используете ту же инъекцию SQL с низкого уровня И вы удаляете кавычки, она обходит защиту. Почему это? Почему так легко обойти mysql_real_escape string
?
Код (краткая версия) среднего уровня:
$id = $_GET['id']; $id = mysql_real_escape_string($id); $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
Я хочу использовать PDO, так как это, вероятно, намного безопаснее. Пожалуйста, дайте мне знать ваши мысли об этом.
Заранее большое спасибо.
Добавление is_numeric
не сделало бы это очень вероятной полномасштабной атакой sql, но is_numeric
просто не очень точная:
is_numeric('0xdeadbeef') // true is_numeric('10e3') // true
Вероятно, лучше использовать фильтры:
if (false !== ($id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT))) { }
У меня такая же проблема. Я не знаю, как это взломать.
Но я думаю, что у меня есть ответ на проблему на среднем уровне, я думаю, что это ошибка программиста.
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id"
Обратите внимание, что на низком и высоком уровне у вас есть котировки в $ id, а не на Medium … Я думаю, что в этом смысл. Если у вас есть это:
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"
Я уверен, что было бы непросто обойти строку mysql_real_escape на среднем уровне.
Другими словами, я уверен, что если бы у вас не было котировок на высоком уровне, вы тоже могли бы сделать инъекцию.
На среднем уровне просто используйте: 1 and 1=1 order by X
Все запросы автора являются низкими, но вы можете заменить имя таблицы шестнадцатеричным кодом 0x...
, например, where table_name=0x12345
. Если мы используем строковый символ, у нас будет ошибка, потому что '
не разрешено.