#import "@local/nure:0.1.0": * #show: pz-lb.with(..yaml("doc.yaml"), title: [SQL-ІН'ЄКЦІЇ], worknumber: 2) #v(-spacing) == Мета роботи Ознайомитися з вразливостями типу "ін’єкції", зокрема SQL-ін'єкції. == Хід роботи #v(-spacing) Для виконання даної практичної роботи та для дослідження вразливостей, було написано PHP додаток, що розміщено за URL: https://vulnerability.linerds.us/. Спершу, будемо розглядати ін'єкції, що можна застосувати до поля "пошуку товару за назвою". Перша ін'єкція дозволяє вивести всі товари, незалежно від назви. `' OR 1=1 --` #figure(image("1st_query.png"), caption: [Поле вводу даних для пошуку товару з введеним шкідливим запитом]) На даний момент, існує всього два товари, але у випадку, якщо їх буде більше -- можна буде отримати всі можливі товари з бази даних. #figure(image("1st_res.png", width: 70%), caption: [Результат роботи шкідливого запиту (виведено всі товари)]) Далі, за допомогою наступної команди, виведемо паролі всіх користувачів з бази даних. `' UNION select password, password, email from users;` Можемо побачити, що дані користувача замінили собою дані товару. Це стало можливим завдяки використанню погано написаного коду, що дозволяє виводити неправильні типи даних та обирає їх не за назвою стовпця, а за індексом. #figure(image("2nd_res.png", width: 50%), caption: [Дані користувача у вигляді товару]) Виконаємо наступну команду, щоб обрати предмет з id, що дорівнює 2. `' or id=2; -- select item with Nth(2nd) id` #figure(image("3_res.png", width: 50%), caption: [Товар з id = 2]) Як можемо побачити, нам справді повернувся предмет з id = 2. Цей функціонал не був задуманий розробниками, а це означає, що можна робити виборку і за іншими параметрами, наприклад, за кількістю товарів на складі. За допомогою запиту, наведеного нижче, робимо SQL-ін'єкцію з використанням UNION та group_concat. Це дозволяє атакуючому (нам) вибрати всі потрібні стовпці та згрупувати їх в один. `' UNION SELECT group_concat('email: ', email, ' passw: ', password), 1, 2 from users -- ` #figure(image("4_res.png", width: 50%), caption: [Продукт з конкатенованими даними користувача]) Використавші ці дані в формі логіну, можемо побачити, що вони є справжніми даними користувача. #figure(image("4_login.png"), caption: [Форма логіну]) #figure(image("4_login_s.png"), caption: [Результат операції логін з отриманими даними]) Далі, спробуємо дістати з таблиці користувачів одного або більше з поштою, яка містить слово "admin". `' UNION SELECT password, username, email from users where email like '%admin%'; -- ` #figure(image("5_res.png", width: 60%), caption: [Дані від акаунту адміністратора]) Використаємо вразливість форми і дізнаємось назви таблиць, що містяться в поточній базі даних. Застосувавши наступний запит, отримуємо назви всіх таблиць. `' union select TABLE_NAME,1,2 from INFORMATION_SCHEMA.TABLES; # ` #figure(image("6_res.png", width: 50%), caption: [Назви всіх таблиць в поточній базі даних]) Застосунок, що відповідає за логіку додатку та взаємодію з БД, використовує правило "oдна БД на окремого користувача". Тож, виконавши запит, що наведений нижче, отримаємо назви всіх БД, а з цим і ID всіх користувачів додатку. `' union select SCHEMA_NAME, 1,2 from INFORMATION_SCHEMA.SCHEMATA; # ` #figure(image("7_res.png", width: 50%), caption: [Назви всіх баз даних в поточній СУБД]) Далі, використовуючи схему з UNION SELECT, змусимо сервер виконувати складні обчислення, викликавши функцію BENCHMARK і передавши в неї функцію шифрування. `' union select BENCHMARK(500000, AES_DECRYPT(AES_ENCRYPT(REPEAT("a",3000), "key"), "key")), 2, 3; # ` Як можна побачити на рисунку нижче, сервер обчислював відповідь на запит трохи більше 50 секунд. #figure(image("waiting_50s.png", width: 80%), caption: [Результат SQL ін'єкції на основі часу]) Бібліотека PDO та багато інших мають обмеження на обчислення декількох модифікуючих запитів одночасно. Наприклад, при виклику методу query(SQL_QUERY) на об'єкті PDO, другий запит (той, що користувач передає після крапки з комою) не виконується. Саме тому модифікуючи шкідливі запити є можливість робити тільки на тих формах, що використовують методифікуючі функції бібліотеки PDO або інших. Наприклад, exec(SQL_INSERT|UPDATE|DELETE). В даному випадку, була використана форма додавання товару в каталог. По перше, можна виконати вставку користувача в базу даних за допомогою наступної команди. `-1); insert into users(username, email, password) values ('hacker2222', 'mail\@hackerr.com' , 'pass'); -- ` #figure(image("8_query.png", width: 60%), caption: [Форма додавання товару з вставленим шкідливим запитом]) Відвідавши сторінку "Users", можна побачити, що нашого користувача було успішно додано. #figure(image("8_res.png", width: 70%), caption: [Результат виконання шкідливого запиту]) Наступна команда змушує базу даних чекати 5 секунд. `'1'); DO SLEEP(5); #` #figure(image("9_res.png", width: 60%), caption: [Очікування відповіді від сервера протягом 5 секунд]) Запит, що наведено нижче видаляє базу даних для поточного користувача. ID для цієї бази даних знаходиться в кукі під ключем "user_id". Після цього додаток перестає працювати. Для того, щоб він знову запрацював, треба видалити кукі для сайту, де він розташований. Далі, для користувача створиться новий ID та нова база даних. ```3); drop database `6d3147fd-d529-4dfb-a2d8-036904283326`; ``` #figure(image("10_query.png"), caption: [Кукі, де зберігається ID користувача та шкідливий запит на видалення його бази даних]) #figure(image("10_res.png"), caption: [Результат видалення бази даних користувача]) // === Підготовка // #lorem(150) // === Виконання дослідження // #lorem(300) // === Підрахунок результатів // #lorem(250) == Висновки Було проведено ознайомлення з вразливостями типу "ін’єкції", зокрема SQL-ін'єкціями. Був розроблений веб-тренажер для ін'єкій мовою PHP, що демонструє потенціальну небезпеку. Були проведені різні типи атак, включаючи атаки часом, екранування запиту, ін'єкції в параметри та використання UNION і group_concat. // == Контрольні запитання // #lorem(100): // - #lorem(20); // - #lorem(30); // - #lorem(15); // - #lorem(25); // - #lorem(42); // - #lorem(27). #show: appendices_style // = Quote // #link("https://youtu.be/bJQj1uKtnus")[ // The art isn't the art, the art is never the art, // the art is the thing that happens inside you when you make it and the feeling in the heart of the beholder. // ] // = Приклад звіту 1 // #v(-spacing) // == Частина 1 // #lorem(100) // == Частина2 // #lorem(200) // // = Приклад звіту 2 // #lorem(200) // // = Приклад звіту 3 // #lorem(200)