Борьба с мельницами или «О безопасности с умом»

в 9:55, , рубрики: rdp, windows, данные, информационная безопасность, ненормальное программирование, метки: , ,

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

В статье будут затронуты вопросы:

  • Работают ли реально эти технические ограничения?
  • Как сказываются эти ограничения на заказчике и исполнителе?
  • Что делать в итоге?

Работают ли реально технические ограничения

Для простоты здесь рассматривается пример для систем Windows и способ доступа «Удаленный рабочий стол», но рассматриваемая проблема не ограничена только ними.

В число технических ограничений прежде всего входят функции передачи содержимого буфера и обмена файлов. Целью отключения этих функций является лишение возможности пользователя (исполнителя) переносить данные со своего компьютера на удаленное рабочее место, а так же переносить данные в обратном направлении. А значит, если цель выполняется, то ограничения работают. Соответственно, в противном случае, ограничения не работают.

Ответ на поставленный вопрос сильно зависит от стиля удаленной работы. Забегая вперед можно сказать, что ограничения работают не всегда и можно показать способ и конфигурацию, в котором данные ограничения бесполезны.

Рассматриваемый способ доступа имеет следующие характеристики:

  1. Исполнитель работает на своем оборудовании, которое он полностью контролирует (ситуация является обыденной при удаленной работе).
  2. На удаленной системе есть средство автоматизации (VBScript,MSOffice с макросами, Java JDK и т.п.) и исполнитель может им пользоваться.
  3. У пользователя достаточно времени для проведения загрузки или выгрузки данных.
Основная идея

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

Задача передачи файла на удаленное рабочее место разбивается на две подзадачи: кодирование данных в доступную форму для передачи (например, нажатия клавиш) и декодирования данных на рабочем месте в исходный вид. Так как терминал под контролем пользователя, то он может использовать сколь угодно сложные, заранее подготовленные средства для кодирования информации. Но вид данных, сохраняемых на удаленном рабочем месте должен быть прост для декодирования (хотя бы на начальном этапе), т.к. пользователь может быть ограничен средствами и временем.

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

Таким образом, автоматизировав нажатие клавиш по заданной программе и написав (или передав. автоматически) скрипт для декодирования мы получаем решение задачи по передаче файла на удаленное рабочее место. При этом оно никак не зависит от ограничений на передачу данных из буфера обмена или файлов.

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

Реализация задач об обмене данными

Для демонстрации и тестирования возможности передачи данных был создан проект SFAI, который доступен на GitHub. Концепт представляет собой утилиту командной строки, написанную на Java и работающую на x86 и x64 Windows-системах.

В качестве примера кодирования и декодирования данных в изображение можно использовать следующий код:

Простое кодирование
package localhost;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;

public class Main {

  public static void main(String[] args) throws Exception {

    FileInputStream input = new FileInputStream(new File(args[0]));

    int len = input.available();

    byte[] buf = new byte[len];

    input.read(buf);

    int cols = 1024;
    int rows = (buf.length + cols-1)/ cols;

    BufferedImage image = new BufferedImage(cols, rows, BufferedImage.TYPE_INT_RGB);

    int count = 0;

    for(int y = 0; y<rows; y++) {
      for(int x=0;x<cols; x++) {
        int r,g,b;
        if(count<buf.length) {
          int data = buf[count++];
          r = (data & 0xc0);
          g = (data & 0x0f) << 4;
          b = (data & 0x30) << 2;
        } else {
          r = 0;
          g = 0;
          b = 0;
        }
        image.setRGB(x, y, r + (g<<8) + (b<<16));
      }
    }

    ImageIO.write(image, "png", new File("output.png"));
    System.out.println("Done");
  }

}

Простое декодирование

package localhost;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class MainRead {

  public static void main(String[] args) throws Exception {
    BufferedImage image = ImageIO.read(new File(args[0]));
    FileOutputStream output = new FileOutputStream(new File(args[1]));

    int cols = image.getWidth();
    int rows = image.getHeight();

    int count = 0;

    for(int y = 0; y<rows; y++) {
      for(int x=0;x<cols; x++) {
          int data = image.getRGB(x, y);

          int r = (data & 0xff) & 0xc0;
          int g = ((data >> 8) & 0xf0) >> 4;
          int b = ((data >> 16) & 0xc0) >> 2;

          output.write(r|g|b);
      }
    }
    output.close();
    System.out.println("Done");
  }

}
Технические ограничения по скорости

На практике проверены некоторые технические возможности для решения задач. Решения не являются идеальными, но они задают планку снизу по скорости передачи данных.

Используя стандартную и простую функцию Windows API SendInput(), можно достичь скорости передачи данных в 50-150 байт в секунду. Это не быстро, но вполне достаточно для многих целей.

Для получения данных использовалось кодирование файла в RGB-картинку с эффективностью 1 байт на 1 пиксел. Это означает, что картинка 1000x1000 пикселов позволяет передать около мегабайта данных. Стоит заметить, что выгрузка данных в таком виде гораздо быстрее (и беспроблемнее), чем загрузка через эмуляцию нажатия клавиш.

Ограничения и последствия

Как было показано выше, есть ситуации (в которых нет ничего особенного), в которых ограничение функций на передачу данных не работают.

Самым главным негативным последствием для заказчика является ложная уверенность в защищенности своих данных.

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

Что делать?

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

Автор: TolTol

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js