测试运行

用于入侵检测的人工免疫系统

James McCaffrey

下载代码示例

James McCaffrey入侵检测人工免疫系统 (AIS) 是一个软件系统,模特的人体的免疫系统,以保护计算机网络免受病毒和类似的网络攻击行为的某些部分。基本想法是人体免疫系统 — — 这是淋巴细胞 (白血细胞)、 抗体和许多其他组件组成的一个复杂系统 — — 由来已久,提供强大的保护,防止有害的毒素和其他病原体的时间。因此,建模行为的人体免疫系统可能提供有效的架构,对网络攻击。

在这篇文章我描述的一些人工免疫系统的原则,并提出一个程序来演示这些原则。关于认可机构保护工作是仍然相对较新,在我看来,没有商业的实现都是相当准备就绪。本文中介绍的代码将不直接使您能够创建一种切合实际的网络入侵系统,但至少四个理由为什么您可能会发现这篇文章值得一读。首先,代码会给你一个起点的动手实验,用一个简单的 AIS 系统。第二,解释的原则将把你送是相当困难的初始跨栏到这一领域,并允许您了解对认可机构的研究论文。第三,在本文中,在特定的 r 块位匹配和阴性选择,使用的编程技术的几个可以在其他编程方案中很有用。第四,您可能会发现基于行为本身就有趣的人体免疫系统的软件系统建模的想法。

最好的感受我是来看一看的屏幕快照演示的运行,所示图 1。该演示程序开始通过创建一组六个正常模式 (已知不是一些网络攻击的一部分的模式) 代表 TCP/IP 网络数据包中的二进制形式。认可机构术语中,这被称为 self 集。当然,在实际的 AIS 系统,自设将可能包含数万或数十万的模式,并且每个模式会大得多 (通常 48 256 位) 比在这里使用的 12 位。接下来,该演示程序创建三个人工淋巴细胞。每个淋巴细胞已有四位 (再次,人工小) 的模拟的抗体、 年龄和刺激的字段。该抗体字段是本质上是一种探测器。如您很快就会看到,淋巴细胞创建,以便他们都不检测中自设的任何模式。现在,观察每个淋巴细胞有三个连续的 0 或 1s,但中自设的模式没有三个连续相同的位值。

Artificial Immune System Demo
图 1 人工免疫系统演示

已初始化系统后,该演示程序开始微小仿真与六个输入模式。第一个输入检测淋巴细胞 1,但由于每个淋巴细胞有激活阈值,淋巴细胞不会触发报警。在时间 t = 3,淋巴细胞 1 检测到另一个可疑输入但,再次,尚不超过阈值。但在时间 t = 5,淋巴细胞 1 检测到第三个可疑的输入的数据包和模拟触发。

在下面的章节中,我将首先解释人体免疫系统,用于建模的认可机构的关键概念。然后我陪你走的截图中的代码通过图 1。最后,我会给你一些其他的参考资料和有关认可机构的几点意见。本文假定您有至少中间级与现代编程语言的编程技巧。我使用 C# 的演示程序,但我会解释的你需要更改如果你想要我的代码重构到另一种语言 (如 Visual Basic.NET 或 Python。我目前生成的屏幕快照中的所有代码图 1; 代码也是可用在 archive.msdn.microsoft.com/mag201301TestRun

人体免疫系统

一个高度简化的免疫系统的关键要素所示图 2。有害的项目是称为抗原的蛋白质。在图 2 抗原的红色,和有尖角。人体还包含许多非有害的抗原称为自我-抗原,或 self-items。这些自然产生的蛋白质和在图 2 将标记为绿色和有圆角的边。

Key Elements of a Simplified Immune System
图 2 的一个简化的免疫系统的关键要素

淋巴细胞检测抗原。每个淋巴细胞有几个的抗体,可以被认为是探测器。每个抗体是特定于特定的抗原。通常情况下,因为抗体抗原匹配只是近似的淋巴细胞不会触发反应单抗体检测单一抗原时。只有几个抗体检测其相应抗原后将淋巴细胞成为刺激和触发某种形式的防御性反应。

注意没有淋巴细胞检测 self-item 的抗体。真正的抗体生成的胸腺中的免疫系统,但任何检测到的抗体 self-items 被摧毁之前被释放到血液流中,一个称为细胞凋亡的过程。

入侵检测系统,在抗原对应其内容包含某种有害数据例如,计算机病毒的 TCP/IP 网络数据包。自我抗原对应于正常、 无有害网络数据包。抗体对应于大约与匹配一个未知的、 可能有害的网络数据包的位模式。淋巴细胞表示两个或更多的反­机构和检测器。细胞凋亡是使用一种称为阴性选择技术建模的。

程序的整体结构

在所示的演示程序图 1 是一个 C# 控制台应用程序命名为 ArtificialImmuneSystem。我使用 Visual Studio 2010,但任何版本的 Visual Studio 具有 Microsoft.NET Framework 2.0 或更高版本应该工作。我重命名命名为更具描述性的 ArtificialImmuneSystemProgram.cs program.cs,然后从 Visual Studio 模板生成文件,重命名以及相应的类。程序的总体结构中列出图 3

图 3 人工免疫系统的程序结构

using System;
using System.Collections.Generic;
using System.Collections; // for BitArray
namespace ArtificialImmuneSystem
{
  class ArtificialImmuneSystemProgram
  {
    static Random random;
    static void Main(string[] args)
    {
      Console.WriteLine("\nBegin Artificial Immune System for Intrusion" +
        " Detection demo\n");
      random = new Random(1);
      int numPatternBits = 12;
      int numAntibodyBits = 4;
      int numLymphocytes = 3;
      int stimulationThreshold = 3;
      Console.WriteLine("Loading self-antigen set ('normal' historical patterns)");
      List<BitArray> selfSet = LoadSelfSet(null);
      ShowSelfSet(selfSet);
      Console.WriteLine("\nCreating lymphocyte set using negative selection" +
        " and r-chunks detection");
      List<Lymphocyte> lymphocyteSet = CreateLymphocyteSet(selfSet, numAntibodyBits,
        numLymphocytes);
      ShowLymphocyteSet(lymphocyteSet);
      Console.WriteLine("\nBegin AIS intrusion detection simulation\n");
      int time = 0;
      int maxTime = 6;
      while (time < maxTime)
      {
        Console.WriteLine("============================================");
        BitArray incoming = RandomBitArray(numPatternBits);
        Console.WriteLine("Incoming pattern = " +
          BitArrayAsString(incoming) + "\n");
        for (int i = 0; i < lymphocyteSet.Count; ++i)
        {
          if (lymphocyteSet[i].Detects(incoming) == true)
          {
            Console.WriteLine("Incoming pattern detected by lymphocyte " + i);
            ++lymphocyteSet[i].stimulation;
            if (lymphocyteSet[i].stimulation >= stimulationThreshold)
              Console.WriteLine("Lymphocyte " + i + " stimulated!" +
                " Check incoming as possible intrusion!");
            else
              Console.WriteLine("Lymphocyte " + i + " not over stimulation" +
                " threshold");
          }
          else
            Console.WriteLine("Incoming pattern not detected by lymphocyte " + i);
        }
        ++time;
        Console.WriteLine("============================================");
      } // Simulation loop
        Console.WriteLine("\nEnd AIS IDS demo\n");
        Console.ReadLine();
    } // Main
    public static List<BitArray> LoadSelfSet(string dataSource) {..}
    public static void ShowSelfSet(List<BitArray> selfSet) {..}
    public static string BitArrayAsString(BitArray ba) {..}
    public static List<Lymphocyte> CreateLymphocyteSet(List<BitArray> selfSet,
      int numAntibodyBits, int numLymphocytes) {..}
    private static bool DetectsAny(List<BitArray>
      selfSet, Lymphocyte lymphocyte) {..}
    public static void ShowLymphocyteSet(List<Lymphocyte> lymphocyteySet) {..}
    public static BitArray RandomBitArray(int numBits) {..}
  } // Program
  public class Lymphocyte
  {
    public BitArray antibody;  // detector
    public int[] searchTable;  // for fast detection
    public int age;            // not used; could determine death
    public int stimulation;    // controls triggering
    public Lymphocyte(BitArray antibody) {..}
    private int[] BuildTable() {..}
    public bool Detects(BitArray pattern) {..}
    public override int GetHashCode() {..}
    public override string ToString() {..}
  }
} // ns

我删除了所有的模板生成使用除引用系统和 System.Collections.Generic 的命名空间声明。 所以我可以有访问 BitArray 类添加到 System.Collections 命名空间的引用。 启动消息之后, 我实例化静态随机对象使用任意种子值为 1。

如果您比较中的 Main 方法中的代码图 3 的截图中与图 1,您不应该有太多理解程序逻辑的麻烦。 认可机构演示的关键是淋巴细胞类的定义。 请注意,以保持较小的演示代码的大小和清除的主要思路,我删除了所有正常的错误并检查您很可能将包括在试验期间。

淋巴细胞类

淋巴细胞类有四个数据字段:

public BitArray antibody;  // Detector
public int[] searchTable;  // For fast detection
public int age;            // Not used; could determine death
public int stimulation;    // Controls triggering

我宣布与公共范围为简单起见的所有字段。 BitArray 抗体作用域。 如果您不熟悉 BitArray,这个想法是 int 的使用一个普通数组表示的位的集合是 int 的效率非常低,因为每个 int 需要存储的 32 位。 位数组凝结成单个 int 存储,再加上一些开销为该类信息的 32 位。 别有样 BitArray 类的编程语言需要您做低级位操作位掩蔽与位操作。

SearchTable 字段是一个数组,它的检测方法用于极大地提高性能。 年龄字段不用在我的演示程序 ; 许多 AIS 系统跟踪模拟淋巴细胞的年龄和近亲杀死并生成基于年龄的新淋巴细胞。 刺激字段是一个计数器,用于跟踪多少次淋巴细胞对象已检测到可能的威胁。 在此演示中,淋巴细胞刺激值超过 3,stimulationThreshold 值时,会触发警报。

淋巴细胞构造函数是:

public Lymphocyte(BitArray antibody)
{
  this.antibody = new BitArray(antibody);
  this.searchTable = BuildTable();
  this.age = 0;
  this.stimulation = 0;
}

构造函数接受一个 BitArray 参数,表示一种抗原/检测器。 SearchTable 阵列是使用一个名为 BuildTable,我会于短期内提交的私有的 helper 方法实例化的。

任何认可机构系统的关键部分之一是该例程,用于确定是否一种抗原检测模式。 要求精确匹配不是可行 (和不模仿真实抗原行为)。 早期工作对认可机构使用一种称为 r-连续位匹配,其中抗原和输入的模式都有相同的比特数和抗原和模式匹配中 r 个连续位时发生检测技术。 后来的研究表明一种更好的检测算法是 r 块位匹配。 R 块位匹配就是类似于 r-连续位匹配只不过抗原检测仪是小于的模式要检查,和检测时发生抗原匹配模式的 ny 子集。 例如,如果在抗原是 110,一种模式是 000110111 抗原检测起始索引 3 处的模式。

如果你想想 r 块匹配了一会儿,你就会知道它是一个字符串的子字符串函数几乎相同。 唯一的区别该 r 块匹配的匹配项双边投资条约和匹配的子字符串的字符。

在前面的示例中,r 块匹配到一个简单的方法将检查模式起始索引为 0,然后在索引为 1,然后 2,等等。 然而,这种方法是在大多数情况下十分缓慢。 有几个尖端的子串算法,预处理的较小的探测器字符串来创建数组 (通常称为表)。 可以使用此搜索表,向前跳,遇到不匹配时,并极大地提高性能。 在较小的探测器字符串反复用于检查不同模式的情况下 — — 如认可机构入侵检测 — — 的时间和创建搜索表所需的内存是小的代价,以大大提高性能。

淋巴细胞类检测方法使用应用于 BitArray Knuth-莫里斯-普拉特子串算法。 检测方法接受 000110111 等输入的模式,并返回 true,如果当前对象的抗原,如 110,与模式匹配。 检测方法的代码中列出图 4

图 4 检测方法

public bool Detects(BitArray pattern)  // Adapted KMP algorithm
{
  int m = 0;
  int i = 0;
  while (m + i < pattern.Length)
  {
    if (this.antibody[i] == pattern[m + i])
    {
      if (i == antibody.Length - 1)
        return true;
      ++i;
    }
    else
    {
      m = m + i - this.searchTable[i];
      if (searchTable[i] > -1)
        i = searchTable[i];
      else
        i = 0;
    }
  }
  return false;  // Not found
}

检测方法假定搜索表的存在。 记得淋巴细胞构造函数调用 BuildTable 创建的 searchTable 字段的帮助器方法。 中列出的代码 BuildTable 图 5

图 5 BuildTable 方法

private int[] BuildTable()
{
  int[] result = new int[antibody.Length];
  int pos = 2;
  int cnd = 0;
  result[0] = -1;
  result[1] = 0;
  while (pos < antibody.Length)
  {
    if (antibody[pos - 1] == antibody[cnd])
    {
      ++cnd; result[pos] = cnd; ++pos;
    }
    else if (cnd > 0)
      cnd = result[cnd];
    else
    {
      result[pos] = 0; ++pos;
    }
  }
  return result;
}

淋巴细胞类定义重写的 GetHashCode 和 ToString merthods。 GetHashCode 方法用来防止重复淋巴细胞对象和是:

public override int GetHashCode()
{
  int[] singleInt = new int[1];
  antibody.CopyTo(singleInt, 0);
  return singleInt[0];
}

此实现假定 BitArray 抗体领域具有 32 位或更少。 在那里的抗体字段具有超过 32 位的现实情况下,处理重复的淋巴细胞对象不是那么简单的。 一种办法将定义一个自定义哈希代码方法返回 BigInteger 类型 (可用在.NET Framework 4 和更高版本)。

该演示程序中使用的淋巴细胞 ToString 方法是:

public override string ToString()
{
  string s = "antibody = ";
  for (int i = 0; i < antibody.Length; ++i)
    s += (antibody[i] == true) ? "
1 " : "0 ";
  s += " age = " + age;
  s += "  stimulation = " + stimulation;
  return s;
}

创建自设

您当然熟悉与标准 (非认可机构) 的计算机病毒检测软件,如 Microsoft 安全要点。 这些系统通过存储的已知的计算机病毒定义的本地数据库的工作。 当检测已知的病毒模式时,立即警报触发。 这种防病毒系统上现有的病毒,有麻烦处理变动和完全在大多数情况下,面对一种全新的病毒时失败。 认可机构入侵检测工程以相反的方式通过维护一组已知为非有害的输入模式,然后触发警报时检测到未知的模式。 这使得 AIS 入侵检测系统 — — 在原则上,至少 — — 来检测新病毒。 然而,处理误报 — — 也就是说,触发警报上非有害的输入模式 — — 是 AIS 系统的重大挑战。

真正的 AIS 入侵检测系统会收集数以千计的正常输入模式过去一天或几周。 本地主机或服务器上,将存储这些正常的自设的模式。 此外,实际的 AIS 系统会不断更新自设 (和诱导的淋巴细胞集) 的正常模式,以便随着时间的推移核算的网络交通正常变化。 在这篇文章的演示程序创建人工、 静态自订使用 LoadSelfSet 方法:

public static List<BitArray> LoadSelfSet(string dataSource)
{
  List<BitArray> result = new List<BitArray>();
  bool[] self0 = new bool[] { true, false, false, true, false, true,
                              true, false, true, false, false, true };
  // Etc.
bool[] self5 = new bool[] { false, false, true, false, true, false,
                              true, false, false, true, false, false };
  result.Add(new BitArray(self0));
  // Etc.
result.Add(new BitArray(self5));
  return result;
}

该方法接受一个道具不使用数据源参数表明现实情景中自设的数据不会硬编码。 BitArray 构造函数,有点令人惊讶的是,接受 bool 值,其中 true 表示 1 的位,false 表示 0 位的数组。 观察我以这种方式生成的 self 集的数据没有 self-item 有两个以上连续 0 或 1s。

该演示程序使用实用程序方法,其中要求帮助器方法,BitArrayAsString,ShowSelfSet 显示 self 集:

public static void ShowSelfSet(List<BitArray> selfSet)
{
  for (int i = 0; i < selfSet.Count; ++i)
    Console.WriteLine(i + ": " + BitArrayAsString(selfSet[i]));
}
public static string BitArrayAsString(BitArray ba)
{
  string s = "";
  for (int i = 0; i < ba.Length; ++i)
    s += (ba[i] == true) ? "
1 " : "0 ";
  return s;
}

在创建淋巴细胞集

如果你看回人体免疫系统的工作原理的解释,你会注意的淋巴细胞集应包含只有淋巴细胞不能发现任何模式中自设的对象。 中列出方法 CreateLymphocyteSet 图 6

图 6 CreateLymphocyteSet 方法

public static List<Lymphocyte> CreateLymphocyteSet(List<BitArray> selfSet,
  int numAntibodyBits, int numLymphocytes)
{
  List<Lymphocyte> result = new List<Lymphocyte>();
  Dictionary<int, bool> contents = new Dictionary<int, bool>();
  while (result.Count < numLymphocytes)
  {
    BitArray antibody = RandomBitArray(numAntibodyBits);
    Lymphocyte lymphocyte = new Lymphocyte(antibody);
    int hash = lymphocyte.GetHashCode();
    if (DetectsAny(selfSet, lymphocyte) == false &&
      contents.ContainsKey(hash) == false)
    {
      result.Add(lymphocyte);
      contents.Add(hash, true);
    }
  }
  return result;
}

在认可机构术语中,CreateLymphocyteSet 方法使用不利的选择。 对象是生成的然后进行测试,查看它不检测任何模式中自设,,而且,如果随机淋巴细胞淋巴细胞不已经在结果集中。 这种做法是相当粗糙,并有其他更有效的方法。 我使用字典集合道具 bool 值来跟踪淋巴细胞的现有对象 ; 在.NET 框架 4.5 及更高版本的 HashSet 是更为有效的替代。

通过生成随机 BitArray 创建一个随机的淋巴细胞对象:

public static BitArray RandomBitArray(int numBits)
{
  bool[] bools = new bool[numBits];
  for (int i = 0; i < numBits; ++i)
  {
    int b = random.Next(0, 2);  // between [0,1] inclusive
    bools[i] = (b == 0) ?
false : true;
  }
  return new BitArray(bools);
}

帮助器方法 DetectsAny 接受自设,和淋巴细胞通过自设扫描并返回 true,如果任何在自设的模式由淋巴细胞抗原检测到:

private static bool DetectsAny(List<BitArray> selfSet,
  Lymphocyte lymphocyte)
{
  for (int i = 0; i < selfSet.Count; ++i)
    if (lymphocyte.Detects(selfSet[i]) == true) return true;
  return false;
}

该演示程序使用 ShowLymphocyteSet 的实用工具方法来显示生成的淋巴细胞对象:

public static void ShowLymphocyteSet(List<Lymphocyte> lymphocyteySet)
{
  for (int i = 0; i < lymphocyteySet.Count; ++i)
    Console.WriteLine(i + ": " + lymphocyteySet[i].ToString());
}

总结

并解释我已经提交了本文中的代码应该给你一个坚实的基础与认可机构的动手实验。研究人员建议许多选项。例如,在这篇文章的演示程序火灾警报当单个淋巴细胞检测未知的输入的模式的次数多一些阈值数。这里的想法是真正的病原体排出许多抗原。另一个可能性是 AIS 系统需要多个不同淋巴细胞检测同一未知的模式后,才会触发警报。

它是重要的是要指出的是认可机构,并不是用于入侵检测单个解决方案。相反,它意味着一种多层防御,其中包括传统的防病毒软件的一部分。此外,因为与认可机构的工作仍然相对年轻,还有很多悬而未决的问题。如果您想要检查一些对认可机构的研究,我推荐联机搜索文章的作者 S.福雷斯体育威廉斯和美国Aickelin。

Dr。James McCaffrey为伏信息科学 Inc.,他在管理工作在微软雷德蒙德,华盛顿州,校园的软件工程师的技术培训工作。他已为多种 Microsoft 产品效过力,包括 Internet Explorer 和 MSN Search。McCaffrey 是《.NET 软件测试自动化之道》(Apress,2006)的作者。可通过 jammc@microsoft.com 与他联系。

衷心感谢以下技术专家对本文的审阅:Dan Liebling