RSS

Компьютерная терминология    1_9  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  .....  A  Б  В  Г  Д  Ж  З  И  К  Л  М  Н  О  П  Р  С  Т  У  Ф  Х  Ц  Ч

Моделирование эпидемии

   

Моделирование эпидемии

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

О моделировании, так и это тоже не совсем правда. Потому, что моделирование в массовом сознании как бы подразумевает отсутствие практики. Это не так. Наше моделирование -- это средство для получения информации о том, что будет ПОСЛЕ.

Итак, мы ведем речь о планировании действий самораспространяющейся программы.

Поскольку этот текст -- первая попытка описать то, что мы знаем о моделировании, здесь навряд ли получится рассказать обо всем, о чем хотелось... так что не плюйте в монитор.


Основные понятия таковы:

червь --Самораспространяющаяся программа. Направлена на захват интернетовских машин с целью использования их ресурсов.
сеть --(сеть червей) -- виртуальная сущность, множество связанных друг с другом инфицированных машин. Считается, что предусматривается возможность удаленного контроля над элементами сети по-отдельности и над сетью в целом. То есть сеть -- это когда все инфицированные машины действуют согласно некоторому единому плану, при этом обмениваясь некоторой внутренней информацией. Интересным свойством является возможность хранения и обработки распределенной базы данных, т.к. это позволит написать программу, работающую постоянно и независимо от ее носителей.
Nmax --Число моделируемых машин. Будем считать константой. Другими словами, это общее число машин, являющихся потенциальными носителями червя. То есть это те машины, в которых есть такие дыры, которые мы можем использовать. Естественно, мы моделируем не все предполагаемое множество реальных машин, а только некоторую его часть.
Cgmt --Это число отражает вращение земного шарика вокруг своей оси; что, в свою очередь, означает смену дня и ночи, и соответственно здесь есть некоторая связь с включенными/выключенными машинами. Более точно, Cgmt показывает, какую часть суток включена среднестатистическая моделируемая машина. Мы будем называть эту ситуацию "проблемой GMT", так уж повелось.
Например при 8-часовом рабочем дне Cgmt может быть равно 8/24=0.33. Более того, при случайно выбираемых машинах, при большом их числе, Cgmt всегда меньше единицы, так как всегда есть вероятность того, что какие-то из машин выключены.
Na --Число активных машин. Переменно. Зависит от времени дня, от типа моделируемых машин, от распределения машин по временным зонам, и десятков прочих факторов. Поскольку мы ориентируемся на то, что машины разбросаны повсюду, то будем считать, что в среднем, при нормальном положении дел (т.е. изначально), Na=Nmaxgmt, где Cgmt=0.3(imho!) для юзерских машин и Cgmt=1 для серверов.
Ni --Число инфицированных машин, т.е. машин, уже являющихся носителями червя. Переменно. Зависит от времени, прошедшего с момента запуска червя, т.е. от поведения моделируемой системы за прошедшее время. Сюда входят активные и пассивные зараженные машины, т.е. как работающие, так и недоступные в настоящее время (например, выключенные).
Nai --Число активных инфицированных машин. Переменно. Другими словами, это число инфицированных машин, активных на данный момент. Ибо другая часть инфицированных машин "спит", согласно своей временной зоне и привычкам хозяина машины.
Если же червь таков, что хранится исключительно в памяти компьютера, т.е. инфицированная машина после перезагрузки самоизлечивается, то Nai очень близко к Ni, но не равно, так как тут есть такая фича как гибернация (hibernate), и ее стоит иметь в виду -- потому что из этого следует что всегда есть вероятность "всплывания" червя через некоторое время. Кроме того, связь с червем может быть прервана на некоторое время и без всякого выключения/гибернации машины-носителя, хотя бы и из-за временных глюков в сети.
Nai0 --Начальное число активных инфицированных машин, т.е. число машин, с которых начинается массовое распространение червя. Обычно считалось, что равно 1 (запуск с одной машины). Это число суть весьма важный фактор, и увеличивая его можно существенно сократить суммарное время захвата всех машин, а также более точно предсказать изменение числа инфицированных машин Ni, так как в самом начале, при малом числе инфицированных машин, влияние случайных факторов велико.
t --Время, прошедшее с момента активирования червя. Эксперимент мы считаем закончившимся тогда, когда все Nmax (или чуть меньше, 99%) машин инфицированы. Последний 1% машин можно не рассматривать, так как при выборе адреса случайным образом их нахождение потребует сравнительно много времени.
Ts --Время, необходимое на поиск (s=search) новой машины.
В случае, если червь изначально содержит в себе список необходимых адресов, Ts=0. Это может быть достигнуто предварительным сканом.
В случае, если черви хранят и обновляют распределенную базу данных об обработанных адресах, то это время будет постоянно уменьшаться. Поясним на примере: на левой картинке поиск адресов происходит случайным образом, на правой -- с учетом ранее найденных адресов.

Поиск адресов случайным образомПоиск с учетом ранее найденных адресов

Tc --Время, необходимое на проверку (c=check) того, что в софте машины есть одна или несколько определенных используемых нами дыр.
Pc --Вероятность того, что дыры присутствуют. То есть вероятность того, что после проверки (затрачено время Tc) мы будем пытаться машину инфицировать.
Ti --Время, необходимое на инфицирование одной машины. То есть время от начала инфицирования и до получения с инфицированной машины ответа от успешно запущенного червя, плюс (опционально) передача новому червю каких-то данных, в случае, если черви объединены в сеть.
Pi --Вероятность успеха при инфицировании машины. То есть 1-Pi отражает те случаи, когда затрачено Ts+Tc+Ti.
S --шаг по времени.


Откуда взять Cgmt, Ts, Tc, Pc, Ti, Pi ?

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

Как выбрать Nmax и S ?

  1. Варьировать Nmax = 10, 100, 1000, 10 000, 100 000, ...
  2. Построить графики Na(t), Ni(t), Nai(t) для каждого Nmax
  3. Взять то Nmax, для которого результат мало отличается от предыдущего.
  4. То же самое для S = 1,2,3 секунды,... Да, и кстати. Значение S должно быть меньше Ts, Tc и Ti.
  5. Повторять начиная с пункта 1 до тех пор, пока не будет достигнута устойчивость при изменении любого из этих двух параметров -- т.к. это будет означать, что дальнейшее увеличение точности излишне.

Таким образом, задав вышеописанные Nmax, S, Cgmt, Ts, Tc, Pc, Ti, Pi и Nai0, можно построить графики Na(t), Ni(t) и Nai(t).


Теперь собственно о моделировании, но для начала -- о рандомном генераторе. Точнее -- о том, как при моделировании включить/выключить некую i-ю машину около, например, десяти часов. Ясно, что моделировать такое событие для каждой машины ровно в указанное время нельзя -- это будет лажа. Но и рандомно разбросать время включения [9:30..10:30] -- тоже как-то не очень. Ибо тогда получится что до 9:30 машины молчали, а потом в течении ровно часа включались то там то здесь.

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

rnd(N)N/2+rnd(N/2)-rnd(N/2)
N/2+rnd(rnd(N/2))-rnd(rnd(N/2))N/2+rnd(rnd(rnd(N/2)))-rnd(rnd(rnd(N/2)))


Вот весьма простая моделирующая програмка:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define Nmax    10000
#define Nai0    10
#define Cgmt    30              // %
#define S       10              // sec
#define Ts      60              // sec
#define Tc      60              // sec
#define Pc      10              // %
#define Ti      300             // sec
#define Pi      90              // %
#define INMEMORY  0             // 0/1

int t, Na, Ni, Nai;
                                        // биты состояния машины:   параметр:
#define ST_ACTIVE       0x00000001      // активная                 m_time1
#define ST_INFECTED     0x00000002      // инфицированная           m_time1
#define ST_SEARCHING    0x00000004      // идет поиск цели          m_time2
#define ST_CHECKING     0x00000008      // идет проверка цели       m_time2
#define ST_INFECTING    0x00000010      // идет инфицирование цели  m_time2

// моделируемые машины
int m_state[Nmax];  // ST_xxx -- состояние
int m_time1[Nmax];  // [sec]  -- время последующего включения/выключения
int m_time2[Nmax];  // [sec]  -- время окончания поиска/проверки/инфицирования
int m_target[Nmax]; // #      -- индекс обрабатываемой цели

int tmpn;       // временный массив индексов активных машин для ускорения выбора
int tmp[Nmax];  //   случайной машины при инфицировании

// рандомер

DWORD randseed;

DWORD my_random(DWORD range)
{
  randseed = randseed * 214013 + 2531011;
  if (range >= 65536)
    return randseed % range;
  else
    return ((randseed >> 16) * range) >> 16;   // в 1.5 раза быстрее чем %
}

#define rndX(x)   ((x) + my_random((x)/30) - my_random((x)/30))

void main()
{
  randseed = GetTickCount();       // randomize

  FILE*log=fopen("model.log","wb");

  // инициализируем машины
  for(int i=0; i<Nmax; i++)
  {
    if ((my_random(100) < Cgmt) || (i < Nai0))
    {
      m_state[i] = ST_ACTIVE;                         // активная машина
      m_time1[i] = my_random( 24*3600*Cgmt/100 );     // время выключения
      if (i < Nai0)
        m_state[i] |= ST_INFECTED;      // изначально инфицированные машины
    }
    else
    {
      m_state[i] = 0;                                 // выключенная машина
      m_time1[i] = my_random( 24*3600*(100-Cgmt)/100 );  // время включения
    }
  }

  for(t = 0; ; t += S)  // главный цикл, для каждого момента времени
  {

    // включения/выключения машин,
    // это действо имеет больший приоритет чем червь
    for(int i=0; i<Nmax; i++)
      if (t >= m_time1[i])              // окончилось время ожидания?
        if ( m_state[i] & ST_ACTIVE )   // была активная машина?
        {
          m_state[i] &= INMEMORY ? 0 : ST_INFECTED;   // теперь выключена
          m_time1[i] = t + rndX( 24*3600*(100-Cgmt)/100 ); // время включения
        }
        else                            // была выключенная машина?
        {
          m_state[i] |= ST_ACTIVE;      // теперь включена
          m_time1[i] = t + rndX( 24*3600*Cgmt/100 ); // время выключения
        }

    // создаем временный список активных машин,
    // для ускорения выбора случайной машины при инфицировании
    tmpn = 0;
    for(int j=0; j<Nmax; j++)
      if (m_state[j] == ST_ACTIVE)
        tmp[tmpn++] = j;

    // моделируем действия червя
    for(int i=0; i<Nmax; i++)           // для каждой машины
      if (m_state[i] & ST_ACTIVE)       // для каждой активной
      if (m_state[i] & ST_INFECTED)     // для каждой активной-инфицированной
        // ничего не делает?
        if ((m_state[i] & (ST_SEARCHING|ST_CHECKING|ST_INFECTING))==0)
        {
          m_state[i] |= ST_SEARCHING;   // теперь ищет цель
          m_time2[i] = t + rndX( Ts );  // время окончания поиска
        }
        else  // окончилось время поиска/проверки/инфицирования?
          if (t >= m_time2[i])
          {
            if (m_state[i] & ST_SEARCHING)  // искали новую машину?
            {
              m_state[i] &= ~ST_SEARCHING;  // больше не ищем

              // выбираем случайную цель
              if (tmpn) // если таковая имеется
              {
                int ti = my_random(tmpn);
                int tv = tmp[ti];
                tmp[ti] = tmp[--tmpn];
                m_target[i] = tv;           // индекс цели
                m_state[i] |= ST_CHECKING;  // будем проверять на наличие дыр
                m_time2[i] = t + rndX( Tc ); // время окончания проверки
              }

            }
            else
            if (m_state[i] & ST_CHECKING)   // проверяли найденную цель?
            {
              m_state[i] &= ~ST_CHECKING;   // больше не проверяем

              if (my_random(100) < Pc)      // с вероятностью Pc успех
              {
                m_state[i] |= ST_INFECTING;  // теперь будем инфицировать
                m_time2[i] = t + rndX( Ti ); // время на инфицирование
              }
            }
            else
            if (m_state[i] & ST_INFECTING)   // инфицировали?
            {
              m_state[i] &= ~ST_INFECTING;   // закончили

              if (my_random(100) < Pi)       // с вероятность Pi все OK
              {
                // помечаем найденную и проверенную машину как инфицированную
                if (m_state[m_target[i]] == ST_ACTIVE)
                    m_state[m_target[i]] |= ST_INFECTED;
              }
            }
          }

    // считаем статистику
    Na = Ni = Nai = 0;
    for(int i=0; i<Nmax; i++)
    {
      if (m_state[i] & ST_ACTIVE)   Na++;
      if (m_state[i] & ST_INFECTED) Ni++;
      if (m_state[i] & ST_ACTIVE) if (m_state[i] & ST_INFECTED) Nai++;
    }

    // выводим статистику в лог
    fprintf(log,"t=%i Na=%i Ni=%i Nai=%i\n", t,Na,Ni,Nai);

    // последние машины не проверяем -- это долго
    if (Ni >= Nmax*99/100) break;

  }

  fclose(log);

} //main


И вот некоторые результаты:

Как видим на графике выше, в начале число инфицированных машин Ni растет экспоненциально, но с учетом Cgmt, рост резко ограничивается, и далее Ni увеличивается только линейно: ибо Земля вращается равномерно ;-), и начиная со второй части графика все вновь поступившие машины тут же инфицируются. Из этого следует, что с учетом Cgmt, невозможно инфицировать равномерно распределенные по временным зонам машины меньше чем за 24*(1-Cgmt) часов.


Увеличим число моделируемых машин Nmax:

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


Теперь поизменяем различные параметры и посмотрим что получится. Уменьшаем шаг по времени, S:

Результат совсем немного изменился, причем в лучшую сторону; но это не стоит втрое больших затрат по времени (хотя это все равно какие-то минуты).


Увеличим число изначально активных инфицированных машин, Nai0, с которых начинается распространение:

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


Увеличиваем Cgmt до 90%, то есть моделируем машины, включенные большую часть времени:

Результат радует, не правда ли? Несколько часов на все.


Предположим, что червь поддерживает большое количество операционных систем, софта и дыр. Это будет означать, что слегка увеличится время проверок машин на наличие дыр Tc, но вместе с тем и увеличится вероятность их нахождения Pc:

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


Рассмотрим случай, когда червь хранится только в памяти компьютера, и после перезагрузки машина возвращается в обычное не-инфицированное состояние:

Как видим, при Cgmt существенно меньшем единицы, становится невозможным единовременно захватить большую часть машин, так как червь с них постоянно исчезает.

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


Теперь в кратце рассмотрим то, что мы здесь забыли.

seo & website usability inet html os faq hardware faq memory video cpu hdd mainboard faq printer & scaner modem mobiles

Windows 10 | Registry Windows 10 | Windows7: Общие настройки | Windows7: Реестр | Windows7: Реестр faq | Windows7: Настроки сети | Windows7: Безопасность | Windows7: Брандмауэр | Windows7: Режим совместимости | Windows7: Пароль администратора |  |  |  |  | Память | SDRAM | DDR2 | DDR3 | Quad Band Memory (QBM) | SRAM | FeRAM | Словарь терминов | Video | nVIDIA faq | ATI faq  | Интегрированное видео faq | TV tuners faq | Терминология | Форматы графических файлов | Работа с цифровым видео(faq) | Кодеки faq | DVD faq | DigitalVideo faq | Video faq (Архив) | CPU | HDD & Flash faq | Как уберечь винчестер | HDD faq | Cable faq | SCSI адаптеры & faq | SSD | Mainboard faq | Printer & Scaner | Благотворительность

На главную | Cookie policy | Sitemap

 ©  2004