## Внедрение зловредного кода
Атака в ходе которой может быть воссоздан или переиспользован объект языка программирования или технологии, которая используется для работы приложения.
Наиболее популярными способами проведения атак является использование инйекции.
Примеры:
- 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