2019级信息安全方向软件安全技术课 代课教师为王星魁
一、书上重点:
第一章
1.零日攻击
什么是零日攻击?
零日漏洞是指未被公开披露的软件漏洞,没有给软件的作者或厂商以时间去为漏洞打补丁或是给出解决方案建议,从而使攻击者能够利用这种漏洞破坏计算机程序、数据及设备。注意,零日漏洞并不是软件发布后被立刻发现的漏洞。
利用零日漏洞开发攻击工具进行的攻击称为零日攻击。零日攻击所针对的漏洞由于软件厂商还没有发现或是还未提供相应的补丁,所以零日漏洞攻击的成功率高,造成的破坏大。
2.软件漏洞
什么是软件漏洞?
软件漏洞通常被认为是软件生命周期中与安全相关的设计错误、编码缺陷及运行故障等。
3.恶意代码
恶意代码的概念?
恶意代码是未在授权的情况下,以破坏硬件设备、窃取用户信息、干扰用户正常使用、扰乱用户心理为目的而编制的软件或代码片段。
包括计算机病毒、蠕虫、特洛伊木马、后门、勒索软件等等。
4.软件安全
什么是软件安全?
软件安全是软件工程与软件保障的一个方面,它提供一种系统的方法来标识、分析和追踪对危害及具有危害性功能(例如数据和命令)的缓解与控制。
5.用信息安全的基本属性理解软件安全
*CIA
什么是CIA
信息安全的三大基本属性CIA——保密性、完整性、可用性。
1.保密性
信息安全中保密性是指确保信息资源仅被合法的实体(如用户、进程等)访问,使企业不泄露给未授权的实体。这里所指的信息不但包括国家秘密,而且包括各种社会团体、企业组织的工作秘密和商业秘密,以及个人秘密和个人隐私。保密性还包括保护数据的存在性,有时候存在性比数据本身更能暴露信息。
2.完整性
信息安全中的完整性是指信息资源只能由授权方以授权方式修改,在存储或传输过程中不被授权、未预期或无意篡改、销毁,或在篡改后能够被迅速发现。不仅要考虑数据的完整性,还要考虑操作系统的完整性,既保证系统以无害的方式按照约定的功能运行,不被有意的或者意外的非法操作所破坏。
3.可用性
信息安全中的可用性是指信息资源(信息、服务和IT资源等)可被合法实体并按要求的特性使用。例如,破坏网络和有关系统正常运行的拒绝服务攻击就属于可用性的破坏。
什么方法可以实现CIA?
实现保密性的方法一般是通过信息加密,或是对信息划分密级并为访问者分配访问权限,系统根据用户的身份权限控制对不同密级信息的访问。
实现完整性的方法一般分为预防和检测两种机制。预防机制通过组织任何未经授权的方法来改写数据的企图,以确保数据的完整性。检测机制并不试图阻止完整性的破坏,而是通过分析用户或系统行为,或是数据本身来发现数据的完整性是否遭到破坏。
为了实现可用性,可以采取备份与灾难恢复、应急响应、系统容侵等许多安全措施。
CIA的目标
CIA网络安全的核心目标是为关键资产提供机密性、可用性和完整性。
6.软件安全相关概念
软件可靠性:
软件可靠性作为衡量软件质量的唯一特性受到特别重视,软件可靠性定义如下:
*在规定条件下,在规定时间内不引起系统失效的概率。该概率是系统输入和系统使用的函数,也是软件中存在缺陷的函数。系统输入将确定是否会遇到已存在的缺陷。
*在规定时间周期内所述条件下程序执行所要求的功能的能力。
由上述定义可知,软件可靠性不但与软件存在的缺陷和/或差错有关,而且与系统输入和系统使用有关,提高软件可靠性就是要减少软件中的缺陷或错误,提高软件系统的健壮性。因此,软件可靠性通常涉及软件安全性的要求,但是软件可靠性要求不能完全取代软件安全性的要求。
可信软件:
一般认为,“可信”是指一个实体在实现既定目标的过程中,行为及结果可以预期,它强调目标与实现相符,强调行为和结果的可预测性和可控制性。软件的“可信”是指软件系统的动态行为及其结果总是符合人们的预期,在受到干扰时仍能提供连续的服务。这里的“干扰”包括操作错误、环境影响和外部攻击等。
软件定义网络(SDN):
把当前IP网络互联结点中决定报文如何转发的复杂控制逻辑从交换机/路由器等设备中分离出来,以便通过软件编程实现硬件对数据转发规则的控制,最终达到对流量进行自由操控的目的。SDN的核心思想是使网络软件化并充分开放,从而使得网络能够像软件一样便捷、灵活,以此提高网络创新能力。
软件定义安全(SDS):
SDS是适应SDN复杂网络的安全防护新思想,基本原理是将物理及虚拟的网络安全设备预期接入模式、部署方式和实现功能进行解耦,底层抽象为安全资源池里的资源,顶层统一通过软件编程的方式进行智能化、自动化的业务编排和管理,以完成相应的安全功能,从而实现一种灵活的安全防护。SDS可以分解为软件定义流量、软件定义资源和软件定义威胁模型,三个举措环环相扣,形成一个动态、闭环的工作模型。
*软件定义流量:通过软件编程的方式来实现网络流量的细粒度定义及转发控制管理,通过将目标网络流量转发到安全设备上,实现安全设备的逻辑部署和使用。
*软件定义资源:通过管理中心对安全资源进行统一注册、池化管理、弹性分配,在虚拟计算环境下,管理中心还要支持虚拟安全设备模板的分发和设备的创建。
*软件定义威胁模型:对网络流量、网络行为和安全事件等信息进行自动化的采集、分析和挖掘,实现对未知的威胁甚至是一些高级安全威胁的实时分析和建模,之后自动用建模结果指导流量定义,实现一种动态、闭环的安全防护。
软件定义安全并不代表不再需要一些专门的信息安全硬件,这些仍然是必不可少的,只不过就像软件定义的网络一样,只是将价值和智能化转移到软件当中而己。
SDN和由此基础上发展起来的SDS,其基本思想都是不依赖于硬件设备,通过软件来实现系统的安全性,特别是可控性保障。从本质上说,软件安全关注的是实现软件产品安全性的全面质量保证的方法,而软件定义安全是实现分布式系统安全可控的一种有效方法。二者虽然都属于信息安全工程的范畴,但却是两个不同的发展方向。可以将二者结合起来,实现更高安全等级的系统安全。
7.软件安全防护的基本方法
软件安全防护围绕漏洞消除展开,目前有两种基本方法:
1)采用多种检测、分析及挖掘技术对安全错误或是安全漏洞进行发现、分析与评价,然后采取多种安全控制措施进行错误修复和风险控制,如传统的打补丁、防病毒、防火墙、入侵检测和应急响应等。
这种将安全保障措施置于软件发布运行之时是当前普遍采用的方法。历史经验证明,该方法在时间和经济上投入人产出比低,信息系统的安全状况很难得到有效改善。本章前面对于当前软件安全问题的现状分析表明了这点。
2)分析软件安全错误发生的原因,将安全错误的修正嵌入到软件开发生命周期的整个阶段。通过对需求分析、设计、实现、测试、发布及运维等各阶段相关的软件安全错误的分析与控制,以期大大减少软件产品的漏洞数量,使软件产品的安全性得到有效提高。
该方法是将安全保障的实施开始于软件发布之前,尤其强调从软件生命周期的早期阶段开始安全考虑,从而减少软件生命周期的后期系统运行过程中安全运维的工作量,提高安全保障效果。实践经验表明,从系统开发需求阶段就引入安全要素要比在系统维护阶段才考虑安全问题所花费的错误修复成本要低很多。
8.软件安全防护的主要技术
- 软件安全属性的认知
- 系统安全工程
- 软件安全开发
9.软件安全开发关注了什么
①软件安全需求分析
②软件安全设计
③软件安全编码
④软件安全测试
⑤软件安全部署
第二章
- 软件漏洞
①什么是软件漏洞?
软件漏洞通常被认为是软件生命周期中与安全相关的设计错误、编码缺陷及运行故障等。
②软件漏洞的成因?
- 计算机系统结构决定了漏洞的必然性
- 软件趋向大型化,第三方扩展增多
- 新技术、新应用产生之初即缺乏安全性考虑
- 软件使用场景更具威胁
- 对软件安全开发重视不够,软件开发者缺乏安全知识
③软件漏洞的特点?
(1)持久性与时效性
一个软件系统从发布之日起,随着用户广泛且深入地使用,软件系统中存在的漏洞会不断暴露出来,这些被发现的漏洞也会不断地被软件开发商发布的补丁软件修补,或在以后发布的新版软件中得以纠正。而在新版软件纠正旧版本中的漏洞的同时,也会引入一些新的漏洞和问题。软件开发商和软件使用者的疏忽或错误(如对软件系统不安全的配置或者没有及时更新安全补丁等),也会导致软件漏洞长期存在。随着时间的推移,旧的漏洞会不断消失,新的漏洞会不断出现,因此漏洞具有持久性。相关数据表明高危漏洞及其变种会可预见地重复出现,对内部和外部网络构成持续的威胁。
漏洞具有时效性,超过一定的时间限制(例如,当针对该漏洞的修补措施出现时,或者软件开发商推出了更新版本系统时),漏洞的威胁就会逐渐减少直至消失。漏洞的时效性具有双刃剑的作用,一方面,漏洞信息的公开加速了软件开发商的安全补丁的更新进程,能够尽快警示软件用户,减少了恶意程序的危害程度;另一方面,攻击者也可能会尽快利用漏洞信息实施攻击行为。
(2)广泛性与具体性
漏洞具有广泛性,会影响到很大范围的软件和硬件设备,包括操作系统本身及系统服务软件、网络客户和服务器软件、网络路由器和防火墙等。理论上讲,所有信息系统或设备中都会存在设计、实现或者配置上的漏洞。
漏洞又具有具体性,即它总是存在于具体的环境或条件中。对组成信息系统的软硬件设备而言,在这些不同的软硬件设备中都可能存在不同的安全漏洞,甚至在不同种类的软硬件设备中,同种设备的不同版本之间,由不同设备构成的信息系统之间,以及同种软件系统在不同的配置条件下,都会存在各自不同的安全漏洞。
(3)可利用性与隐蔽性
漏洞具有可利用性,漏洞一旦被攻击者利用就会给信息系统带来威胁和损失。当然,软件厂商也可以通过各种技术手段来降低漏洞的可利用性,例如微软公司通过在Windows 操作系统或应用软件中增加内存保护机制(如 DEP、ASLR和 SafeSEH等),极大地降低了缓冲区溢出等漏洞的可利用性,本书将在第3章介绍这些保护机制。
漏洞具有隐蔽性,往往需要通过特殊的漏洞分析手段才能发现。尽管随着程序分析技术的进步,已有工具可以对程序源代码进行静态分析和检查,以发现其中的代码缺陷(如strcpy等危险函数的使用),但是对于不具备明确特征的漏洞而言,需要组合使用静态分析和动态分析工具、人工分析等方法去发现。本书的后面部分会着重讲述这些漏洞分析技术。
④软件漏洞的分类?
- 国外漏洞分类研究
(1)从对操作系统研究的角度提出的漏洞分类方法
操作系统安全性分析研究项目RISOS将漏洞分为7类。
·不完整的参数合法性验证:参数使用前没有进行正确检查。
·不一致参数合法性验证:使用不一致的数据格式进行数据有效性检查。
·固有的机密数据共享:不能正确地隔离进程和用户。
·异步验证错误或不适当的序列:竞争条件错误。
·不适当的鉴别、认证和授权:不正确地认证用户。
·可违反的限制:处理边界条件错误。
·可利用的逻辑错误:不属于上述6类的其他错误。
(2)从软件错误角度的漏洞分类方法
T.Aslam等人将漏洞分为编码错误和意外错误等。由于该分类方法存在二义性和非穷举性,I.V.Krsul对该方法进行了扩展及修改,形成了完整的分类方法,将漏洞类型分为操作错误、编码错误、环境错误及其他错误四大类。
(3)多维度分类方法
M. Bishop等人根据时间、漏洞成因、利用方式、漏洞利用组件数、代码缺陷和作用域6个维度分别进行了分类。
(4)广义漏洞分类方法
E.Knight 将网络漏洞分为策略疏忽、社会工程、技术缺陷和逻辑错误。
(5)抽象分类方法
(1)基于漏洞成因的分类
基于漏洞成因的分类包括:内存破坏类、逻辑错误类、输人验证类、设计错误类和配置错误类。
1)内存破坏类。此类漏洞的共同特征是由于某种形式的非预期的内存越界访问(读、写或兼而有之),可控程度较好的情况下可执行攻击者指定的任意指令,其他的大多数情况下会导致拒绝服务或信息泄露。对内存破坏类漏洞再按来源细分,可以分出如下子类型:栈缓冲区溢出、堆缓冲区溢出、静态数据区溢出、格式串问题、越界内存访问、释放后重用和二次释放。
2)逻辑错误类。涉及安全检查的实现逻辑上存在的问题,导致设计的安全机制被绕过。
3)输入验证类。漏洞来源都是由于对来自用户输人没有做充分的检查过滤就用于后续操作,威胁较大的有以下几类:SQL注入、跨站脚本执行、远程或本地文件包含、命令注入和目录遍历。
4)设计错误类。系统设计上对安全机制的考虑不足导致在设计阶段就已经引入安全漏洞。
5)配置错误类。系统运行维护过程中以不正确的设置参数进行安装,或被安装在不正确的位置。
(2)基于漏洞利用位置的分类
1)本地漏洞。即需要操作系统级的有效账号登录到本地才能利用的漏洞,主要构成为权限提升类漏洞,即把自身的执行权限从普通用户级别提升到管理员级别。
2)远程漏洞。即无需系统级的账号验证即可通过网络访问目标进行利用的漏洞。
3)基于威胁类型的分类
1)获取控制。即可以导致劫持程序执行流程,转向执行攻击者指定的任意指令或命令,控制应用系统或操作系统。这种漏洞威胁最大,同时影响系统的机密性、完整性,甚至在需要的时候可以影响可用性。主要来源为内存破坏类。
2)获取信息。即可以导致劫持程序访问预期外的资源并泄露给攻击者,影响系统的机密性。主要来源为输入验证类和配置错误类漏洞。
3)拒绝服务。即可以导致目标应用或系统暂时或永远性地失去响应正常服务的能力,影响系统的可用性。主要来源为内存破坏类和意外处理错误类漏洞。
⑤软件漏洞的分级?
- 按照漏洞严重等级进行分级
- 利用通用漏洞评分系统(CVSS)进行分级
第三章
- 程序运行时的结构
在Win32环境下,由高级语言编写的程序经过编译、链接,最终生成可执行文件,即PE 文件。在运行PE文件时,操作系统会自动加载该文件到内存,并为其映射出4GB的虚拟存储空间,然后继续运行,这就形成了所谓的进程空间。
Win32系统中,进程使用的内存按功能可以分为4个区域,如图3-1所示。
1)代码区:存放程序汇编后的机器代码和只读数据,这个段在内存中一般被标记为只读,任何企图修改这个段中数据的指令都将引发一个 Segmentation Violation错误。当计算机运行程序时,会到这个区域读取指令并执行。
2)数据区:用于存储全局变量和静态变量。
3)堆区:该区域内存由进程利用相关函数或运算符动态申请,用完后释放并归还给堆区。例如,C语言中用malloc/free函数、C++语言中用new/delete运算符申请的空间就在堆区。
4)栈区:该区域内存由系统自动分配,用于动态存储函数之间的调用关系。在函数调用时存储函数的入口参数(即形参)、返回地址和局部变量等信息,以保证被调用函数在返回时能恢复到主调函数中继续执行。
2.堆和栈的概念
堆区:该区域内存由进程利用相关函数或运算符动态申请,用完后释放并归还给堆区。例如,C语言中用malloc/free函数、C++语言中用new/delete运算符申请的空间就在堆区。
栈区:该区域内存由系统自动分配,用于动态存储函数之间的调用关系。在函数调用时存储函数的入口参数(即形参)、返回地址和局部变量等信息,以保证被调用函数在返回时能恢复到主调函数中继续执行。
3.缓冲区
程序中所使用的缓冲区既可以是堆区和栈区,也可以是存放静态变量的数据区。由于进程中各个区域都有自己的用途,根据缓冲区利用的方法和缓冲区在内存中的所属区域,其可分为栈溢出和堆溢出。
缓冲区溢出漏洞就是在向缓冲区写人数据时,由于没有做边界检查,导致写入缓冲区的数据超过预先分配的边界,从而使溢出数据覆盖在合法数据上而引起系统异常的一种现象。
目前,缓冲区溢出漏洞普遍存在于各种操作系统(Windows、Linux、Solaris、Free BSD ,HP-UX 及 IBM AIX),以及运行在操作系统上的各类应用程序中。著名的Morris蠕虫病毒,就是利用了VAX机上 BSD UNIX 的 finger程序的缓冲区溢出错误。
4.栈溢出、栈溢出漏洞及利用分析
栈溢出漏洞基本原理
在函数的栈帧中,局部变量是顺序排列的,局部变量下面紧跟着的是前栈帧EBP及函数返回地址RET。如果这些局部变量为数组,由于存在越界的漏洞,那么越界的数组元素将会覆盖相邻的局部变量,甚至覆盖前栈帧EBP及函数返回地址 RET,从而造成程序的异常。
5.栈溢出攻击
栈溢出攻击是一种利用栈溢出漏洞所进行的攻击行动,目的在于扰乱具有某些特权运行的程序的功能,使得攻击者取得程序的控制权,如果该程序具有足够的权限,那么整个主机就被控制了。
6.格式化字符串漏洞及利用分析
1.格式化串漏洞
格式化串漏洞的产生源于数据输出函数中对输出格式解析的缺陷,其根源也是C语言中不对数组边界进行检查的缓冲区错误。
2.格式化串漏洞利用
格式化串漏洞的利用可以通过以下方法实现。
1)通过改变格式化串中输出参数的个数实现修改指定地址的值:可以修改填充字符串长度实现;也可以通过改变输出的宽度实现,如%8d。
2)通过改变格式化串中格式符的个数,调整格式符对应参数在栈中的位置,从而实现对栈中特定位置数据的修改。如果恰当地修改栈中函数的返回地址,那么就有可能实现程序执行流程的控制。也可以修改其他函数指针,改变执行流程。相对于修改返回地址,改写指向异常处理程序的指针,然后引起异常,这种方法猜测地址的难度比较小,成功率较高。
7.Windows安全漏洞保护分析
- 栈溢出检测选项/GS
①/GS保护机制
②对抗/GS保护
- 数据执行保护DEP
①数据执行保护DEP机制
②对抗数据执行保护DEP
8.地址空间布局随机化ASLR
ASLR保护机制。其原理很简单:通过对堆、栈和共享库映射等线性区域布局的随机化,增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止漏洞利用的目的。例如,同一版本的Windows XP上系统里DLL模块的加载地址是固定的,那么攻击者只需针对不同操作系统版本进行分别处理即可,但是使用ASLR之后,攻击者必须在攻击代码中进行额外的地址定位操作,才有可能成功利用漏洞,这在一定程度上确保了系统安全。
ASLR保护机制进行随机化的对象主要包括以下几个方面。
- 映像随机化:改变可执行文件和 DLL文件的加载地址。
- 栈随机化:改变每个线程栈的起始地址。
- 堆随机化:改变已分配堆的基地址。
9.安全结构化异常处理SafeSEH
1. SafeSEH 机制
为了防止SEH机制被攻击者恶意利用,微软通过在.Net编译器中加入/SafeSEH 连接选项,从而正式引入了SafeSEH技术。
SafeSEH的实现原理较为简单,就是编译器在链接生成二进制IMAGE 时,把所有合法的异常处理函数的地址解析出来制成一张安全的SEH表,保存在程序的IMACE 数据块里面,当程序调用异常处理函数时会将函数地址与安全SEH表中的地址进行匹配,检查调用的异常处理函数是否位于该表中。如果 IMAGE不支持SafeSEH,则表的地址为0。
安全结构化异常处理((Safe Structured Exception Handling,SafeSEH)保护机制的作用是防止覆盖和使用存储栈上的SEH结构。如果使用/SafeSEH链接器选项编译和链接一个程序,那么对应二进制的头部将包含一个由所有合法异常处理程序组成的表,当调用异常处理程序时会检查这张表,以确保所需的处理程序在这张表中。这项检查工作是作为ntdll. dll 中的RtlDispatchException例程的一部分来完成的,它会执行以下测试。
·确保异常记录位于当前线程的栈上。
·确保处理程序的指针没有指回栈。
·确保处理程序已经在经授权处理程序列表中登记。·确保处理程序位于可执行的内存映像中。
由此可以看出,SafeSEH 保护机制对于保护异常处理程序而言相当有效,但稍后将看到,它也并非绝对安全。
2.对抗 SafeSEH 机制的方法
SafeSEH是一种非常有效的漏洞利用防护机制,如果一个进程加载的所有模块都支持SafeSEH的 IMAGE,覆盖SafeSEH进行漏洞利用就基本不可能。Windows 7下绝大部分的系统库都支持SafeSEH 的IMAGE,但 Windows XP/2003等绝大部分系统库不支持Windows的IMAGE。当进程中存在一个不支持SafeSEH的 IMACE时,整个SafeSEH 的机制就很有可能失效。此外,由于支持SafeSEH需要.Net的编译器支持,现在仍有大量的第三方程序和库未使用.Net编译或者未采用/ safeSEH链接选项,这就使得绕过SafeSEH 成为可能。
(1)利用未启用SafeSEH的模块作为跳板进行绕过
对于目前的大部分Windows操作系统,其系统模块都受SafeSEH 保护,可以选用未开启SafeSEH 保护的模块来利用,比如漏洞软件本身自带的dll文件。在这些模块中寻找特定的某些跳转指令如 pop/POP/ret等,用其地址进行SEH函数指针的覆盖,使得 SEH函数被重定位到这些跳转指令,由于这些指令位于加载模块的IMAGE空间内,且所在模块不支持SHE,因此异常被触发时,可以执行到这些指令,通过合理安排shellcode,那么就有可能绕过SafeSEH 机制,执行shellcode 中的功能代码。
(2)利用加载模块之外的地址进行绕过
利用加载模块之外的地址进行绕过,包括从堆中进行绕过和从其他一些特定内存绕过。从堆中绕过,源于这样的缺陷:如果SEH中的异常处理函数指针指向堆区,则通常可以执行该异常处理函数,因此只需将shellcode布置到堆区就可以直接跳转执行。此外,如果在进程内存空间中的一些特定的、不属于加载模块的内存中找到跳转指令,则仍然可以用这些跳转指令的地址来覆盖异常处理函数的指针,从而绕过SafeSEH。
第四章
1.了解web基本架构
一次Web访问过程分析:在这整个过程中,大致可以分为以下几个阶段:DNS域名解析、TCP连接、HTTP请求、处理请求返回HTTP响应、页面渲染和关闭连接。
2.Web漏洞概述
什么是web漏洞
Web应用安全漏洞是Web应用程序在需求、设计、实现、配置、维护和使用等过程中,有意或无意产生的缺陷,这些缺陷一旦被攻击者所利用,就会造成对网站或用户的安全损害,从而影响构建于Web应用之上正常服务的运行,危害网站或用户的安全属性。
Web安全十大漏洞
3.SQL 注入漏洞
原理:SQL注入漏洞是指,攻击者能够利用现有Web应用程序,将恶意的数据插入SQL查询中,提交到后台数据库引擎执行非授权操作。
SQL注入漏洞的主要危害如下。
·非法查询、修改或删除数据库资源。
·执行系统命令。
·获取承载主机操作系统和网络的访问权限。
利用方法:
1)注入点选择
在SQL注人攻击之前,首先要找到网站中各类与数据库形成交互的输入点。通常情况下,一个网站的输入点包括以下几项。
·表单提交,主要是POST请求,也包括GET请求。
·URL参数提交,主要是 GET请求参数。
·Cookie参数提交。
· HTTP请求头部的一些可修改的值,如 Referer、User_Agent等。·一些边缘的输入点,如.mp3文件的一些文件信息等。
上面列举的几类输入点,只要任何一点存在过滤不严、过滤缺陷等问题,都有可能发生SQL注入攻击。
(2)数字型和字符型注入
按照注人的数据类型,可将SQL注入攻击分为数字型注入和字符型注入。
- 数字型注人。当输人的参数为整数时,即为数字型注入,如ID、年龄等。数字型注入是—种最简单的注入方式。
- 字符型注入。当输人的参数为字符串时,即为字符型注入,如姓名、密码等。字符型注入和数字型注入的区别在于:字符型注入需要闭合单引号,而数字型注入不需要。
- 通过Web端对数据库注入和直接访问数据库注入
按照注人的物理途径,可将SQL注人攻击分为通过Web端对数据库注入和直接访问数据库注入。
4.XSS跨站脚本漏洞
(1)反射型XSS漏洞原理:
反射型XSS是XSS中最为普遍的一种类型。如果服务器直接使用客户端提供的数据,而没有对数据进行无害化处理,就会出现此漏洞。这些数据包括URL中的数据、HTTP请求(CET报文)及HTML表单中提交的数据。反射型XSS的特点是,用户单击时触发,而且只执行一次,因此反射型XSS也称为非持久型XSS。
反射型XSS通常是由攻击者诱使用户向有漏洞的Web应用程序提供危险内容,然后危险内容会反射给用户并由浏览器执行。一个典型的反射型XSS攻击过程如图4-20所示,描述如下。
1)攻击者发现某网站有反射型XSS 漏洞,然后精心构造包含恶意脚本的URL,通过E-mail 等途径发送给受害者,并引诱其单击这个URL。
2)受害者单击该URL,用户浏览器向服务器发送包含恶意脚本的请求。
3)服务器将恶意脚本嵌入到响应(通常为HTML页面)中返回给受害者,此时响应中的恶意脚本对于用户的浏览器而言是动态的可执行脚本(反射的攻击脚本)。
4)受害者浏览器收到响应后,其中的恶意脚本被解析和执行,攻击发生,如将受害者的会话Cookie发送给攻击者指定的地址。
(2)存储型XSS漏洞原理:
存储型XSS也称为持久型XSS,它的危害更大。此类XSS不需要用户单击特定的URL就能执行跨站脚本。攻击者事先将恶意脚本代码上传或者存储到存在漏洞的服务器端数据库中,只要用户浏览包含此恶意脚本的网页便会触发,遭受攻击。
1)攻击者发现某个网站存在存储型XSS漏洞,于是将恶意脚本(存储的攻击脚本)插入到数据库中。
2)用户浏览器发送完全无害的访问请求,试图访问此站点上的信息。
3)服务器端将包含恶意脚本的内容嵌入到响应(通常为HTML页面)中发回给用户。4)用户浏览器收到响应后,其中的恶意脚本被解析和执行,攻击发生。
存储型XSS漏洞通常在留言板、个人资料等位置出现,并常被用于编写危害性更大的XSS蠕虫。
第五章
1.软件生命周期
概括地说,软件生命周期由定义、开发和维护3个时期组成,每个时期又可进一步划分成若干个阶段。
2.软件安全开发模型
1)微软的软件安全开发生命周期模型SDL,以及相关的敏捷SDL和ISO/IEC 27034标准。
2) McGraw的内建安全模型BSI,以及BSI 成熟度模型BSIMM。
3)美国国家标准与技术研究院(NIST)的安全开发生命周期模型。
4) OWASP提出的综合的轻量级应用安全过程CLASP,以及软件保障成熟度模型SAMM。
以上各类模型的核心思想是,为了开发出尽可能安全的软件,把安全活动分散到软件生命周期的各个阶段中去。
安全开发生命周期SDL:
第1阶段:安全培训
在软件开发的初始阶段,针对开发团队和高层进行安全意识和能力培训,使之了解安全基础知识及安全方面的最新趋势,同时能针对新的安全问题与形势持续提升团队的能力。
第2阶段:安全需求分析
- 确定安全需求。在安全需求分析阶段,确定软件安全需要遵循的安全标准和相关要求,建立安全和隐私要求的最低可接受级别。
- 创建质量门/缺陷(Bug)等级。质量门和缺陷等级用于确立安全和隐私质量的最低可接受级别。
- 安全和隐私风险评估。安全风险评估(SRA)和隐私风险评估(PRA)是必需的过程,用于确定软件中需要深入评析的功能环节。
第3阶段:安全设计
在安全设计阶段,从安全性的角度定义软件的总体结构。通过分析攻击面,设计相应的功能和策略,降低并减少不必要的安全风险,同时通过威胁建模,分析软件或系统的安全威胁,提出缓解措施。
第4阶段:安全实施
在安全实施阶段,按照设计要求,对软件进行编码和集成,实现相应的安全功能、策略及缓解措施。在该阶段通过安全编码和禁用不安全的API,可以减少实现时导致的安全问题和由编码引入的安全漏洞,并通过代码静态分析等措施来确保安全编码规范的实施。
第5阶段:安全验证
在安全验证阶段,通过动态分析和安全测试手段,检测软件的安全漏洞,全面核查攻击面,检查各个关键因素上的威胁缓解措施是否得以正确实现。
第6阶段:安全发布
在安全发布阶段,建立可持续的安全维护响应计划,对软件进行最终安全核查。本阶段应将所有相关信息和数据存档,以便对软件进行发布与维护。这些信息和数据包括所有规范、源代码、二进制文件、专用符号、威胁模型、文档和应急响应计划等。即使在发布时不包含任何已知漏洞的程序,也可能面临日后新出现的威胁。
第7阶段:安全响应
在安全响应阶段,响应安全事件与漏洞报告,实施漏洞修复和应急响应。同时发现新的问题与安全问题模式,并将它们用于SDL的持续改进过程中。
第六章
- 软件安全需求分析与软件需求分析的区别:
(1)软件安全需求的客观性
软件安全需求由系统的客观属性决定。安全需求与一般需求的一个主要不同之处在于:安全需求并不是从使用者的要求和兴趣出发,而是由系统的客观属性所决定的。因此,需求分析员将承担更多软件需求的分析工作。
在软件需求分析过程中,分析员和用户都起着关键的、必不可少的作用。因为,只有用户才真正知道自己需要什么,而他们又需要开发人员来帮助实现自己的需求,所以用户必须把他们对软件的需求尽量准确、具体地描述出来;分析员知道怎样用软件去实现人们的需求,但是在需求分析开始时他们对用户的需求并不十分清楚,必须通过与用户沟通来获取用户对软件的需求。因此,软件需求分析过程中,用户与分析员之间需要密切沟通,而且,为了避免在双方交流信息的过程中出现误解或遗漏,还必须严格审查验证需求分析的结果。
在软件安全需求分析过程中,用户对于软件即将面临的使用对象和使用环境的考虑通常不会包括那些恶意用户和不可控环境,因此,他们对于安全威胁的了解往往不全面,也很难从专业角度提出安全需求。这时,需求分析员就需要承担软件安全需求分析的主要工作。
(2)软件安全需求的系统性
软件安全需求分析不能只从软件本身出发,必须从系统角度进行分析。这是因为,虽然软件(包括操作系统、数据库等)本身可能会由于逻辑、数据和时序等设计缺陷导致安全问题,但同时,由于软件属于逻辑产品,很多情况下并不是软件失效,而是在软件正常工作时,在某种特殊条件下软硬件相互作用,以及由于人的使用问题而导致不安全情况发生。因此,软件安全需求分析必须在系统安全性分析的基础上进行。
通常情况下,凡是与软件相关的接口、硬件状态、硬件故障和系统时序、人员操作、使用环境,包括软件自身的逻辑和物理模型,以及处理的静态动态数据,均属于软件安全性需求分析的范畴。分析的重点为软件功能设计缺陷,以及软件使用过程中软件、硬件和操作人员的相互作用。
此外,软件开发的每一个阶段都需要持续地对安全需求进行充分的定义和管理,这些安全需求应该作为与软件功能、质量和可用性同等重要的需求来处理,并且对那些残余风险需要遵从相关约束的安全需求也应该明确定义。
从系统角度分析软件的安全性需求,这就不可避免地会涉及各种不同领域的专业知识与经验积累。因此,分析时应以人为主,任何软件分析工具只能起辅助作用。这就对软件安全性分析人员提出了较高的要求。分析时要求有专门知识的软件安全性分析人员、熟悉系统结构的系统总体设计人员、软件设计人员和领域专家共同参加,共同工作。
(3)软件安全需求的经济性和适用性
软件安全的需求内容非常丰富,并不是所有的应用安全需求控制都要采纳和实施。组织应当根据具体业务的重要性,对安全措施进行成本控制。安全控制的成本应该与软件所有者或者管理部门要求的目标水平相当。
信息安全等级保护制度是我国信息安全保障体系建设的一项基本制度,对不同等级的信息系统提出相应的安全要求,要求不同等级的信息系统具备相应的基本安全保护能力。不同安全等级的信息应能对抗不同强度和时间长度的安全威胁,即使对于相同等级的信息系统,由于承载的业务不同,其所面临的威胁也不同。因而需要使用不同的保护策略。由此可见,通过对威胁的识别和分析进而建模威胁,是信息系统进行等级保护的基本前提。
软件安全需求分析的目的和作用
(1)软件安全需求分析的目的
软件安全需求分析的目的是描述为了实现信息安全目标,软件系统应该做什么,才能有效地提高软件产品的安全质量,减少进而消减软件安全漏洞。
(2)软件安全需求分析的重要作用
以往软件在开发时只强调业务功能需求,没有考虑安全需求,导致所开发的应用系统存在大量的漏洞。尽管周边安全技术如防火墙、入侵检测系统、防病毒及平台安全可以用来实现系统安全,但由于安全只是在产品环境下被测试和构建,其效果并不理想。
一个缺少安全需求分析的软件开发项目,将威胁到信息的保密性、完整性和可用性,以及其他一些重要安全属性。这个软件产品被攻破可能就只是一个时间早晚的问题,而不是条件的问题,这取决于攻击者对于这个软件系统价值的判断。
2.软件安全需求的来源
软件运行的情境通常可以分为外部情境和内部情境,因此安全需求可以从外部需求和内部需求两个方面来分类。
1.外部安全需求
外部安全需求通常主要指法律、法规等遵从性需求,包括相应国家和地区关于安全技术与管理的法规、标准及要求等。这些安全技术和管理的合规性要求往往是已有安全威胁的经验性对策的总结,因而遵循这些要求不仅是法规制度上的要求,也是软件安全性保障的要求。
2.内部安全需求
内部安全需求通常包括两个部分,一是组织内部需要遵守的政策、标准、指南和实践模式,二是与软件业务功能相关的安全需求。
在需求分析过程中,不论是外部安全需求还是内部安全需求,都应当给予同等重视。
等级保护:
(1)等级保护要求
对信息安全分级保护是客观需求。信息系统的建立是为社会发展、社会生活的需要而设计、建立的,是社会构成、行政组织体系及其业务体系的反映,这种体系是分层次和分级别的。因此,信息安全保护必须符合客观存在。
等级化保护是信息安全发展规律。按组织业务应用区域,分层、分类、分级进行保护和管理,分阶段推进等级保护制度建设,这是做好国家信息安全保护必须遵循的客观规律。
等级保护是国家法律和政策要求。为了提高我国信息安全的保障能力和防护水平,维护国家安全、公共利益和社会稳定,保障和促进信息化建设的健康发展,1994年国务院颁布的《中华人民共和国计算机信息系统安全保护条例》规定:“计算机信息系统实行安全等级保护,安全等级的划分标准和安全等级保护的具体方法,由公安部会同有关部门制定”。
2017年6月1日起实施的《中华人民共和国网络安全法》(以下简称《网络安全法》)第21条明确规定:“国家实行网络安全等级保护制度,要求网络运营者应当按照网络安全等级保护制度要求,履行安全保护义务”;第31条规定“对于国家关键信息基础设施,在网络安全等级保护制度的基础上,实行重点保护”。
为了与网络安全法提出的“网络安全等级保护制度”保持一致性,等级保护的名称由原来的“信息系统安全等级保护”修改为“网络安全等级保护”。
《网络安全法》规定国家实行网络安全等级保护制度,标志着从1994年国务院颁布的《中华人民共和国计算机信息系统安全保护条例》上升到国家法律;标志着国家实施十余年的信息安全等级保护制度进入2.0阶段;标志着以保护国家关键信息基础设施安全为重点的网络安全等级保护制度依法全面实施。
(2)等级保护2.0
随着等级保护制度从部门规章上升为国家法律,等级保护的重要性不断增加,等级保护对象也在扩展,等级保护的体系也在不断升级。等级保护2.0时代网络安全等级保护的核心内容包括以下几个方面。
·将风险评估、安全监测、通报预警、案事件调查、数据防护、灾难备份、应急处理、自主可控、供应链安全、效果评价、综合考核等措施全部纳入等级保护制度并实施。将网络基础设施、信息系统、网站、数据资源、云计算、物联网、移动互联网、工控系统、公众服务平台、智能设备等全部纳入等级保护和安全监管。
·将互联网企业的网络、系统、大数据等纳入等级保护管理,保护互联网企业的健康发展。(3)等级保护的基本概念
1)网络安全等级保护是指:
·对网络(含信息系统、数据,下同)实施分等级保护、分级监管。●对网络中使用的网络安全产品实行按等级管理。
·对网络中发生的安全事件分等级响应、处置。
这里的“网络”是指,由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息进行收集、存储、传输、交换、处理的系统,包括网络设施、信息系统、数据资源等。
- 网络安全等级保护制度将网络划分为如下五个安全保护等级,从第一级到第五级逐级增高。
第一级,属于一般网络,其一旦受到破坏,会对公民、法人和其他组织的合法权益造成损害,但不危害国家安全、社会秩序和社会公共利益。
第二级,属于一般网络,其一旦受到破坏,会对公民、法人和其他组织的合法权益造成严重损害,或者对社会秩序和社会公共利益造成危害,但不危害国家安全。
第三级,属于重要网络,其一旦受到破坏,会对公民、法人和其他组织的合法权益造成特别严重损害,或者会对社会秩序和社会公共利益造成严重危害,或者对国家安全造成危害。
第四级,属于特别重要网络,其一旦受到破坏,会对社会秩序和社会公共利益造成特别严重危害,或者对国家安全造成严重危害。
第五级,属于极其重要网络,其一旦受到破坏,会对国家安全造成特别严重危害。3)开展网络安全等级保护工作的流程。
根据《信息安全等级保护管理办法》(公通字[2007] 43号)的规定,等级保护工作主要分为以下五个环节。
·一是定级。网络运营者根据《信息安全技术网络安全等级保护定级指南》(GA/T1389—2017)拟定网络的安全保护等级,组织召开专家评审会,对初步定级结果的合理性进行评审,出具专家评审意见,将初步定级结果上报行业主管部门进行审核。
·二是备案。网络运营者将网络定级材料向公安机关备案,公安机关对定级准确、符合要求的网络发放备案证明。
·三是等级测评。网络运营者选择符合国家规定条件的测评机构,对第三级以上网络(含国家关键信息基础设施)每年开展等级测评,查找发现问题隐患,提出整改意见。
·四是安全建设整改。网络运营者根据网络的安全保护等级,按照国家标准开展安全建设整改。
·五是监督检查。公安机关每年对网络运营者开展网络安全等级保护工作的情况和网络的安全状况实施执法检查。
网络安全等级保护是对网络进行分等级保护、分等级监管,是将信息网络、信息系统、网络上的数据和信息,按照重要性和遭受损坏后的危害性分成五个安全保护等级(从第一级到第五级,逐级增高);等级确定后,第二级(含)以上网络到公安机关备案,公安机关对备案材料和定级准确性进行审核,审核合格后颁发备案证明;备案单位根据网络的安全等级,按照国家标准开展安全建设整改,建设安全设施、落实安全措施、落实安全责任、建立和落实安全管理制度;选择符合国家要求的测评机构开展等级测评;公安机关对第二级网络进行指导,对第三、第四级网络定期开展监督、检查。
(4)等级保护政策体系
为组织开展网络安全等级保护工作,国家相关部委(主要是公安部牵头组织,会同国家保密局、国家密码管理局、原国务院信息办和发改委等部门)相继出台了一系列文件,对具体工作提供了指导意见和规范,这些文件构成了网络安全等级保护政策体系,如图6-1所示。
(5)等级保护标准体系
为推动我国网络安全等级保护工作,全国信息安全标准化技术委员会和公安部信息系统安全标准化技术委员会组织制定了信息安全等级保护工作需要的一系列标准,为开展等级保护工作提供了标准保障。对于涉密信息系统的分级保护,另有保密部门颁布的保密标准。
(6)网络等级保护与信息安全管理体系的联系和区别
信息安全管理体系是站在管理的角度上对信息进行管理,而等级保护则是管理体系中的一部分,是基础性的工作,两者在管理目标上具有一致性,而且还有相辅相成的作用。
- 信息安全管理体系和等级保护的工作重点不同。信息安全管理体系是站在管理的角度上对信息进行保护的,而等级保护则是站在技术及管理两个方面来开展工作的,两者所处的角度不同,看待问题及关注的焦点自然也不同。信息安全管理体系关注的焦点在于构建高效的信息安全管理制度和组织,并将其切实地落实到实际管理中,其注重的是管理的意义,而等级保护的主要思想是分类、分级保护,其关注点在于怎样通过对现有资源进行有效利用,从而将安全管理工作落实到位。所以说,信息安全管理体系和等级管理在关注点这一方面存在差异。
- 信息安全管理体系和等级保护所依据的标准不同。在信息安全管理体系实施的过程中,需要依据的是GB/T22081—2016等标准,在此实施规则中对管理的措施等进行了阐述,并且还为体系确定管理目标而提出了具体的依据。等级保护是信息安全管理体系中的一部分,而且其主要作用就是为了检查信息系统有没有达到规定的安全等级要求,而因为每个地区的信息安全管理要求及实际情况不同,所以每个地区可以根据自身实际情况来确定测评规范。这样的情况就使得信息安全管理体系和等级保护两者在落实过程中所参照的标准不同。
3)信息安全管理体系和等级保护的实施对象不同。信息安全管理体系建立的主要目的是为各企业提供信息保障服务,所以其针对的主要群体是企业,而等级保护的主要目的是对信息安全管理体系进行测评,所以其针对的主要对象是需要使用信息安全管理体系的政府部门。政府部门中有很多信息都需要确保安全性,就需要相应的信息安全管理体系。为了确保体系是科学、合理的,就需要等级保护来对其进行测评,这样一方面可以提高信息化的程度,另一方面还可以让政府内部工作人员认识到信息保护的重要性,从而培养他们的等级保护意识。
为推动我国网络安全等级保护工作,全国信息安全标准化技术委员会和公安部信息系统安全标准化技术委员会组织制定了信息安全等级保护工作需要的一系列标准,为开展等级保护工作提供了标准保障。对于涉密信息系统的分级保护,另有保密部门颁布的保密标准。
3.软件安全需求的获取
位置、相关方:
软件安全需求获取的相关方包括业务负责人、最终用户、客户、安全需求分析人员和安全技术支持等。
业务负责人、最终用户和客户在安全需求确定时应发挥重要作用,他们应当积极参与安全需求的采集和分析过程。业务负责人是业务风险的最终责任人,负责确定可接受的风险阈值,明确哪些残余风险是可以接受的,因此他们应该了解软件的安全漏洞,协助安全需求分析人员和软件开发团队考虑风险的优先顺序,权衡决定哪些风险是重要的。
由于业务负责人、客户和最终用户对安全威胁和相关安全技术的了解和掌握不是很专业,他们还应当加强信息安全方面的培训和教育,提升安全意识,增长安全知识,确保能够充分了解软件将来应用的外部和内部环境威胁,对于安全需求的优先级确定提供帮助。
就像一个业务分析师需要将业务需求转换为软件功能说明一样,安全需求分析人员要负责软件安全需求的收集和分析,并帮助软件开发团队将安全需求转化为功能说明。
此外,运维小组和信息安全小组等安全技术支持也是软件安全需求获取相关方,安全需求分析人员、业务负责人、最终用户及客户应当积极与之保持联系和沟通,寻求他们的支持和帮助。
为了保证安全需求获取活动有效地开展,相关方面的人员必须进行充分的沟通与合作,特别是当相关方是非技术/业务人员的情况下。
由于每个人对于安全需求的重要性认识不同,软件安全需求获取活动将是一项具有挑战性的工作。
方法:调查可以直接用于生成安全需求。通常通过发送E-mail或在线问卷的方式请被调查者回答一些问题,也可以采用访谈的方式来进行。问卷调查和访谈的有效性取决于如何向被调查对象提出合适的问题。调查的问题应当覆盖软件安全设计原则和安全配置文件的内容,应当考虑业务风险、过程(或项目)风险和技术(或产品)风险。
在调查时,一些常见的安全需求问题如下。
·软件将要处理、传输或存储什么样的数据?数据的敏感程度有多高?
软件处理与个人身份或隐私相关的信息吗?
什么用户将被允许执行变更操作?需要对他们进行审计和监控吗?软件的最大可容忍宕机时间是多长?
软件系统运行中断时,需要在多长时间内恢复正常操作?可容忍的数据损失量是多少?需要单点登录认证吗?
球战·用户的角色是什么?每个角色应该有哪些特权和权限(如创建、读、写、更新或删除)?
·当发生错误时,软件需要处理的错误消息和条件是什么?
觉要如果在调查过程中提出了新问题,可能需要额外的安全需求调查分析工作。
当然,在整个调查过程中,调查人和被调查人之间的协作和沟通是很重要的。
第七章
- 软件设计的主要工作
当软件需求分析阶段完成后,就进入了软件设计阶段。从生命周期的角度,软件设计可以看作是从软件需求规格说明书出发,根据需求分析阶段确定的功能,设计软件系统的整体结构、划分功能模块、确定每个模块的实现算法等内容,形成软件的具体设计方案,即从整体到局部,从总体设计(也称为概要设计)到详细设计的过程。
4.软件安全设计的主要工作
1.软件安全设计的目的和作用
软件安全设计的目的是将安全属性设计到软件架构中,以实现软件产品本质的安全性。软件安全设计对于软件安全有着举足轻重的作用,大多数软件安全问题都是由于软件设计上的安全性考虑不足或不完整所导致的。
2.软件安全设计与软件设计的联系
简单地说,软件安全设计就是将软件的安全需求转化为软件的功能结构的过程。软件设计过程通常包括架构设计、接口设计、构件设计和数据模型设计等工作,这意味着安全设计也不仅要考虑系统架构及相关的安全问题,同时还要考虑如何将安全需求嵌入到软件的功能结构中,与功能结构相融合并且成为一个有机的整体,为高质量地实现软件的业务目标提供安全保障。因此,软件安全设计的主要工作包括软件架构安全性设计、软件架构安全性分析及软件安全功能设计。本节接下来概要介绍软件架构安全性设计和安全性分析,软件安全功能设计将在7.3节中介绍。
3.软件架构安全性设计(1)软件架构设计
为了达到控制软件复杂性、提高软件系统质量、支持软件开发和复用的目的,开发人员提出了软件架构的概念。
软件架构可以分为以下3类。
- 逻辑架构:描述软件系统中组件之间的关系,如用户界面、数据库和外部系统接口等。
2)物理架构:描述软件组件在硬件上的部署方式。
3)系统架构:说明系统的非功能性特征,如可扩展性、可靠性、灵活性和性能等。软件架构设计对于开发高质量软件具有较大作用。一般而言,软件架构的设计首先需要理清业务逻辑的功能要求,了解业务逻辑的变化性要求,包括可维护性和可扩展性,分离出概要业务逻辑层。接着,设计业务逻辑层和系统其他部分的接口与交互关系,按照职责分离原则设计包、类、方法和消息,设计业务逻辑算法。然后,使用自底向上和自顶向下相结合的方式,不断渐进地迭代架构设计。
(2)软件架构安全性设计
软件架构安全设计首先需要进行系统描述,包括系统功能、安全要求、系统部署和技术需求,确定软件系统的安全级别。接着,设计软件网络、数据库等应具备的安全功能,根据软件具体安全需求的不同,设计的安全功能包括加密、完整性验证、数字签名、访问控制及安全管理等。在架构安全设计过程中,还需要解决软件安全功能的易用性、可维护性和独立性问题。
4.软件架构安全性分析
(1)软件架构安全性分析的重要性
在软件架构安全性设计的过程中,尤其是对于大而复杂的系统,要将安全属性一次性设计到软件架构中成为架构的有机组成部分,这是一项非常具有挑战性的工作。
为此,一旦软件架构设计或是软件架构安全性设计完成,在退出设计阶段进入开发阶段之前,需要对软件(安全)架构和设计方案进行检查,以确保设计能够满足软件的安全需求。这不仅包括功能方面的设计检查,也包括安全设计检查。检查可以帮助开发人员在编码之前对安全设计要素进行验证,提供一个识别和处理任何安全漏洞的机会,减少后续阶段重新设计软件的需要。
设计检查需要考虑安全政策和软件部署的目标环境,同时也需要对应用系统进行全局检查。网络和主机水平的安全保护都需要到位,保护措施之间不会相互矛盾从而削弱保护强度。需要特别关注软件安全设计基本原则和软件核心安全属性需求的设计,以确保保密性、完整性和可用性。此外,还需要逐层对软件架构进行分析以保证纵深防御控制措施到位。攻击面评估、威胁建模和滥用案例建模、安全体系结构和设计检查等几个方面都是非常有用的,它们可以确保软件不仅能实现预期的功能,同时也不会违反任何安全策略。
(2)软件架构安全性分析的基本过程
软件架构安全性分析的基本过程如图7-1所示,首先进行架构建模,然后根据软件的安全需求描述或相关标准,对架构模型是否满足要求进行检查,如果不满足则需要修改设计架构,如此反复,直至满足所有安全需求和相关标准。
目前,国内外关于软件架构安全性分析的理论和应用研究还处于探索阶段。软件架构安全性分析可以分为形式化和工程化两类分析方法。
1)形式化分析技术。使用形式化方法描述软件架构和安全需求,最终的分析结果精确、可量化,且自动化程度高,但实用性较差。形式化分析主要包括UMLSec建模描述分析法、软件架构模型法 ( Software Architectural Model ,SAM)、离散时间马尔可夫链 DTMC安全可靠性模型方法和卡耐基梅隆大学提出的ACME组件系统架构描述法等。
2)工程化分析技术。从攻击者的角度考虑软件面临的安全问题,实用性强,但自动化程度较低。软件架构的工程化分析主要包括场景分析法、错误用例分析法和威胁建模。相对而言,威胁建模方法实用程度较高。
根据以上的介绍,本章接下来将介绍软件安全设计中涉及的3个主要内容。
1)软件安全设计原则:这是一套在软件生产过程中关注软件安全性的卓有成效的开发经验总结。
2)软件安全功能设计:考虑如何将安全需求融入软件架构和设计方案中,将它们转化为可实现的功能组件。
3)威胁建模:通过抽象的概念模型对影响软件系统的威胁进行系统的识别和评价。
5.了解软件安全设计原则
Michael Howard总结的13条安全设计原则
Michael Howard根据SD3法则,结合其长期软件设计开发经验,在 Writing Secure Code( 2nd ed)一书中总结出以下13条安全设计原则(有些原则将在后续部分详细介绍)。
1)从错误中吸取教训。要从以前的错误中汲取教训,防止同样的安全错误再次发生。针对软件或其他软件产品中的每一个 bug或错误,应该思考以下问题。
·这个安全错误是如何发生的?
·在代码的其他部分会不会发生同样的错误?应当如何防止这个错误发生?
·如何确保这类错误将来不会再次发生?是否需要更新安全教育内容或安全分析工具?2)尽可能地减少软件受攻击面。
3)纵深防御。
4)使用最小特权。
5)采用安全的默认设置。
6)向下兼容总是不安全的。随着时间的推移,产品的版本需要与时俱进,不断更新。在处理兼容性方面,其安全性总是需要慎重考虑的。
7)假设外部系统是不安全的。如果应用程序从一个不能受其完全控制的系统接收数据,那么这些接收到的数据都应该被认为是不安全的,甚至可能就是攻击源。例如,注人类攻击就是来自于安全的输入,因此所有外部输人都应该被小心过滤。
8)要有应对失败的计划。不要认为发布的产品就是绝对安全的,要为可能出现的安全问题做好准备,制订应急响应计划。
9)系统失效时进入安全模式。在用户提交的数据响应失败时,数据库端返回的数据库类型和版本等信息对于攻击者绕过安全机制成功实施攻击都是有帮助的。因此,当系统失效时尽量不要泄露任何用户不应该知道的信息。用户登录失败时,被告知“您的用户名或密码错误”就是一种安全保护模式。
10)安全特性不等于安全的特性。安全特性是为了保护安全性而设计的。但是使用了安全特性的程序不一定就是安全的,还需要针对威胁模型选择合适的安全方法和安全技术来保证产品的安全性。
11)绝不要将安全仅维系于隐匿。类似于开放设计原则。
12)不要将代码与数据混在一起。缓冲区溢出攻出、SQL注人和跨站脚本等攻击方式,究其根源,都是因为没有严格地将代码和数据进行分隔,导致用户输入的数据可以被当成代码解析执行起来,从而导致安全问题发生。
13)正确地解决安全问题。发现了问题,就要从根本上解决,不能为了解决这个问题而引入其他更多的问题。并且,一个问题可能不仅仅只存在于软件产品的问题发现点,软件中可能还有很多其他地方也存在类似问题,这些都要在解决安全问题的过程中进行全面考虑。
6.安全设计原则介绍
1.减少软件受攻击面原则
软件受攻击面是指,用户或其他程序及潜在的攻击者都能够访问到的所有功能和代码的总和,它是一个混合体,不仅包括代码、接口和服务,也包括对所有用户提供服务的协议,尤其是那些未被验证的或远程用户都可以访问到的协议。一个软件的攻击面越大,安全风险就越大。减少软件受攻击面就是去除、禁止一切不需要使用的模块、协议和服务,其目的是减少攻击可以利用的漏洞。
采取减少软件受攻击面原则的实例如下。
·重要性低的功能可取消;重要等级为中的功能可设置为非默认开启,需要用户配置后才予以开启;重要性高的功能则关闭或增加一些安全措施进行限制。
·重用那些经过测试、已证明安全的现有库和通用组件,而不是用户自己开发的共享库。
2.最小授权原则
最小授权原则是指,系统仅授予实体(用户、管理员、进程、应用和系统等)完成规定任务所必需的最小权限,并且该权限的持续时间也尽可能短。最小授权原则可使无意识的、不需要的、不正确的特权使用的可能性降到最低,从而确保系统安全。
应用程序应该以能够完成工作的最小特权来执行,尽量避免拥有多余的特权属性。因为如果在代码中发现了一个安全漏洞,攻击者可以在目标程序进程中注入代码或者通过目标程序加载执行代码,而这些被注入执行的代码又含有危险操作,那么这部分代码就能够以与该程序进程相同的权限运行。如果没有很高的权限,那么很多程序是无法实现其破坏功能的。不仅要防止程序被攻击,还要尽可能地预防程序被攻击之后的后续破坏行为的实施,将损失尽可能降到最低。
软件设计中采用最小授权原则的实例如下。
·将超级用户的权限划分为一组细粒度的权限,分别授予不同的系统操作员/管理员。对管理员账户分配安全资源的访问权限也要设置为受限访问,而不是超级用户权限。·采用高内聚、低耦合的模块化编程方法,也就是模块之间的依赖关系是弱链接(低耦合).每一个模块只负责执行一个独立的功能(高内聚)
3.权限分离原则
权限分离原则在软件设计中是指,将软件功能设计为需要在两个或更多条件下才能实现,以防止一旦出现问题,整个软件都可能面临风险。实际上这一原则也是最小权限原则的一种体现。
权限分离原则是类似于不将所有鸡蛋放在一个篮子里的防御模式。例如,导弹发射时必须至少由两个人发出正确的指令才能够发射,财务部门中会计和出纳必须由两人分别担任,以防止不同部门人员之间的相互勾结。
软件设计中采用权限分离原则的实例如下。
·清晰的模块划分,将风险分散到各个模块中去。这样,如果出现问题就可以快速定位到模块,以便进行修复;其次,还可以对单个模块进行测试,保证各个模块的正确性;还可以重复使用已经开发的模块,并且可以在已有模块上增加和替换模块,同时不影响原有模块的功能。
·不允许程序员检查自己编写的代码。
4.纵深防御原则
纵深防御又称为分层防御,是指在软件设计中加入层次化安全控制和风险缓解/防御方法。纵深防御原则有助于减少系统的单一失效点。它强调不依赖于单一的安全解决方案,使用多种互补的安全功能,即使一个安全功能失效,也不会导致整个系统遭受攻击。例如,企业通常使用防火墙进行边界防护,如果进一步对数据进行加密等防护,就可以在防火墙被攻击失效的情况下确保数据的机密性。
纵深防御原则还可以威慑好奇的或者非确定性的攻击者,当他们遇到一层又一层的防御控制时,可能就会知难而退。
软件设计中采用纵深防御原则的实例如下。
·在使用预处理语句和存储过程的同时应用输入验证功能,不允许使用用户输入的动态查询结构,以防止注入攻击。
·不允许活动脚本与输出编码、输入或请求验证相结合,以防止跨站脚本攻击XSS.●使用安全域,根据被授权访问的软件或者人员级别来划分不同的访问域。
5.完全控制原则
完全控制原则是指,要求每一次访问受保护对象的行为都应可能进行细粒度检查。例如,在Web应用中,为了方便用户,常常采用让客户端记自又检查结果,即完成身份验证后基于Cookie缓存认证凭证。这种设计方案固然能够提~乙瓷性能,然而也会带来身份假冒和信息泄露的风险,缓冲区中保存的缓存凭证会成为攻绕过身份认证,进行会话劫持、重放攻击及中间人攻击的安全风险。因此,当一个老i官访问对象资源时,不对其访问权限进行检查就允许访问会违反完全控制原则,这样是很危险的。
软件设计中采用完全控制原则的实例如下。
·应该避免仅仅依赖于客户端或者基于Cookie缓存的认证凭证进行身份验证。·不允许没有经过访问权限验证的浏览器进行数据回传。
6.默认安全配置原则
默认安全配置原则是指,为系统提供默认的安全措施,包括默认权限、默认策略等,尽可能让用户不需要额外配置就可以安全地应用。默认安全原则也是保持系统简单化的重要方式。
软件设计中采用默认安全配置原则的实例如下。
·对任何请求默认加以拒绝。
·不经常使用的功能在默认情况下关闭。
·默认检查口令的复杂性。
·当达到最大登录尝试次数后,默认状态下拒绝用户访问,锁定账户。
7.开放设计
软件的开放设计原则是指,软件设计本身应该是开放的,安全防御机制的实现应该不依赖于设计本身。通过模糊和晦涩难懂的方法固然可以给攻击者增加一些难度,或者说某种程度上提供了纵深防御的能力,但不应该是唯一的或主要的安全机制。
这一原则的具体表现是应用于加密设计的柯克霍夫(Kerckhoff)原则,即密码的安全性不依赖于对加密系统或算法的保密,而依赖于密钥。利用经过公开审查的、已经证明的、经过测试的行业标准,而不是仅采用用户自己开发的保护机制是值得推荐的做法。
软件设计中采用开放设计原则的实例如下。
·软件的安全性不应该依赖于设计的保密。
保护机制的设计应该对团队成员的审查工作开放,让一个团队成员发现系统漏洞总比让攻击者发现要好。
8.保护最弱一环原则
保护最弱一环原则也常称为保护最弱链接(( Weakest Link)原则,是指保护软件系统中的最弱组件。该原则类似于“木桶原理”,描述了软件抵御攻击时的弹性主要依赖于最弱组件的安全性,它们可能是代码、服务或者接口。
与最弱链接相关的一个概念是“单点失效”,在软件安全问题中,最弱链接常常是多个单点故障的超集。软件必须被设计为不存在单点的完全失效。当软件被设计为纵深防御时,可以降低最弱链接和单点失效带来的风险。
攻击者常常试图攻击系统中看起来最薄弱的部分,而不是看起来最坚固的部分。有时软件本身并不是系统最薄弱的环节,而人往往是系统的最薄弱环节。例如,攻击者往往通过钓鱼攻击骗取用户账户与口令,而不是花费时间破解。
软件设计中采用保护最弱一环原则的实例如下。·进行风险分析,标识出系统最薄弱的组件。
·对开发人员或者用户进行充分的安全告知、培训和教育。
9最少共用机制原则
最少共用机制原则是指,尽量减少依赖于一个以上用户甚至于所有用户的通用机制。设计应该根据用户角色来划分功能或隔离代码,因为这可以限制软件的暴露概率,提高安全性。
软件设计中采用最少共用机制原则的实例如下。
·不使用成员与管理员和非管理员之间共享的函数或库,而推荐使用两个互相区分的功能,每一个功能为每一个具体的角色服务。
·使诸如文件及变量等共享资源尽可能少。10.安全机制的经济性原则
安全机制的经济性原则是指,以较低的开发成本和资源消耗获得具有较高安全质量的软件产品和系统保障。安全机制的经济性也称化繁为简原则KISS ( Keep It Simple,Stupid ) ,在某些情境下被称为不必要的复杂性原则。
保证代码与设计尽可能简单、紧凑是经济性原则的体现。软件设计越复杂,包含漏洞的可能性越大。更简单的设计意味着程序更易于理解,以及减少的攻击面和更少的弱链接。在攻击面减少的情况下,软件失效的可能性就会越小,发生错误间隔的时间更长,需要修复的问题也越少。
安全机制的经济性原则并不是要求压缩安全上的投入。安全性并不是在业务功能之上的华而不实的功能,而是业务功能之下的系统基本保障功能。微软SDL实践也表明,软件安全开发方法并不会增加成本,相反因为减少了用户的损失和后期系统运行维护的成本而降低了总成本。
软件设计中采用经济性原则的实例如下。
·避免设计不必要的功能和不需要的安全机制,然后再将它们置于禁用状态。
·保持安全机制简单,确保安全机制被全部而不是部分实现,因为后者会导致兼容性问题。同样重要的是要保持数据模型简单,使数据验证代码和例程不过分复杂或不完整。正则表达式能够支持复杂的数据验证,简化数据验证的复杂度。
力求操作方便。单点登录(Single Sign On,SSO)是一个使用户认证简单化并易于操作的好方法。
11.安全机制心理可接受原则
安全机制心理可接受原则是指,安全保护机制设计得要简单,要让用户易用,要确保用户对资源的可访问,以及安全机制对用户透明,用户才会使用这些保护机制。
易用性是指用户使用安全机制的方便程度。例如,很多公司实行了强口令规则,如大小写混合、字母和数字混合并且长度要有一定的限制,另外口令也要求定期变更,以减小口令猜测和强力攻击的可能性,而大多数用户记住复杂的口令非常困难,因此他们倾向于将口令记录到一张纸条上并将它们贴到桌子上,甚至于贴到计算机屏幕上。这是一个典型的安全机制在心理上不被接受的实例。
安全机制不应该阻止资源的可访问性,安全保护机制不应该成为用户额外的负担,更不能比没有安全保护机制的情况下对资源的访问更困难,否则用户就会决定关闭或绕过安全机制,从而中和甚至抵销安全保护机制。
透明性主要是指安全机制本身应该对用户透明或者只有极小的使用阻碍,如果用户对于所用的安全机制存在质疑,他们会选择弃用这些安全机制。
软件设计中采用心理可接受性原则的实例如下。
·配置和执行一个程序应该尽可能简单和直观,输出应该直接而且有用。
通过明确的错误信息和标注通知用户,如消息框提示、帮助对话框及直观的用户界面。
12.平衡安全设计原则
以上介绍的这些安全设计原则每一项都有自己的侧重点,将所有这些安全原则都设计到软件中是不可能的,因此有必要在这些安全原则间进行决策折中,即平衡安全设计原则。
例如,单点登录SSO可以强化用户体验,增加心理可接受性,但它与完全控制原则相矛盾,所以SSO可能只是一个候选方案,并且.SSO本身的设计也要考虑单点失效问题和适当的纵深防御机制。另外,为了实现完全控制,每次都需要对访问权限和优先权进行检查,这些工作会对软件性能产生严重影响,所以软件安全设计需要仔细考虑在实现纵深防御策略的同时不降低用户的体验和心理可接受性。
再如,最少共用机制与利用现有组件的开发方法似乎也相互矛盾,这些也需要在不降低软件安全性的前提下,根据业务需求很好地平衡。心理可接受性原则要求每一次的错误都要向用户报告,实际设计时则需要仔细衡量,以避免内部系统配置信息被泄露。
7.了解软件安全功能设计
P170
8.基于安全模式的软件安全设计
设计模式是对软件设计中普遍存在、反复出现的各种问题,根据多次处理的经验,提出的一套能够快速、准确响应此类问题的解决方案。设计模式描述在各种不同情况下,应解决共性问题。
使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性和程序的重用性。
设计模式特指软件“设计”层次上的问题。具体算法不属于设计模式考虑的范畴,因为算法主要解决计算上的问题,而非设计上的问题。
9.威胁建模
为什么要威胁建模
威胁建模是一项在软件设计阶段不应忽视的、系统的、可迭代的、结构化的安全技术。对软件系统来说,资产包括软件流程、软件本身,以及它们处理的数据。在当前超过70%的漏洞来自于应用软件的情况下,解决软件安全问题应该首先明确应用软件面临的威胁,建立威胁模型,然后才能考虑软件的安全设计和编码实现。
设计模式特指软件“设计”层次上的问题。具体算法不属于设计模式考虑的范畴,因为算法主要解决计算上的问题,而非设计上的问题。
- 早期发现安全风险
- 理解安全需求
- 设计和交付更安全的产品
- 解决其他技术无法解决的问题。
威胁建模的过程:(8个内容也是重点)
第八章
- 软件安全编码的主要工作:
(1)选择安全的编程语言
所谓安全的编程语言,是指那些具有对缓冲区、指针和内存进行管理能力而避免发生软件安全问题的语言。类型安全语言就属于安全的编程语言。
(2)版本(配置)管理
软件版本管理或控制不仅能够保证开发团队正在使用的程序版本是正确的,同时在必要的情况下也能提供回退到上一个版本的功能;另外,软件版本管理还提供了跟踪所有权和程序代码变化的能力。
(3)代码检测
这里的代码主要是指源代码。代码检测是指对代码质量进行检查,以发现是否存在可利用漏洞的过程。根据代码检测时代码所处的状态,可以将代码分析分为两种类型:代码静态检测和代码动态检测。
代码静态检测是指,不在计算机上实际执行所检测的程序,而是采用人工审查或类似动态分析的方法,通常借助相关的静态分析工具完成程序源代码的分析与检测。
代码动态检测是指,实际运行代码时进行检测的方法。通常依靠系统编译程序和动态检查工具实现检测,但完成后可能仍会存在与安全相关的、在编译阶段发现不了的、运行阶段又很难定位的错误。
4。安全编译
编译是指将程序员编写的源代码转换为计算机可以理解的目标代码的过程。安全编译包括以下4个方面的含义。
1)采用最新的集成编译环境,并选择使用这些编译环境提供的安全编译选项和安全编译机制来保护软件代码的安全性。例如在VS中编译时,开启/GS选项对缓冲区的安全进行检查。
2)代码编译需要在一个安全的环境中进行。编译环境的完整性对于保证最终目标代码的正确性是很重要的。可以采用以下一些保证措施。
●在物理环境上,对代码编译系统实施安全访问控制,防止人为地破坏和篡改。
●在逻辑上,使用访问控制列表防止未授权用户的访问。
●使用软件版本控制方法,保证代码编译版本的正确性。
●尽量使用自动化编译工具和脚本,保证目标代码的安全性。
- 对应用环境的真实模拟也是软件编译需要考虑的问题。很多软件在开发和测试环境中运行得很好,而到了生产环境中就会出现很多问题,主要原因就是开发和测试环境与实际开发环境不匹配。由于应用环境比较复杂,因此要开发出能够适应所有环境的应用软件并不是一件简单的工作,对环境的适配也是反映软件应用弹性的一个重要指标。
- 在安全编码阶段,多样化编译技术作为一种提高软件安全性的方法已经得到了应用。
2.CERT安全编码建议:
CERT给出的10条最重要的建议:
1)验证输入(Validate input)。对于不可信任数据源的输入应当进行验证。正确的输人验证能减少大量软件漏洞。这些数据源包括命令行参数、网络接口、环境变量,以及用户文件。
2)留意编译器警告(Heed compiler warnings)。应采用实现了安全特性的编译器,并启用编译器的警告和错误提示功能。不仅要处理和解决代码中的错误,而且也应处理和解决所有的警告,确保不将任何一个警告带入到程序的最终编译版本中。
3)安全策略的架构和设计(Architect and design for security policies)。创建一个软件架构来实现和增强安全策略。例如,如果系统在不同的时间需要不同的权限,则考虑将系统分成不同的互相通信的子系统,每个系统拥有适当的权限。
4)保持简单性(Keep it simple)。这是第7章中介绍的减少软件被攻击面原则的体现。程序越复杂,控制会越复杂,就会增加代码出错的可能。要尽量使程序短小精悍,代码中的每个函数应该具有明确的功能,在编写函数代码时,应在保持功能完整实现的前提下控制该函数内代码量的多少。对于复杂的功能,应将该功能分解为更小、更简单的功能,确保软件仅包含所要求或规定的功能。
5)默认拒绝 (Default deny)。这是第7章中介绍的默认安全配置原则的体现。默认的访问权限是拒绝,除非明确是允许的。
6)坚持最小权限原则(Adhere to the principle of least privilege)。这是一个通用的安全原则,在本书第7章已经提及,这里从编码角度再次重申。每个进程拥有完成工作所需的最小权限,任何权限的拥有时间要尽可能短,以阻止攻击者利用权限提升执行任意代码的机会。
7)清洁发送给其他系统的数据(Sanitize data sent to other systems)。清洁所有发送给子系统的数据,以免攻击者实施注人类等攻击。输人验证后再次净化数据是纵深防御的体现。
8)纵深防御(Practice defense in depth)。这是一个通用的安全原则,在本书第7章已经提及。
9)使用有效的质量保证技术(Use effective quality assurance techniques)。好的质量保证技术能有效地发现和消除漏洞。渗透测试、模糊测试及源代码审计可以作为有效的质量保证措施。独立的安全审查能够促成更安全的系统,外部审查人员能带来独立的观点。
10)采用安全编码标准( Adopt a secure coding standard)。为开发语言和平台设计安全编码标准,并应用这些标准。多数漏洞很容易通过使用一些规范编码的方法来避免,例如对代码进行规范缩进显示,可以有效避免出现遗漏错误分支处理的情况。
3.开发语言的安全性Java
4.Java语言安全编码
(1)语言层安全
1)通过某些关键字(如private、protected )定义代码的可见性范围(即权限)。在 Java语言中,可见性最高层次以包为单位来划分,除了声明为public的类以外,其他类在包外是不可见的。权限的实现通过对象来表示,获取了对象就等于获取了它所代表的权限,也就获取了对应资源的操作能力。Java限制了cast 操作并取消了指针,使得用户不能通过直接对内存访问和类型转换来非法获取对象引用。创建并使用对象的唯一途径是通过new操作符,使得资源保护可以通过对象的构造函数来实现。
2)通过类型规则确保程序运行时变量的值始终与声明的类型一致,在函数或方法调用时形参与实参的类型匹配。Java类型规则构建自较为成熟的类型安全理论,包括编译时的静态类型检查和动态装入时的类文件校验,以及Java虚拟机的强制类型转换系统。稍做简化的Java语言模型已被证明是类型安全的。
同时Java还采用自动内存管理、垃圾收集站、字符串和数组的范围检查等方法,确保Java语言的安全性。
(2)字节码层安全
Java源代码经过编译后产生字节码类文件* . class,字节码就是Java虚拟机(JVM)的机器码指令。在字节码层次,Java提供了两种保障安全的机制:类加载器和字节码验证器。
- 类加载器。它是Java程序执行时的第一道安全防线。由于在JVM中执行的所有代码均由加载器从JVM外部的类文件中加载进来,因此它可以起到:排除恶意代码对正常代码的干扰、保证可信类库不会被替代,把每个类加载到相应的保护域中等作用。
2)字节码验证器。Java程序被编译成类文件后,可以在不同平台的JVM上运行。一个类文件就是一个字节序列,这就造成了JVM无法辨别特定的类文件是由正常的编译器产生还是由黑客特制,为此需要一个文件类检验器—字节码验证器,保证加载的类文件内容有正确的内部结构,并且这些类文件相互间协调一致,以确保只有合法的Java代码才能被执行且执行时不会带来破坏性的操作,如修改运行栈的数值或更新系统对象的专用数据区等。
验证分为静态和动态两个阶段。所谓静态验证,是指由字节码验证器在JVM运行字节码前做检查,一旦不能通过静态检查,根本就不会启动JVM。所谓动态验证,是指利用由JVM在字节码运行期间所做的验证。这两个阶段的验证通过4次独立的扫描来完成。
·类文件的结构检查。在类文件加载时,检查类文件的格式是否正确。包括方法的正确定义、属性的长度是否合适、字节码的长度在合适的范围,以及常量池 (ConstantPool)是否能够被分析等。
类型数据的语义检查。在链接时,检查那些不用分析字节码就可以验证对错的地方,主要是一些语法级的检查。它包括: final类不能被继承或重载;每个类必须要有一个超类;常量池必须满足更严格的限制条件;常量池中关于属性和方法的引用必须要有合法的类名、属性名、方法名或者合适的签名。
●字节码验证。在链接时,用字节流分析法验证字节码的正确性。对指定字节码程序中的任何给定点,不管这一点如何到达,必须做到:栈的大小一致;寄存器的存取要进行合适的类型检查;属性域被修改成合适的类型:所有的操作码要有合适的参数,或者在栈上,或者在寄存器中。
●符号引用的验证。在动态链接过程中,加载将要用到但是还没有用到的类的定义,并验证当前类是否允许引用新加载的类。这将导致对相应操作码的重写并加上快速标记,以便于以后加载该类时可以快速加载,从而提高了运行速度。
第九章
- 软件测试与软件安全测试
区别:软件测试主要是从最终用户的角度出发发现缺陷并修复,保证软件满足最终用户的要求。软件安全测试则是从攻击者的角度出发发现漏洞并修复,保证软件不被恶意攻击者破坏。通常普通用户不会去寻找软件漏洞,而恶意攻击者往往会想方设法寻找软件中的安全漏洞。安全测试和传统测试的最主要区别就是安全测试人员要像攻击者一样寻找系统的软肋。
软件测试用例是根据功能需求和其他开发文档等设计的。安全测试用例则是通过安全需求、攻击模式归纳,以及已公布的漏洞等从攻击者的角度设计的。测试用例中测试数据的选择也不相同,软件测试一般选取正向数据,而安全测试更多的是考虑反向数据,是攻击者精心构造的具有攻击性的数据。
目标:软件安全测试是在产品发布之前,达到以下目标。
·验证软件系统的安全功能是否满足安全需求。
·发现系统的安全漏洞,并最终把这些漏洞的数量降到最低。
·估软件的其他质量属性,包括可靠性、可存活性等。
内容:
1)软件安全功能测试。基于软件的安全属性需求,测试安全功能的实现是否与安全属性要求一致,以及安全功能实现的强度和完备性。功能实现强度测试是指证实安全功能,特别是加密算法、协议和口令策略的强度是否达到定义的要求;功能实现完备性测试是指测试是否有其他的方式降低安全实现的强度或者绕过安全实现的功能区域。
2)软件安全漏洞测试。安全漏洞测试是有关识别潜在的软件安全缺陷和验证应用程序安全性的过程。它站在攻击者的角度,以发现软件的安全漏洞为目标。
软件安全测试的根本目标是保证被测试软件在面对恶意攻击时仍能按照可接受的方式运行。因此,漏洞测试是软件安全测试的主要内容。
原则:
1)应尽早进行软件安全测试,越晚发现漏洞,修复的成本越高。
2)在有限的时间和资源下进行测试,找出软件所有的错误和缺陷是不可能的,软件测试不能无限进行下去,应适时终止。在软件安全测试中同样如此,应该通过威胁建模等方法,优先测试高风险模块。
3)软件安全没有银弹。测试只能证明软件存在错误而不能证明软件没有错误。测试无法显示潜在的错误和缺陷,继续进一步测试可能还会找到其他错误和缺陷。同理,安全测试只能证明系统存在安全漏洞,并不能证明应用程序是安全的,只用于验证所设立安全策略的有效性,安全策略是基于威胁分析阶段假设选择的。
4)程序员应避免检查自己的程序。同样,软件安全测试也应该如此。
5)尽量避免测试的随意性。软件安全测试是有组织、有计划、有步骤的活动,要严格按照测试计划进行,避免测试的随意性。
方法:
2.模糊测试
模糊测试( Fuzz 'Testing)主要属于黑盒测试和灰盒测试领域,是一种基于缺陷注入的软件安全测试技术。模糊测试技术的核心思想是通过监视非预期输入可能产生的异常结果来发现软件问题。
具体来说,就是使用大量半有效的数据作为应用程序的输入,以程序是否出现异常作为标志,发现应用程序中可能存在的安全漏洞。所谓半有效的数据是指,对应用程序来说,测试用例的必要标识部分和大部分数据是有效的,这样待测程序就会认为这是一个有效的数据,但同时该数据的其他部分是无效的。这样,应用程序就有可能发生错误,这种错误可能导致应用程序的崩溃或者触发相应的安全漏洞。
模糊测试方法分类:
1)预生成测试用例。需要理解对象规约支持的数据结构和可接受的范围,然后对应生成测试边界条件或是违反规约的测试用例。生成测试用例很费神,但可复用。用完用例,则测试结束。
2)随机生成输入。效率最低,但可快速识别目标是否有非常糟糕的代码。
3)手工协议变异测试。比随机生成更加初级。其优点是可充分发挥自己过去的经验和“直觉”。常用于Web应用安全测试。
4)变异或强制性测试。模糊器从一个有效的协议样本或是数据格式样本开始,持续不断地打乱数据包或是文件中的每一个字节、字、双字或是字符串。虽然该方法浪费了CPU资源,但是不需要对应用进行研究,并且整个模糊测试过程可以完全自动化。
5)自动协议生成测试。需要先对应用进行研究,理解和解释协议规约或文件定义。但是,这种方法并不基于协议规约或文件定义创建硬编码的测试用例,而是创建一个描述协议规约如何工作的文法。例如,SPIKE和SPIKEfile工具都是这类测试的典型例子,采用SPIKE 脚本描述协议或是文件格式,并使用一个模糊测试引擎来创建输入数据。
模糊测试过程:
1.确定测试目标
不同的测试目标使用的模糊测试技术和方法也不一样。要考虑是对内部开发的应用程序,还是对第三方应用程序进行模糊测试。还必须选择应用程序中具体的目标文件或库,尤其是选择那些被多个应用程序共享的库,因为这些库的用户群体较大,出现安全漏洞的风险也相应较高。
在此过程中,针对被测试的程序,在一些典型的漏洞信息网站,如SecurityFocus ,Secunia和CNVD等,查找软件开发商历史上曾出现的安全漏洞,分析这些漏洞的形成原因及编码习惯,有针对性地选择相应的模糊测试工具和方法。
2.确定预期输入
模糊测试是一个不断枚举输入向量的过程,任何从客户端发往目标应用程序的输入都应该作为输入向量,比如一个HTTP请求,包括请求头、URL及发送的参数等,其他输入向量还有文件名、环境变量及注册表键值等。对不同的软件,可以选择性地侧重某些输入向量,但是一个完整的模糊测试过程应该进行充分、完全的测试。例如,对TCP协议处理软件进行模糊测试,不仅要对数据部分进行测试,序号、确认号、数据偏移字段、标志位、保留字段、窗口及校验和等部分也应该被纳入模糊测试的范围。
3.生成模糊测试用例
确定待测试目标和输入向量后,应该根据不同的输人向量选择不同的模糊器来生成模糊测试用例。由于数据量较大,这个阶段通常会采用自动化方式完成。模糊器常用的生成测试数据的方法如下。
·基于生成的方法,在对目标软件输入数据格式的规约有深刻了解的基础上,自动生成—些不满足数据规约的测试样本。
·基于变异的生成方法,从一个合法的样本出发,通过某些算法不断地修改其中一些数据,生成一批畸形的测试用例。
·生成和变异相结合的方法。4.执行模糊测试用例
执行模糊测试用例就是将上一阶段生成的大量模糊测试数据不断发送给待测试目标程序。面对大量的模糊测试数据,同样需要使用自动化工具来完成。
5.监视异常
监视异常可以发现程序哪里发生故障,并根据监视信息进一步分析为什么会产生故障。由于模糊测试过程比较长,当测试用例的数目较多时,通常需要采用自动化的方式实现。当前常用的异常监视技术依据原理分为两种。
1)基于调试的方法。在调试模式下启动目标软件,通过操作系统平台提供的调试API,开发有针对性的异常监测模块。此方法实现异常监视虽然难度较大,但更加高效。
2)基于插桩的方法。在模糊测试过程中,仅仅通过观察程序的输入、输出,对了解软件内部的运行信息往往是不够的。例如软件运行过程中内部变量的状态信息、模块之间的交互信息等,这些信息对于发现漏洞及定位漏洞来说特别重要。基于插桩的方法就是在保证被测试程序原有逻辑完整的基础上,在程序中插入一些探针(又称为“探测仪”,本质上就是进行信息采集的代码段,可以是赋值语句或采集覆盖信息的函数调用),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。目前常用的插桩方法分为源代码插桩、静态代码插桩和二进制代码插桩等。
·源代码插桩(Source Code Instrumentation),这是一种最自然的方式,即在编写软件时,在需要监视的地方插人检测代码,如增加输出信息语句、增加日志语句等,尤其是面向切面编程技术(Aspect Oriented Programming)可以较好地用于源代码插桩,有效地分离业务逻辑与监测逻辑。
·静态代码插桩。例如在Java中,字节码插桩可以直接更改中间代码文件(如Java的.class文件等)或在类被类加载器(Class Loader)装载时进行字节码插桩。字节码插桩拥有执行效率高、插桩点灵活等优点,使其在面向切面编程领域大放光彩,并陆续出现了BCEL、Javassit和ASM 等工具。
·基于二进制的插桩,该技术可以进一步提高模糊测试的异常监测能力,但是其系统消耗较大,且大部分为商业插桩软件。常用的二进制插桩工具有DynamoRIO、Dyninst和Pin等。
6.异常分析并确认漏洞
异常分析并确认漏洞是模糊测试过程中的最后一步,主要分析目标软件产生异常的位置与引发异常的原因。常用的分析方法是借助于IDA Pro、OllDbg 和 SoftICE等二进制分析工具进行人工分析。
二、课后题目
1.3当前,黑客为了能够有效达到窃取数据、破坏系统的目的,常常通过挖掘或是购买零日漏洞,开发针对零日漏洞的攻击工具,零日漏洞威胁实际上反映了软件系统存在的一个什么问题?
系统存在由于软件厂商还没有发现或是还未提供相应的补丁,即软件漏洞。
1.4根据本书的介绍,软件安全威胁可以分为哪几类?
本书将软件面临的安全威胁分为三大类:软件自身的安全(软件漏洞)、恶意代码及软件侵权。
1.6什么是恶意代码?除了传统的计算机病毒,还有那些恶意代码类型?
恶意代码实在未被授权的情况下,以破坏软硬件设备、窃取用户信息、干扰正常用户使用、扰乱用户心理为目的而编制的软件或代码片段。
恶意代码包括计算机病毒、蠕虫、特洛伊木马、后门、内核套件、间谍软件、恶意广告、流氓软件、逻辑炸弹、僵尸网络、网络钓鱼、恶意脚本及垃圾信息等恶意的或令人讨厌的软件及代码片段。近几年危害甚广的勒索软件也属于恶意代码范畴。
1.8谈谈对软件安全概念的理解。
软件安全是软件工程与软件保障的一个方面,它提供一种系统的方法来标识、分析和追踪对危害及具有危害性功能(例如数据和命令)的软件缓解措施与控制。
1.12确保软件安全的基本思路是什么?软件安全设计的技术主要有哪些方面?
确保软件安全的基本思路是:
1)采用多种检测、分析及挖掘技术对安全错误或是安全漏洞进行发现、分析与评价,然后采取多种安全控制措施进行错误修复和风险控制,如传统的打补丁、防病毒、防火墙、入侵监测和应急响应等。
2)分析软件安全漏洞发生的原因,将安全错误的修正嵌入到软件开发生命周期的整个阶段。
软件安全设计的技术主要有:软件安全属性的认知、系统安全工程、软件安全开发。
2.3试分析软件漏洞的成因。
- 计算机系统结构决定了漏洞的必然性。
- 软件趋向大型化,第三方扩展增多。
- 新技术新应用产生之初既缺乏安全考虑。
- 软件使用场景更具威胁。
- 对软件安全开发重视不够,软件开发者缺乏安全知识。
2.4软件漏洞如何分类分级管理。
软件漏洞的分类:
1.基于漏洞成因的分类:内存破坏类、逻辑错误类、输入验证类、设计错误类、配置错误类
2.基于漏洞利用位置的分类:本地漏洞、远程漏洞
3.基于威胁类型的分类:获取控制、获取信息、拒绝服务
软件漏洞的分级:
1.按照漏洞严重等级进行分级
2.利用通用漏洞评分系统进行分级。
2.5软件漏洞管理应当遵循怎样的标准.
国际标准:
1.通用漏洞和披露
2.通用缺陷枚举/评分系统
3.通用平台枚举
4.开放漏洞评估语言
国内标准:
1.安全漏洞标识与描述规范:《信息安全技术 安全漏洞标识与描述规范》
2.安全漏洞分级规范:《信息安全技术 安全漏洞等级划分指南》
3.安全漏洞分类规范:《信息安全技术 安全漏洞分类》
4.安全漏洞管理规范:《信息安全技术 信息安全漏洞管理规范》、CNNVD漏洞管理规范。
3.1程序运行时的内存布局是怎样的?
进程使用的内存按功能可以分为4个区域:
①代码区:存放程序汇编后的机器代码和只读数据。
②数据区:用于存储全局变量和静态变量。
③堆区:该区域内存由进程利用相关函数或运算法动态申请,用完后释放并归还堆区。
④栈区:该区域内存由系统自动分配,用于动态储存函数之间的调用关系。在函数调用时存储函数的入口参数、返回信息和局部变量等信息,以保证被调用的函数在返回式能恢复只掉函数继续执行。
3.2在程序运行时,用来动态申请分配数据和对象的内存区域形式称为什么?
堆区。
3.3什么是缓冲区溢出漏洞?
缓冲区溢出漏洞就是在向缓冲区写入数据时,由于没有做边界处理,导致写入缓冲区的数据超过预先分配的边界,从而使溢出数据覆盖在合法数据上而引起系统异常的一种现象。
3.4简述Windows安全漏洞保护的基本技术及其存在的问题。
(1)栈溢出检测选项/GS:除了在栈中加入安全Cookie外,在VisualStudio2008以及以后版本中还增加了对函数内部的局部变量和参数的保护功能,编译器会进行以下操作:
①对函数栈重新排序,把字符串缓冲区分配在栈帧的高地址上,这样当字
符串缓冲区被溢出时,也就不能溢出任何本地局部变量了。
②编译器还会将函数参数复制到寄存器或放到栈缓冲区上,以防止参数被
溢出。
存在的问题:
从/GS栈溢出检测机制来看,其关键之处就是在栈中加入安全Cookie来保
护相关参数和变量,因此,对抗这种栈溢出保护机制可以通过Cookie值展开。
(2)数据执行保护DEP:栈溢出漏洞的最常见利用方式是:在栈中精心构造二进制串溢出原有数据结构,进而改写函数返回地址,使其跳转到位于栈中的Shellcode 执行。如果使栈上数据不可执行,那么就可以阻止这种漏洞利用方式的成功实施。而DEP 就是通过使可写内存不可执行或使可执行内存不可写,以消除类似威胁的。
存在的问题:
可利用ret-to-libc执行命令或进行API调用,如调用WinExec实现执行程序;将包含Shellcode的内存页面标记为可执行,然后再跳过去执行;通过分配可执行内存,再将Shellcode复制到内存区域,然后跳过去执行;先尝试关闭当前进程的DEP保护,然后再运行Shellcode。等方式找到一个可执行的区域来对抗数据执行保护DEP
(3)地址空间布局随机化ASLR机制:通过对堆、栈和共享库映射等线性区
域布局的随机化,增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代
码位置,达到阻止漏洞利用的目的。
存在的问题:
①对本地攻击者无能为力;
②造成内存碎片增多;
③利用没有采用/DYNAMYCBASE选项保护的模块做跳板。
(4)安全结构化异常处理SafeSEH机制:编译器在链接生成二进制IMAGE时,
把所有合法的异常处理函数的地址解析出来制成一张安全的SEH表,保存在程
序的IMAGE数据块里面,当程序调用异常处理函数时会将函数地址与安全SEH
表中的地址进行匹配,检查调用的异常处理函数是否位于该表中。如果IMAGE
不支持SafeSEH,则表的地址为0。
安全结构化异常处理保护机制的作用是防止覆盖和使用存储栈上的SEH结
构。如果使用/SafeSEH链接器选项编译和链接一个程序那么对应二进制的头部
将包含一个由所有合法异常处理程序组成的表,当调用异常处理程序时会检查这
张表,以确保所需的处理程序在这张表中。
存在的问题:
WindowsXP/2003等绝大部分系统库不支持Windows的IMAGE。当进程中
存在一个不支持SafeSEH的IMAGE时,整个SafeSEH的机制就很有可能失效。
此外,由于支持SafeSEH需要.Net的编译器支持,现在仍有大量的第三方程序和库未使用.Net编译或者未采用/safeSEH链接选项,这就使得绕过SafeSEH成为可能。如利用未启用SafeSEH的模块作为跳板进行绕过;利用加载模块之外的
地址进行绕过等。
(5)增强缓解体验工具包EMET:由于操作系统版本的差异性,不同版本的操作系统上所能提供的增强型保护机制也不尽相同,且目前仅支Windows XP SP3及以上版本。
4.3根据OWASP在2013发布的Web安全十大威胁报告,Web漏洞分为哪几大类型、请将该报告与2017年发布的Web安全十大威胁进行对比,了解这近几年来Web安全威胁有哪些新的变化和发展?
2013发布的报告中,Web漏洞分为:注入、失效的身份认证与会话管理、跨站脚本、不安全的直接对象引用、错误的安全配置、敏感数据泄露、缺失功能级访问控制、跨站请求伪造、使用有漏洞的组件、未验证的重定向和转发。
对比2013与2017年的报告发现:注入攻击漏洞仍然位居 Top 10 威胁之首,而XSS的威胁程度从A3降到了A7。敏感信息泄露、安全配置错误、失效的访问控制等威胁均有提升,值得重视。与此同时,榜单中还出现了一些新的安全威胁,包括XXE漏洞、针对Java平台的不安全反序列化漏洞以及记录和监控不足风险等,这些新兴的安全威胁也值得重点关注
4.5.简述SQL注入漏洞的原理?为什么SQL注入漏洞多年来一直名列Web安全漏洞的榜首?
答:原理:攻击者能够利用现有Web应用程序,将恶意的数据插入SQL查询中,提交到后台数据库引擎执行非授权操作。
SQL注入漏洞的风险要远高于其他所有的漏洞,SQL注入攻击具有广泛性,所有基于SQL语言标准的数据库软件,以及与之连接的网络应用程序都面临该类攻击。此外SQL注入攻击原理相对简单,介绍注入漏洞和利用方法的教程资源非常多。这些因素造成SQL注入攻击的数量一直居高不下。
4.6.防范SQL注入漏洞的基本方法有哪些?重点谈谈在代码开发层面的安全措施。
答:基本防范措施:
1.代码层漏洞防护:
①采用强类型语言;
②尽量避免使用拼接的动态SQL语句,所有查询语句都使用数据库
③提供的参数化查询接口;
④服务器端验证输入的值和类型是否满足预期要求;
⑤在服务器端对用户输入进行过滤;
⑥避免网站显示SQL错误信息;
⑦加固应用程序服务器和数据库,利用最低权限账户与数据库连接。
使用专业的漏洞扫描工具进行安全性措施:SQLMap、Pangolin
4.8.在如图4-26所示页面中,当输入“1’”进行注入尝试时,系统返回数据库报错信息,是否可以肯定这里一定存在数字型注入漏洞?
答:不能,因为如果输入1’后只能判断存在注入漏洞,而不能肯定是什么类型,具体类型应当根据报错信息,或者其他输入值对应的显示情况进行判断,要想确定存在数字型注入还需要在id后面分别输入“1 and 1=1”和“1 and 1=2”看是否和直接输入1返回的页面相同。
。
4.13.材料分析:第一个XSS蠕虫Samy。
(1)搜集相关资料,详细了解上述两个事件。
(2)分析攻击事件中XSS漏洞的原理。
XSS漏洞是指,应用程序没有对接收到的不可信数据经过适当的验证或转义就直接发给客户端浏览器。
第一个材料和第二个材料中的XSS是存储型XSS,此类型的XSS不需要用户单击特定的URL就能执行跨站脚本。攻击者事先将恶意脚本代码上传或者存储到存在漏洞的服务器端数据库中,只需要用户浏览包含此恶意脚本的网站便会触发。
(3)谈谈如何防范此类攻击事件再次发生。
答:对于用户,应当提升自身对陌生URL的辨识度和警惕性;
对于开发者,应当在应用程序的开发过程中采取各种防御手段和保护措施:
1.输入验证
2.采用开发框架自带的标签输出方式
3.对输出数据进行净化
4.将Cookie设置为HttpOnly
5.谨慎使用DOM操作
6.使用检测工具
4.19.综合实验:分析下面这段代码是否存在安全漏洞,若有,请给出漏洞利用方法。
答:存在漏洞。
1.mysql_real_escape_string()可以转义SQL语句中使用的字符串中的特殊字符,可以通过转化utf等进行绕过。
2.Mysql_error()会返回mysql操作产生的错误信息,直接显示在网页上导致更容易被注入。
5.1什么是软件生命周期?软件生命周期通常包括哪几个阶段?
正如任何事物一样,软件也有其孕育、诞生、成长、成熟和衰亡的生存过程,一般称其为“软件生命周期”。
概括地说,软件生命周期由定义、开发和维护3个时期组成,每个时期又可进一步划分成若干个阶段。
5.4 SD3+C原则是SDL的基本原则,试简述其内容。
SD3+C原则是 SDL模型实施的基本原则,其基本内容如下。
·安全设计(Secure by Design)。在架构设计和实现软件时,需要考虑保护其自身及其存储和处理的信息,并能抵御攻击。
·安全配置(Secure by Default)。在现实世界中,软件达不到绝对安全,所以设计者应假定其存在安全缺陷。为了使攻击者针对这些缺陷发起攻击时造成的损失最小,软件在默认状态下应具有较高的安全性。例如,软件应在最低的所需权限下运行,非广泛需要的服务和功能在默认情况下应被禁用或仅可由少数用户访问。
·安全部署(Security by Deployment)。软件需要提供相应的文档和工具,以帮助最终用户或管理员安全地使用。此外,更新应该易于部署。
·沟通(Communication)。软件开发人员应为产品漏洞的发现准备响应方案,并与系统应用的各类人员不断沟通,以帮助他们采取保护措施(如打补丁或部署变通办法)。
5.5微软的SDL模型与传统的瀑布模型的关系是怎样的?
SDL模型是由软件工程的瀑布模型发展而来的,是在瀑布模型的各个阶段添加了安全活动和业务活动目标。SDL模型的简化描述如图5-1所示,它包括了必需的安全活动:安全培训、安全需求分析、安全设计、安全实施、安全验证、安全发布和安全响应。为了实现所需的安全目标,软件项目团队或安全顾问可以自行添加可选的安全活动。
5.6什么是敏捷SDL?敏捷SDL和经典SDL 的区别是什么?
很多软件产品开发的时间都很紧迫,一般Web项目开发可能只有2~3周的时间,采用完整的SDL开发流程显然不切实际,因此需要更加简洁、快速的软件安全开发方法。为此,微软对SDL进行了调整,使其能够快速利用敏捷开发流程更好地实现安全需求,这就是敏捷SDL。
敏捷SDL与典型SDL的差别主要有两点。
1))敏捷SDL不采用传统的瀑布模型,而是采用无阶段的迭代开发模型,以实现软件版本的快速更新和发布。如果开发团队采用瀑布式开发流程(具有明确定义的设计、实现、验证和发布阶段),那么更适合采用典型的SDL模型,而并不适合敏捷SDL。
2)在敏捷SDL中,并不是每个发布版本(或每次“突击发布”)都需要达到所有的要求,这也是敏捷SDL与传统SDL之间最大的差别。
7.2软件安全设计阶段的主要工作是什么?
1.软件安全设计的目的和作用
2。软件安全设计与软件设计的联系
- 软件架构安全性设计
- 软件架构安全性分析
7.4为什么要进行软件安全架构安全性分析?软件架构安全性分析的基本过程是什么?
在软件架构安全性设计的过程中,尤其是对于大而复杂的系统,要将安全属性一次性设计到软件架构中成为架构的有机组成部分,这是一项非常具有挑战性的工作。
为此,一旦软件架构设计或是软件架构安全性设计完成,在退出设计阶段进入开发阶段之前,需要对软件(安全)架构和设计方案进行检查,以确保设计能够满足软件的安全需求。这不仅包括功能方面的设计检查,也包括安全设计检查。检查可以帮助开发人员在编码之前对安全设计要素进行验证,提供一个识别和处理任何安全漏洞的机会,减少后续阶段重新设计软件的需要。
设计检查需要考虑安全政策和软件部署的目标环境,同时也需要对应用系统进行全局检查。网络和主机水平的安全保护都需要到位,保护措施之间不会相互矛盾从而削弱保护强度。需要特别关注软件安全设计基本原则和软件核心安全属性需求的设计,以确保保密性、完整性和可用性。此外,还需要逐层对软件架构进行分析以保证纵深防御控制措施到位。攻击面评估、威胁建模和滥用案例建模、安全体系结构和设计检查等几个方面都是非常有用的,它们可以确保软件不仅能实现预期的功能,同时也不会违反任何安全策略。
7.5软件受攻击面指什么?举例说明软件设计时可以采取哪些策略来降低受攻击面?
软件受攻击面是指,用户或其他程序及潜在的攻击者都能够访问到的所有功能和代码的总和,它是一个混合体,不仅包括代码、接口和服务,也包括对所有用户提供服务的协议,尤其是那些未被验证的或远程用户都可以访问到的协议。一个软件的攻击面越大,安全风险就越大。减少软件受攻击面就是去除、禁止一切不需要使用的模块、协议和服务,其目的是减少攻击可以利用的漏洞。
采取减少软件受攻击面原则的实例如下。
·重要性低的功能可取消;重要等级为中的功能可设置为非默认开启,需要用户配置后才予以开启;重要性高的功能则关闭或增加一些安全措施进行限制。
重用那些经过测试、已证明安全的现有库和通用组件,而不是用户自己开发的共享库。
7.6什么是最小授权原则?试举例说明软件设计时哪些措施是采用了最小授权原则?
最小授权原则是指,系统仅授予实体(用户、管理员、进程、应用和系统等)完成规定任务所必需的最小权限,并且该权限的持续时间也尽可能短。最小授权原则可使无意识的、不需要的、不正确的特权使用的可能性降到最低,从而确保系统安全。
应用程序应该以能够完成工作的最小特权来执行,尽量避免拥有多余的特权属性。因为如果在代码中发现了一个安全漏洞,攻击者可以在目标程序进程中注入代码或者通过目标程序加载执行代码,而这些被注入执行的代码又含有危险操作,那么这部分代码就能够以与该程序进程相同的权限运行。如果没有很高的权限,那么很多程序是无法实现其破坏功能的。不仅要防止程序被攻击,还要尽可能地预防程序被攻击之后的后续破坏行为的实施,将损失尽可能降到最低。
软件设计中采用最小授权原则的实例如下。
·将超级用户的权限划分为一组细粒度的权限,分别授予不同的系统操作员/管理员。对管理员账户分配安全资源的访问权限也要设置为受限访问,而不是超级用户权限。
·采用高内聚、低耦合的模块化编程方法,也就是模块之间的依赖关系是弱链接(低耦合),每一个模块只负责执行一个独立的功能(高内聚)。
7.10什么是安全模式?为什么说能够利用安全模式来快速、准确地进行软件安全设计?
安全模式是在给定的场景中,为控制、阻止或消减一组特定的威胁而采取的通用解决方案。该解决方案需要应对一系列的问题,并且可以使用UML类图、时序图、状态图和活动图等进行表述。
安全模式封装了反复出现的系统问题的解决方案,同时精确地表述了系统要求和解决方案。采用模式的系统架构描述比较容易让人看懂,也为设计和分析提供了指南,还定义了使架构更安全的方法。安全模式使得不具备专业安全知识的应用开发人员也可以使用安全措施。还可以通过分析现有系统看它们是否包含特定的模式,进而评估它们的安全性。此外,可以在改造旧有系统时,利用模式来添加系统中缺失的安全特性。
7.11试给出一种利用安全模式进行软件安全设计的方法?
一种基于安全模式的软件安全设计方法过程可以分为3个阶段:风险确定阶段、系统安全架构阶段和系统设计细化阶段。在每一个阶段,需要进行一系列相应的实践活动,通过实行这些实践活动,完成每一个阶段的任务,最终实现系统的安全架构。
(1)风险确定阶段
该阶段主要有两个工作:识别风险和评估风险。该阶段通过对业务需求、用户需求及安全需求等的分析,利用历史威胁记录及经验,识别并评估系统面临的风险。
(2)系统安全架构阶段
该阶段对风险进行消解,并对解决方案进行评估,在此基础上构建系统的高层架构图。主要工作包括浏览模式库、选择安全模式、评估安全模式和建立系统高层架构。
1)浏览模式库。如同在学习编程语言时,需要熟悉语言提供的那些基本功能类库一样,通过浏览模式库,可以获知哪些威胁问题已有成熟的解决方案,以及模式的分类情况怎样等信息。浏览模式库的过程主要关注模式解决什么样的问题,而不是关注模式怎么样解决。
2)选择相应的安全模式。在该过程中,选择一系列相应的安全模式以应对风险识别阶段所识别出的风险,这些识别出来的安全模式将作为之后系统安全架构的原材料。
在选择模式时,要审阅模式的问题描述域,看是否与当前项目中的风险匹配。要通过浏览解决方案描述部分和结构图部分考虑这个模式怎样解决了这个风险问题,并且考虑这个解决方案是否可以被应用于解决手头的问题。此外,还应该关注模式间的关联关系,是否存在相似模式或者起补充作用的模式等。有些从系统架构连接层次进行考虑的安全模式,其本身可能并不专为解决某类风险而存在,而是为更好地进行安全功能与业务功能的协调而存在,这类安全模式在构建系统高层架构图时会用到,因此也需要在此阶段对此类模式做出选择。
当模式库的规模不够大,安全模式的问题解决范围覆盖不够广泛时,可能会有部分识别出的系统风险没有现成的解决方案,这种情况下需要求助于安全专家。
3)评估安全模式。该阶段应着重关注安全模式的问题描述域和结果域。问题描述域要看该模式解决的问题是否与待解决的风险完全吻合,还是仅仅只是一个子集,亦或二者存在着交集;结果域重在分析该安全模式对其所应对的风险的效果如何,是否足以完全应对风险,还是部分解决。此外,还应该关注模式之间的关系,尤其是补充关系(该模式不足以应对当前风险,需要在其他模式的配合下才能完全移除)和精化关系(该模式应对的是一大类风险,具体的风险有更为具体的应对模式)。
评估结果通常会是两类:一类是完全移除风险,安全模式所解决的问题与系统风险吻合,这是最理想的一种情况;二是部分移除,安全模式所解决的问题并不能与系统风险问题完美匹配,仅仅只能移除部分风险,这时就需要寻找相关模式,期待一系列模式的结合可以应对风险。
4)建立系统高层架构。在该过程中,架构设计人员需对系统进行功能结构分解,并在此基础上建立各个功能模块的关联关系,从而最终绘制出系统完整的高层结构图。
(3)系统设计细化阶段
该阶段的主要工作包括:构建业务类图、实例化安全模式,以及整合系统并适当重构。在该阶段,在前一阶段选定的安全模式集和系统高层架构图的基础上,细化业务分析和实例化安全模式,并将它们整合到一起形成系统的完整设计类图。
7.12什么是威胁建模?试简述威胁建模的过程。
软件威胁建模是指,通过抽象的概念模型对影响软件系统的威胁进行系统的识别和评价。
7.13在威胁排序的几种计算方法中,为什么说Delphi法和平均排序法,P×I排序方法更科学?
相比 Delphi法和平均排序法,PXI排序方法更科学。PxI排序考虑业务影响(潜在损失和受影响的用户)和发生概率(可再现性、可利用性和可发现性)。PxI排序法对事件发生概率、业务影响及它们合并的影响进行深入分析,使得设计团队能够灵活地掌握如何降低事件发生的概率、减小业务影响或二者同时降低;此外,PxI排序方法还给出了更精确的风险图谱。
三、考试题型
选择题20个20分,填空题10空10分,名词解释4个20分,简答题6个30分,分析与论述题2个20分。
选择题几乎都是情景题,题目都很容易,对上面的知识点有大概的了解就可以都做出来。
填空题、名词解释简单背一背重点都可以写出来。
简答题我们考了一个BSI模型的三根支柱是什么,除了这个我没复习到以外,其他的都是课后习题的内容。
分析与论述题:第一个大题考了指针,让你指出代码中的错误,是第三章的课后题,复习的时候没看这个题,感觉亏爆了,不能只复习栈的结构,也要看看数组指针和指针的常见错误。
第二个就有点怪了,题目是:“你本学期做了哪些实验,谈谈你的收获和感悟”。我觉得对新开的课程,每个实验大家还是要亲手做一做,毕竟老师也没什么可出的题,最可能就是从实验和课后题里面找。