Стаття Хакан php!

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

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

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

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

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

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

$ A = system ($ command);
echo "$ a";
?>

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

У PHP є два оператори - require і include, які зчитують і виконують код із зазначеного файлу. Завдяки цьому можна створити багато разів використовувані функції і константи в окремому файлі і викликати їх в інших сценаріях. (Часто для зручності конфігурації сценарію все його налаштування зберігаються в невеликому скрипті, де їх може легко редагувати який не знає мови людина, не боячись пошкодити основний код. Або, скажімо, дуже зручно включати шматки html'я, щоб багаторазово не виписувати одні й ті ж елементи.)

Функції, як бачиш, корисні і для кодерів, і для хакерів;). У чому різниця між include (); і require () ;? Вона непомітна, але принципова: require (); просто замінюється під час інтерпретації кодом із зазначеного файлу, а include (); обчислює і виконує код в зовнішньому файлі при кожному виявленні оператора include. Це дозволяє використовувати функцію в циклах, що було б неможливим з require. І ще. При виконанні цих функцій повертають значення - якщо виникла проблема, то false, якщо все ОК, то true. Різниця в тому, що при виникненні трабла з require сценарій буде зупинений, в разі, якщо використовується include, його виконання продовжиться. Таким чином, require, в общем-то, еквівалентний коду:

Взагалі, функція system виконує будь-яку команду на сервері, повертаючи результат її виконання. На ній, до речі кажучи, багато багів засноване. Наприклад, для відправки пошти часто використовується ось такий код:

Усе ;). Тепер, коли перець пропатчити бажний движок, у тебе буде бекдор, за яким ти зможеш ще разок ломануть сайт;) Правда, недовго він буде працювати - якщо перець НЕ дебіл, то, після другого дефейса, він подивиться логи веб-сервера та миттю тебе запали, (((. Але завжди залишається шанс, що у нього чи ні доступу до логів (напише адмінам, надішлють йому логи; (), або немає мізків.

Опісалово: У ранніх версіях движка використовувалися статичні імена таблиць (типу messages, authors). Зрозуміло, що їх наявність в базі даних досить імовірно, і щоб уникнути непорозумінь, до імен тепер додається префікс із змінної $ prefix, яка визначається в конфігураційному скрипті config.php. SQL-запит до бази даних в цьому випадку виглядає приблизно так:

mysql_query ( "UPDATE $ prefix" ._ stories. "SET
counter = counter + 1 where sid = $ sid ")

Як бачиш, тут відбувається виклик 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 ".

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

Опісалово: Мда. дірочка стара як світ, а ось програміст про неї чомусь не подумав. Ну що ж, отримуй;).

Читаємо будь-який файл, доступний даному користувачеві. Наприклад, можна прочитати конфігураційний скрипт і вивудити звідти пароль до БД, який може співпасти з паролем на FTP-сервер з сайтом, і так далі. Уяви собі, що перевірка змінної $ l на ".." ВЗАГАЛІ відсутня. Це мене дуже засмутило - ну не вмієш писати, не пиши. Немає ж, лізуть, та ще й виставляють свої творіння на загальний огляд - незрозуміло, навіщо?

Адмін;)
Уразливі версії: 0.4.02 (остання)
Діагноз: отримання прав адміністратора
Xploit: cookie access = ok

Опісалово: Чесно кажучи, коли я вичитав про цей баг, я іржав хвилин п'ять, після чого знову засумував. Це скільки ж і чого треба випити, щоб ідентифікувати адміністратора по cookie "access" з значенням "ok"? Ні, якби це був приватний, оригінальний скрипт - куди не йшло, адже дізнатися про баг можна тільки подивившись його код, зовні докопаєшся. Але ж Сорс проекту викладені на сайті, тому знайти цю тупість - п'ятихвилинне справа. Дивись сам:

Xoops - черговий дірявий движок, досить, як мені здалося, функціональний, тому досить поширений;). Дірок я в ньому знайшов не так вже й багато - по-перше, продукт зовсім молодий, а по-друге, програмісти думали про security при його написанні, хоча, як видно, недовго.

Опісалово: В скрипті 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'

Ясна річ, що замість "update x_users." Може стояти будь-sql-запит, права на виконання якого є у поточного sql-ного користувача.

Цей абзац присвячений тим, хто НЕ ЗНАЄ, як шукати вразливі сайти. Якщо ти не з їх числа - пропускай ці рядки, нічого не втратиш. Отже. Почнемо з азів. Що таке скрипт? Крім виконуваної на стороні сервера програми, це просто файл. І як всякий файл, який працює в сайті, на нього ведуть гіперпосилання жодна стаття.

P.S.
Я розповів тобі про трьох бажних site engine'ах. Показав на їх прикладі найтиповіші для php уразливості - візьми будь дірявий php-скрипт з багтрака, там, швидше за все, будуть точно такі ж діри. Сподіваюся, ти не сприймеш статтю, як керівництво по скріпткіддінгу, а зрозумієш, що зламувати PHP нітрохи не менш цікаво, ніж perl;).

P.P.S. Всі баги тестувалися на локальному веб-сервера Apache під winNT з прикрученим PHP третьої версії.
Хай щастить ;)

Схожі статті