## Внедрение зловредного кода Атака в ходе которой может быть воссоздан или переиспользован объект языка программирования или технологии, которая используется для работы приложения. Наиболее популярными способами проведения атак является использование инйекции. Примеры: - command injections - insecure deserialization - SpEL injection - SQL injection - NoSQL injection - ... Основополагающим методом для проведения инйекций является использование "специальных" символов, которые могут нести дополнительный смысл для технологии, где будет разбираться команда или запрос. Например: - знак ' для SQL языка - знак #{ для SpEL ## Различные контексты инъекций Контекстом инйекции называется действие, которое выполняет оригинальных запрос. То есть это может быть: - SELECT - INSERT - UPDATE - DELETE - ... В зависимости от этого запроса будет меняться "контекст", в общем случае контекст ограничивает возможные действия для проведения атаки. Помимо контекста могут быть так же разные места в самом запросе. Например: - SELECT * from logins WHERE username='[injection]' <= в фильтре, можно бесконечно добавлять конструкции - SELECT * from logins WHERE username='[injection]' and password LIKE '%test%' <= в фильтре, но справа есть дополнительные конструкции, которые нужно или закоментировать, либо свести к "абсурду" ## Причины возникновения - недостаточная нормализация данных - использование "сырых" запросов - выполнение запросов напрямую в базу Примеры: **Java** ```Java= // Get username from parameters String username = request.getParameter("username"); // Create a statement from database connection Statement statement = connection.createStatement(); // Create unsafe query by concatenating user defined data with query string String query = "SELECT secret FROM Users WHERE (username = '" + username + "' AND NOT role = 'admin')"; // ... OR ... // Insecurely format the query string using user defined data String query = String.format("SELECT secret FROM Users WHERE (username = '%s' AND NOT role = 'admin')", username); // Execute query and return the results ResultSet result = statement.executeQuery(query); ``` **Ruby** ```Ruby= class ApplicationController < ActionController::Base protect_from_forgery with: :exception end class UsersController < ApplicationController def update con = Mysql.new 'localhost', 'user', 'pwd' con.query 'UPDATE users set name = ' + params[:name] + ' where id = ' + params[:id] con.close end end ``` **PHP** ```php= <?php require_once('../_helpers/strip.php'); // this database contains a table with 2 rows // This is my first secret (ID = 1) // This is my second secret (ID = 2) $db = new SQLite3('test.db'); if (strlen($_GET['id']) < 1) { echo 'Usage: ?id=1'; } else { // don't sanitize user input, making the SQL query vulnerable to // an injection. The query result only returns a row count, making // it blind. It can be exploited based on whether the server // responds with "Yes!" or "No!" $count = $db->querySingle('select count(*) from secrets where id = ' . $_GET['id']); if ($count > 0) { echo 'Yes!'; } else { echo 'No!'; } } ``` **C#** ```C#= using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Data.SqlClient; namespace WebFox.Controllers { [ApiController] [Route("[controller]")] public class Sqli : ControllerBase { private readonly ILogger<Sqli> _logger; public Sqli(ILogger<Sqli> logger) { _logger = logger; } [HttpGet("{id}")] public string DoSqli(string id) { string conString = "I AM a connection String"; using (SqlCommand cmd = new SqlCommand("SELECT * FROM users WHERE userId = '" + id + "'")) { using (SqlConnection con = new SqlConnection(conString)) { con.Open(); cmd.Connection = con; SqlDataReader reader = cmd.ExecuteReader(); string res = ""; while (reader.Read()) { res += reader["userName"]; } return res; } } } } } ``` **nodeJS** ```js= models.Items.findAll({ limit: '1; DELETE FROM Items WHERE 1=1; --', }).then(function (users) { console.log(users); }); ``` ## Последствия эксплуатации - изменение поведения приложения - добавление новой логики в приложение (может потребоваться дополнительная уязвимость) - чтение/запись файлов в файловой системе сервера с базой данных - отправка HTTP/SMB запросов - выполнение кода в контексте системых приложений ## Способы обнаружения - Web Application FireWall - настройки логирования запросов в БД и настройка постоянного мониторинга - силами SOC ## Примеры и практическое задание - https://portswigger.net/web-security/all-labs (раздел SQL Injection) - https://www.root-me.org/en/Challenges/Web-Server/ - https://ringzer0ctf.com - https://sql.training.hackerdom.ru ## Способы защиты - Prepared statements - ORM (с большим вниманием) ## Дополнительные материалы: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html https://github.com/sqlmapproject/sqlmap