2软件安全风险
第二讲软件安全风险
n1.软件安全风险分类
¨软件源代码安全分类
¨WEB安全分类
¨攻击对象分类
¨软件生命周期分类
n2.典型安全风险介绍
本讲目标
理解软件安全到底需要解决哪些问题n了解目前软件中存在的主要问题n
1.1 软件安全风险分类: Gary Mcgraw软件源代码安全分类
对这些安全漏洞的分类目
前有很多种,我们主要采用
McGraw提出的分类方法.将软
件代码中存在的安全漏洞分为
8类,分别是:
•1 输入验证与表示
•2 API误用
•3 安全特征
•4 时间与状态
•5 错误处理
•6 代码质量
•7 封装
•8
环境
软件代码安全问题分类原则--输入验证与表示
ü
ü输入验证和表示问题通常是由特殊字符、编码和数字表示所引起的,这类安全问题的发生是对输入的信任所造成的。一些较严重的安全问题往往都是由于对输入的信息过度信
任造成的,主要问题包括:
输入验证与表示
输入验证与表示
软件代码安全问题分类原则--API误用
üAPI是调用者与被调用者之间的一个约定,大多数的API误用是由于调用者没有理解约定的目的所造成的。举个例子,如果一个程序在调用chroot()后调用chdir()失败,那是因为它违背了约定所指定的如何在安全模式下改变动态root目录。
另一个lib误用的好例子是调用者期望被调用者返回可信的DNS信息,在该例子中,调用者根据自己对API功能的假定(认为它会返回用于验证的值)来调用API,造成了被调用API的误用。üü
API误用
API误用
nAPI误用包括以下方面:
软件代码安全问题分类原则--安全特征
n
ü
软件代码安全问题分类原则--时间与状态分布式计算是与时间和状态有关的。也就是说,为了让多个
部件之间交互,需要状态共享,而这要花费时间。
大多数程序员将他们的工作人格化。他们认为控制器的一个线程会按照他们所想的方式来执行整个程序。然而,现在的计算机能在多任务之间快速切换,采用多核、多CPU或者说分布式系统,两个事件甚至能在同一时间发生。这样一来,在程序员所想的程序执行模式和实际发生的情况之间就会产生问题。这些问题可能涉及到线程、进程、时间和信息之间的非法交互。这些交互通过共享的状态产生:如信号量、变量、文件系统以及任何能够存储信息的东西。
ü
ü
时间与状态
n
包括以下方面:
软件代码安全问题分类原则—错误处理
ü
错误和错误处理代表了一类API。与错误处理有关的错误是很常见的。与API误用相比,和错误处理相关的安全漏洞一般是两种方式造成的:
üü
第一种是根本忘记处理错误或者只是简单的处理,并没有彻底解决第二种则是程序对可能的攻击者泄露了过多的信息或者涉及面太广没有人愿意去处理这些问题。
错误处理
n
包括以下方面:
代码质量
n
低劣的代码质量会导致不可预测的行为。从用户的角度来看,这通常会表现为低劣的可用性。对于攻击者而言,低劣的代码使他们可以以
封装
n
封装就是划定强力的分界线。在web浏览器中,这就意味着你的代码模块不能被其他代码模块滥用。在服务端,这意味着要区分校验过的数据和未经校验的数据,区分不同用户的数据,或者区分用户能看到
软件代码安全问题分类原则—环境
üü
环境包括的内容虽然是源代码之外的,但它们对产品的安全性仍然至关重要。因为其覆盖的内容并不与源代码直接相关,所以我们将它与其他内容分隔开来。环境中可能存在风险例如:
¨不安全的编译器优化(Insecure Compiler Optimization)¨不安全的传输(J2EE Misconfiguration: Insecure Transport)
¨弱访问许可(J2EE Misconfiguration: Weak Access Permissions)
¨配置文件中的密码(Password Management: Password in Configuration File)
1.2 OWASP的WEB安全风险分类
认证(Authentication)n授权(Authorization)
n客户端攻击(Client-side Attacks)n命令执行(Command Execution)n信息泄露(Information Disclosure)n逻辑攻击
n
认证(Authentication)
这一部分的安全威胁涵盖了针对Web应用程序识别用户、服务或应用的方法的攻击。n1.暴力破解(Bruce Force)n2.不充分认证(Insufficient Authentication)
n3.弱口令恢复(Weak Password Recovery Validation)
n
授权(Authorization)
nnnnn
这一部分的威胁涵盖了对判断用户、服务或应用是否具有进行某一请求操作所需要的授权的攻击。1.会话预测(Credential/Session Prediction)2.不充分授权(Insufficient Authorization)3.不恰当的会话超时(Insufficient Session Expiration)
4.会话定置(Session Fixation)
客户端攻击(Client-side Attacks)客户端攻击关注的是来自Web站点用户的滥用和恶意利用。
n1.内容欺骗(Content Spoofing)n2.跨站脚本(Cross-site Scripting)n
命令执行(Command Execution)n
n
n
n
n
n
n
n命令执行所涵盖的攻击是指针对在Web站点上执行远程命令的攻击。1.缓冲区溢出(Buffer Overflow)2.格式化字符串攻击(Format String Attack)3.LDAP注入(LDAP Injection)4.运行操作系统命令(OS Commanding)5.SQL注入(SQL Injection)6.SSI注入(SSI Injection)7.XPath注入(XPathInjection)
信息泄露(Information Disclosure)
n
n
n
n
n信息泄露部分涵盖的是获取Web站点特定系统信息的攻击。特定系统信息包括软件部署、版本、补丁级别,或者是备份和临时文件的存放路径等。大多数情况下,都不需要公开这些信息来满足用户的需求,因此应该尽可能地将这些信息隐藏起来。1.目录索引(Directory Indexing)2.信息泄露(Information Leakage)3.路径递归(Path Traversal)4.可预见的资源位置(Predictable Resource Location)
逻辑攻击
n
n
n
n逻辑攻击部分关注的是对Web应用逻辑的滥用和非法利用。应用逻辑是指执行一个特定动作的过程,如密码恢复、账户注册等都属于应用逻辑。1.功能误用(Abuse of Functionality)2.拒绝服务(Denial of Service)3.不充分的过程验证(Insufficient Process Validation)
1.3根据攻击对象的分类n软件的安全威胁的对象各不相同。拒绝服务攻击是针对软件服务器所在网络的;命令执行的对象是软件服务器所运行的主机、服务器软件等;不充分认证和授权则是针对软件应用的威胁。据此,可以将软件安全威胁划分为网络级、主机级和应用级。
网络级软件安全威胁
构成网络基础结构的主要组件有路由器、防火墙和交换机。它们担当网关守卫的角色,来保护服务器和应用程序不受攻击与入侵。常见的缺陷包括脆弱的默认安装设置、对外开放的访问控制等。主要的网络级威胁包括:
n会话预测
n拒绝服务n
主机级软件安全威胁n
n
n
n
n
n主机威胁主要针对构建应用程序的系统软件,也还可能威胁到架设系统软件的主机,包括操作系统、应用服务器(如IIS、Apache等)和数据库服务器(如SQL Server、Oracle等)。主要的主机级威胁包括:暴力破解拒绝服务跨站脚本命令执行信息泄露
应用级软件安全威胁n
n
n
n
n
n
n应用级威胁的主要攻击对象是Web应用,即这些威胁都是要针对每一个软件应用的不同实现(实现语言、部署方式等)来进行不同的有针对性的攻击。应用级威胁攻击的目标包括获取应用内受保护的信息、破坏应用所能提供的服务、窃取使用同一应用的其他帐号信息等。主要的应用级威胁包括:不充分认证脆弱的密码恢复验证不充分授权会话定置客户端攻击命令执行
1.4 根据软件生命周期的分类n
n
n
n此处所涉及的软件生命周期是指设计、开发和管理配置这三个层面。在这三个层面上,软件安全威胁可以被划分到不同的阶段加以改善、防范或解决。例如,如果在设计阶段,充分考虑了身份验证策略,如使用强密码、支持密码期限和账户禁用等,那么就可以在很大程度上抵御暴力破解的攻击,从而大大降低了暴力破解的成功率。再如,如果在开发编码阶段,制定并实施了详细的安全代码规范,那么就完全可以避免Java代码发生SQL注入攻击示例的情况。在管理配置层面,如果根据实际需要合理配置会话的超时时间就可以避免不恰当的会话超时攻击;而如果注意了Web服务器对于目录索引的缺省配置,那么也就可以避免目录索引攻击的发生
2.典型安全风险介绍
2.1 竞态条件:
n
n竞态条件是指使用应用安全控制和使用该服务之间的时差。由和事件时间相关的意料之外的依赖所导致的反常行为。换句话说,由程序员不正确地假设一个特殊的事件总是在另一个事件之前发生而导致的反常行为。
竞态条件:
n每一个线程竞相在其它线程进入同一关键代码部份前完成它自己的关键代码部份的行为。因为线程的执行顺序是不可知的,所以不能保证一个线程能够在其它线程进入关键代码部份前完成它自己的关键代码部份。因此,我们会有竞态条件引起不一致。
要阻止竞态条件,每一个线程必须在其它线程进入同一关键代码部份或其它操作同一共享变量或资源的相关关键代码部份前完成它自己的关键代码部份。n
竞态条件
竞态条件发生在以下三种情况:
1.静态数据库连接:p
n问题:在静态域中存储的数据库连接会在多个线程间共享。
说明:一个事务资源对象,如数据库连接,一次只能与一个事务关联。因此,一个连接不应该在线程间共享,也不应该存储在一个静态域中。n
竞态条件
2.文件访问
文件访问的竞态条件发生在:
n1)程序校验文件的属性,通过名字来引用文件。n2)程序随后用同一个文件名进行文件操作,认为文件仍然保持之前校验过的属性。n利用校验文件属性和使用文件之间的时间差可以进行权限扩大攻击。
竞态条件—实例
n实例1:面的代码来自于一个setuidroot的程序。程序允许没有特权的用户进行某些文件操作,为了防止用户利用程序的root权限来进行未经授权的操作,程序在打开文件进行操作前,会调用access()来校验用户是否有权限去访问指定文件。
if(!access(file,W_OK)) {
f = fopen(file,
operate(f);
...
}
else {
fprintf(stderr,
}
竞态条件—实例n实例说明:
ü若运行程序的用户有权限去写文件,access()会返回0,否则返回-1。然而由于access()和fopen()都是对文件名而不是对文件句柄进行操作,所以并不能保证access()和fopen()所用file变量是指向同一个文件。如果攻击者在调用access()后将file替换为指向另一个文件的符号链接,那么即使这个文件不允许攻击者修改,程序也会利用root权限对该文件进行操作。通过欺骗程序让它进行不被允许的操作,攻击者获得了更高的权限。
这种攻击并不仅限于有root权限的程序,如果一个应用程序可以进行攻击者不被允许的操作,那么它就有可能成为攻击者的目标。这种攻击的原因是校验文件的时间和使用文件的时间之间存在间隔。即使在校验之后立即使用,现在的操作系统也不能保证CPU会立即执行。攻击者有各种技术可以用来延长此时间间隔,但即使是很小的时间间隔,攻击者也可以反复尝试攻击,直到成功为止。üüü
竞态条件
3.单独的成员域
n问题简介:Servlet成员域可能允许一个用户看到另一个用户的数据。
说明:很多Servlet开发者并没有认识到:只有当一个Servlet实现了SingleThreadModel接口时,这个Servlet才是单独的。否则只会有一个Servlet实例,这个Servlet实例被反复使用,用来处理不同线程同时进行的多个请求。这种误解所造成的一个常见的后果就是开发者在使用Servlet成员域的时候,一个用户可能会在不经意间看到另一个用户的数据。换句话说,将用户数据存储在Servlet成员域中会导致数据访问的竞态条件竞争条件。nn
竞态条件—实例
n实例1:下面的Servlet将一个请求的参数值存储在成员域中,然后在响应输出流中将该参数值输出。public class GuestBookextends HttpServlet{String name;
protected void doPost(HttpServletRequestreq,
HttpServletResponseres) {
name = req.getParameter(
...
out.println(name+
}
}
竞态条件—实例
n在单用户环境下该代码可以完美的运行,但是如果在差不多同一时间有2个用户访问这个Servlet,那么处理这2个请求的线程很可能以如下方式工作:
Thread 1: 分配
Thread 2: 分配
Thread 1: 打印
Thread 2: 打印
这样就把第2个用户的名字显示给了第1个用户。
2.2 HTTP应答截断(HTTP Response
Splitting)
Ø问题简介:
在HTTP响应头中包含未经验证的数据将可能导致缓存中毒(cache-poisoning)、跨站脚本(cross-site scripting)、跨用户攻击(cross-user defacement)或者页面劫持(page hijacking)攻击。
ØHTTP应答截断攻击发生在:
•数据通过一个非可信源进入web应用程序,最可能的是通过HTTP请求。
•包含在HTTP响应头中发送给web用户的数据没有对恶意字符进行验证。
Ø与很多软件安全攻击一样,HTTP响应截断是一种达到目的的手段,它本身并不是目的。起初,这种攻击很简单:攻击者传递恶意数据给有漏洞的应用程序,应用程序将这些数据包含在HTTP响应头中。
Ø要想成功地使用该攻击,应用程序必须允许响应头中包含CR(回车,即%0d或者\r)和LF(换行,即%0a或者\n)字符。这些字符不仅使得攻击者可以控制应用程序发送的部分响应头和响应体,还使得攻击者可以创建能够完全控制的HTTP响应。
Ø在HTTP响应头中包含未经验证的数据,将可能导致:
•缓存中毒(cache-poisoning)
•跨站脚本(cross-site scripting)
•跨用户攻击(cross-user defacement)
•页面劫持(page hijacking)
Ø攻击者可以制作一个专门的请求发给有漏洞的服务端,服务端将会创建两个响应,第二个响应会被误解为是另一个请求的响应,这个请求是由使用同一个TCP连接访问服务端的另一个用户发来的。
Ø当攻击者诱使用户自己提交恶意请求时,或者更隐蔽的,当攻击者与用户共用同一个TCP连接到服务端(比如共享的代理服务)时,就可以完成上述攻击。最好的情况下,攻击者可以通过这种攻击使用户认为应用程序已经被修改了,导致用户对应用程序的安全性失去信心。最糟的情况下,攻击者可以模仿应用程序,提供相似的内容,诱使用户将私有信息(如账号和密码)发送给攻击者。
Ø一旦攻击者可以控制应用程序发送的响应,他们就可以选择各种恶意内容来提供给用户。
Ø跨站脚本是最常见的攻击,它在用户浏览器上执行响应中包含的恶意JavaScript或者其他代码。基于XSS的攻击种类几乎是无限的,但是它们通常会包括:传送私有数据(如cookies或者其他session信息)给攻击者,将受害者的浏览器重定向到攻击者所控制的web内容中,或者假借有漏洞的站点在用户机器上进行其他恶意操作。
Ø针对一个有漏洞的应用程序的用户,最常见的也是最危险的攻击方式是通过JavaScript将session和认证信息发送给攻击者,使得攻击者能够完全控制受害者的账号。
Ø除了通过有漏洞的应用程序来发送恶意内容给用户以外,这种攻击还能够将服务端生成的要发送给用户的敏感内容重定向给攻击者。Ø攻击者通过一个请求生成两个响应,一个是服务端原有的响应,一个是攻击者制造的响应。然后攻击者通过一个中间节点,如共享的代理服务,将服务端产生的发给用户的响应指向攻击者。因为攻击者制造的请求产生了两个响应,第一个作为攻击者请求的响应,第二个会保留在响应池中。当用户通过同一个TCP连接提出HTTP请求时,由于攻击者制造的响应已经存在,所以该响应会被当作用户的响应发送给用户。然后攻击者发送第二次请求给服务端,此时代理服务器就会把服务端生成的原本要发给用户的响应当作攻击者的响应发送给攻击者,这样攻击者就能从该响应中获取危及用户安全的敏感信息。
ü实例:下面的代码段从HTTP请求中读取一篇博客文章的作者名author,然后将它放入HTTP响应的cookie头。
ü假如在HTTP请求中提交的字符串是由标准的文字和数字字符组成,如“Jane Smith”,那么HTTP响应中包含的cookie可能是如下
形式:
ü然而,因为cookie的值是根据未经验证的用户输入生成的,所以只有当提交的Author.Text的值中不包含任何CR和LF字符时,HTTP响应才会是以上形式。如果攻击者提交了一个恶意字符串,比如“Wiley Hacker\r\nHTTP/1.1 200 OK\r\n...”,那么HTTP响应将被分割为如下两个响应:
ü显然,第二个响应是由攻击者完全控制的,它能够构成任何攻击者想要的响应头和响应体。这种攻击者可以构造任意HTTP响应的能力可以导致各种攻击
说明:
n
n造成http响应头截断漏洞的主要原因是对用户提交的非法字符没有进行严格的过滤,尤其是CR,LF字符的输入。攻击者通过发送一经过精心构造的request,迫使服务器认为其返回的数据是两个响应,而不是常规的一个响应。当可以通过精心制作的request完全控制第二个响应时,可以通过这样来实现攻击:
发送两个请求A,B。A请求包含构造数据,该请求致使服务器返回两个响应R1,R2,其中R2是可以通过在A中的精心构造而完全控制的。服务器将R1作为response返回给A,而第R2则被服务器作为B的response而返回给了B﹙即使R2并不是服务器自己生成的)。
RequestA------------->WebServer(R1,R2)RequestB------------->WebServer(本该是R3)WebServer(R1)------------>AWebServer(R2)————>B
解决方案:
n要想进行HTTP响应截断攻击,应用程序必须允许响应头中包含CR(回车,即%0d或者\r)和LF(换行,即%0a或者\n)字符。所以我们可以在数据进入应用程序之前把可能的危险拦截,针对CR和LF字符进行过滤。