安全
环境与安全
- 威胁
目标 | 威胁 |
---|---|
数据机密性:数据持有者可指定谁可以获取数据,系统会强制执行规则 | 数据暴露 |
数据完整性:改动数据应该需要得到许可 | 数据篡改 |
系统可用性:没有人可以扰乱系统使之瘫痪 | 拒绝服务 |
- 入侵者
操作系统安全
- 被动攻击:窃取信息
- 主动攻击:使程序行为异常
可信系统
现代操作系统复杂的功能决定了必然不存在某种方式来确保绝对安全
可信计算基(TCB)
实施安全规则所必须的硬件和软件
通过访问监视器,接收所有系统请求 由其决定是否运行
必须包含在TCB的功能:
- 进程创建
- 进程切换
- 内存页面管理
- 文件和IO管理
保护机制
制订可以做的事情,描述系统哪些资源需要保护
保护域
系统中有许多对象,域就是(对象,权限)对的集合
进程会在某个域中运行 可以获得对象的权限,需要时,可以切换域,这样对象的权限也会发生改变
满足最小权限原则,安全性将达到最好
保护矩阵
系统可以通过保护矩阵来跟踪确定对象属于哪个域
访问控制列表(ACL)
对于稀疏的对象权限,矩阵会浪费大量空间,使用ACL:
ACL也不仅可以只对用户授权 也可以对用户组进行授权:
UID,GID:permissions;
同时,可以引入通配符来使用户可以访问与当前登录组无关的情况
也可以使用另外一种方式来管理用户和用户组:
File:UID1:RW;UID2:RWX
通过ACL 可以很方便对用户进行赋权收权
权能字
防止权能字被修改:
- 内存字必须拥有额外的位来判断是否包含权限字
- 在操作系统保存权能字列表
- 在用户空间对权能字加密管理
相对来说 权能字效率较高 ACL需要进行搜索操作
安全系统的形式化模型
多级安全
强制性的访问控制:确保系统的安全策略被强制执行
- Bell-LaPadula模型:保证数据不会从高一级泄漏到低一级
- 简易安全规则:密级为k的进程只能读取同一密级或者更低密级的对象
- *规则:密级为k的进程只能写同一密级或者更高密级的对象
实现:为用户分配安全级别,shell获取级别,该安全级别随着shell创建的所有子进程继承下去
- Biba模型
- 简单完整性规则:只能写同一等级或者更低等级
- 完整性 * 规则:只能读同一等级或者更高等级
隐蔽信道
也称为边信道 指应用程序可以通过各种精巧的信道,如CPU使用率 声音等来向外传输信息
隐写术:通过利用某些文件的编码,将信息编入文件,从而携带出去
可信平台模块
TPM:硬件加解密模块
认证
弱密码
- 战争拨号器与IP端口扫描
UNIX密码安全性
UNIX通过对密码加盐的方式抵御大部分外部攻击
- 一次性密码
单向散列链:通过初始化对一个密码进行n轮散列运算,第i次登陆的密码散列就是n-i+1次散列运算结果
- 挑战-响应认证
通过为用户选择一种运算,服务器传递给用户一串参数,用户运算后回传相关结果来进行认证。运算方式可以经常发生变化
物理识别
- 磁条卡
- 此条可以写入140字节的数据
- 芯片卡
- 储值卡:有ROM,可以存储数据
- 智能卡:携带微型处理器,可以进行运算
生物识别
注册部分:提取用户特征后进行存储
识别部分:比对登录用户特征与存储的用户特征
- 虹膜识别
- 声音测定
软件漏洞
红皇后效应:不进则退
缓冲区溢出攻击
void A(){ char B[128]; gets(B);}
超过缓冲区长度的数据将会直接覆盖到栈上,攻击者可以借此重写返回地址 从而让程序跳转到某个地方
这种类型的漏洞适用于任何复制缓冲区中用户提供的数据且不做任何边界检查的情况
空指令滑行区
如果无法猜测到返回地址,则填充大量无操作的机器指令并最终附带恶意代码,只要代码执行到此处,最终都会被运行
栈金丝雀保护
通过编译器在返回地址下面插入个随机值,函数返回时检查这个随机值 如果不匹配,就停下来
- 反栈金丝雀:缓冲区溢出不仅可以通过修改返回地址来实现,也可以通过修改栈内的变量或者函数指针等来使代码跳转到非预期的地方
数据执行保护(DEP)
只要禁止在堆和栈执行字节就能避免溢出攻击(但这个措施不现实),现代操作系统通过一个NX位来保证某些区域的数据可写不可执行或者可执行不可写
- 代码重用攻击:攻击者不需要引入新代码,基于现有的二进制文件或者库就可以构造必要的功能
地址空间布局随机化(ASLR)
随机化程序每次运行所用的函数和数据的地址
- 反ASLR
- 有些操作系统随机化程度不够
- 通过内存泄漏泄漏内存布局 进行攻击
非控制流转向攻击
此种攻击并非是劫持程序控制流 同样是通过溢出的方式修改栈内变量来改变程序执行结果
格式化字符串攻击
printf(gets())
输入格式化字符串可以覆盖内存
悬垂指针
int *A = (int *)malloc(128);//...free(A);A[0] = xx;
内存空间释放后 这样的操作极有可能将别处缓冲区的数据覆写
空指针间接引用攻击
现代操作系统都会进行内存映射 如果进程的内存空指针真正映射到地址0 那除了进程崩溃之外 攻击者可以通过某种手段进行映射修改 使之映射到某段恶意代码
整数溢出攻击
如图形程序通过整数溢出的方式来修改高度宽度 这样图像的内存也很容易溢出 从而造成跟缓冲区溢出类似的效果
命令注入攻击
可执行空间保护:对于一个进程使用的内存,只把其中的指令部分设置成“可执行”的,对于其他部分,比如数据部分,不给予“可执行”的权限
原理同注入攻击一样,都是由于将用户输入的数据当做代码执行
检查时间/使用时间攻击
假设系统先检查 后打开文件 攻击者利用竞争条件在中间创建一个本不属于自己的符号链接 可能会导致权限验证失效
内部攻击
- 逻辑炸弹
- 后门陷阱
- 登陆欺骗
恶意软件
特洛伊木马
- 诱导用户下载主动运行
- 替代真实程序等待用户运行或者误操作激活
病毒
一个插入到正常程序的恶意程序,称之为感染 让感染的程序被运行,会感染其他程序 从而继续传播
局域网可传播病毒的原因:局域网的计算机通常能直接通过网络登录并执行命令
- 共事者病毒:病毒被启动会启动正常程序来进行掩盖
- 可执行程序病毒:感染可执行程序,通过将病毒二进制代码跟正常程序藏在一起
- 提供存活能力
- 随机感染
- 不重复感染
- 提供存活能力
- 内存驻留病毒:藏在内存中,拦截系统调用对可执行程序进行感染
- 引导扇区病毒:覆盖磁盘主引导记录或引导扇区
- 设备驱动病毒:UNIX中设备驱动是启动时被加载的可执行程序 如果设备驱动被感染 运行在核心态病毒可以直接劫持系统调用
- 宏病毒:诸如WORD文档之类的文件可以包含可执行指令
- 源代码病毒:不可信赖的外部三方库
蠕虫
- 使用rsh运行远程shell
- 利用finger的缓冲区溢出漏洞
- 利用sendmail的bug
间谍软件
间谍软件的扩散:
- 类似木马
- 利用浏览器的扩展
- 不断骚扰用户
间谍软件的行为:
- 广告弹窗 改变系统默认行为以谋取利益
rootkit
试图隐藏自身的存在
- 固件rootkit:隐藏在固件中
- 管理程序rootkit:通过启动一个虚拟机运行操作系统和程序以达到隐藏效果
- 检测资源与实际硬件资源的细微差异
- 内核rootkit:感染操作系统并作为驱动以隐藏
- 库rootkit:隐藏在系统库中
- 应用程序rootkit:大型应用会创建许多文件 这里是隐藏的好去处
除了管理程序或者主动rootkit(会对检测程序进行干扰),其他都可以通过文件散列方式来进行查找rootkit
防御
- 多层安全性
防火墙
通过一系列的规则来决定是否对网络流量放行
- 软件防火墙
- 硬件防火墙
反病毒和反反病毒
- 病毒扫描器
通过放出一个不执行任何操作的诱饵程序让病毒感染 获取病毒的完全代码表并上报到数据库
数据库的病毒特征可以下载下来与本地程序进行对比扫描,可以通过记录文件的属性来提高效率,但病毒可能会对程序进行压缩逃避此类扫描
病毒为了逃避扫描软件的特征扫描 可能会通过每次感染加解密并使用不同密钥的方式进行变换形态
另外一种方式是交换机器码指令而不影响程序功能来躲避扫描 同时有些病毒会控制系统调用,扫描软件有时就必须跳过操作系统直接操作物理硬盘来进行扫描
- 完整性检查程序
通过在信任状态时对系统文件进行求校验和 当下次发现校验和不一致时就能发现被感染 这种情况需要注意对校验和的存放及加密
- 行为检查程序
如覆盖引导扇区的程序几乎可以断定是病毒 但如覆盖可执行程序就是一个特殊操作,反病毒软件应该发出一个警告
代码签名
只允许那些来自可靠厂商的软件
通过公钥密码体系来验证软件是否被篡改过
囚禁
- 沙盒技术
基于模型的入侵检测
通过生成正常程序的系统调用图来检测程序是否被感染
攻击者会使用模拟攻击来生成与原有程序相同的调用图迷惑IDS
对于更多的IDS,使用称为蜜罐的系统来监视攻击并提取相关特征
可下载代码病毒防御
- 沙盒法:保证可下载代码不能跳转到沙盒之外执行
- 对于可下载代码的系统调用 使用一个监视器来控制 必要时拒绝掉移动代码的系统调用请求
- 解释执行:通过这种方式阻止小程序获得对硬件的控制 缺点是速度比较慢