目录
简介:
由于在执行过程中存在错误,即使精心设计的验证机制也可能非常不安全。这些错误可能导致信息泄露、完全避开登录, 或者使验证机制的总体安全弱化。
与保密性不强的密码和可被蛮力攻击之类的设计缺陷相比, 执行缺陷往往更加细微, 更难以发现。由于大量威胁模型和渗透测试可能已经发现了最为注重安全的应用程序中的任何明显的执行缺陷,针对这类缺陷实施攻击通常会取得更大的成果。
1.1、故障开放登录机制
简述:
故障开放逻辑是一种逻辑缺陷,如果验证机制中出现这种缺陷就会造成十分严重的后果。
故障开放登录机制实例,如果由于某种原因, 调用db.getUser()产生异常(例如,因为用户的请求中没有用户名或密码参数), 用户仍然可以成功登录。虽然产生的会话可能并不属于某个特殊的用户,因此无法执行其全部功能,但攻击者仍然可以通过这种方法访问一些敏感数据或功能
public Response checkLogin(Session session) {
try{
String unme=session.getParameter("usernme");String passwd= session.getParameter("passwd");
User user= db.getUser(uname, passwd);
if (user==null){
//证书无效
session.setmessage("Loginm failed");
return doLogin(session);
}
}
catch (Exception e) { }
//有效用户
session.setmessage("Login successful");
return doMainMenu(session);
}
不能指望这样的代码通过即使是最简单的安全审查, 在更复杂的机制中很可能存在概念相同的缺陷。这些机制会产生大量分层方式调用,可能会出现许多潜在的错误并在不同的位置对它们进行处理, 其中更复杂的确认逻辑可能需要维护重要的登录进展状态。
过程:
1、使用控制的一个账户执行一次完整、有效的登录。使用拦截代理服务器记录提交的每一份数据、收到的每一个响应
2、多次重复登录过程, 以非常规方式修改提交的数据。对于客户端传送的每个请求参数或cookie
A、提交一个空字符串值;B、完全删除名/值对;C、提交非常长和非常短的值;D、提交字符串代替数字或相反;E、以相同和不同的值,多次提交同一个数据项
3、仔细检查应用程序对提交的每个畸形请求的响应, 确定任何不同于基本情况的差异
4、根据这些观察结果调整测试过程。如果某个修改造成行为改变, 设法将这个修改与其他更改组合在一起, 使应用程序的逻辑达到最大限度
1.2、多阶段登录机制中的缺陷
简述:
一些应用程序使用精心设计的多阶段登录机制
输入用户名和密码
响应一个质询, 答案是PIN中的特殊数字或值得纪念的
提交在不断变化的物理令牌的值
多阶段登录机制旨在提高基于用户名和密码的简单登录模型的安全性。多阶段登录机制订先要求用户通过用户名或类似数据项确认自己的身份,随后, 登录阶段再执行各种验证检查。这种机制常常存在安全漏洞, 特别是各种逻辑缺陷
注:执行多次验证检查可能会显著提高登录机制的安全性。但与此同时,这个过程也存在更多的执行缺陷。如果一个多阶段登录机制存在多个执行缺陷, 它甚至还没有基于用户名和密码的正常登录安全
缺陷假设1:
在执行过程中,一些多阶段登录机制对用户与早先阶段的交互做出潜在不安全的假设
1、应用程序可能认为访问第三阶段的用户已经完成第一、二阶段的验证。因此,它可能允许直接由第一阶段进入第三阶段并且提供正确证书的攻击者通过验证, 使仅拥有部分正常登录所需的各种证书的攻击者能够成功登录
2、应用程序可能会信任由第二阶段处理的一些数据, 因为这些数据已经在第一阶段得到确认。但是, 攻击者能够在第二阶段操控这些数据, 提供一个不同于第一阶段的值。
例如,在第一阶段, 应用程序会判定用户的账户是否已经过期、被锁定或者属于管理用户, 或者是否需要完成第二阶段以外的其他登录阶段。如果攻击者能在不同登录阶段的转换过程中干扰这些标记, 他们就可以更改应用程序的行为, 让他们只需部分证书即可通过验证, 或者提升其权限
3、应用程序可能认为每个阶段的用户身份不会发生变化, 所以它并不在每个阶段明确确认用户身份。
例如, 第一阶段可能需要提交一个有效的用户名和密码, 第二阶段需要重新提交用户名(此时保存在总藏表单字段中)和不断变化的物理令牌上的一个值。如果攻击者在每个阶段提交有效的数据对, 但这些数据属于两个不同的用户, 那么应用程序可能会允许该用户通过验证,认为他是两名用户中的任意一名用户。这就允许拥有自己物理令牌并发现其他用户密码的攻击者能够以该用户的身份登录。虽然不对其他信息加以利用, 攻击者无法完全攻破登录机制, 但它的总体安全状态已严重削弱,应用程序为执行二元机制所投人的大量开支和努力并未取得预期的效果。
过程:
1、使用控制的一个账户执行一次完整、有效的登录。使用拦截代理服务器记录向应用程序提交的每一份数据
2、确定各个不同登录阶段以及在每个阶段收集到的数据。确定是否不止一次收到某条信息, 或者是否有信息被返回给客户端, 并通过隐藏表单字段、cookie或者预先设置的URL参数重新提交
3、使用各种畸形请求多次重复登录过程:
A、尝试按不同的顺序完成登录步骤;B、尝试直接进入任何特定的阶段, 从那里继续登录;C、尝试省略每个阶段并从下一阶段继续登录;D、联想其他任何登录阶段尝试
4、如果有数据不止提交一次, 尝试在另一个阶段提交一个不同的值, 看看是否仍然能够成功登录。有些提交数据可能是多余的, 实际上并不由应用程序处理。有些数据在某个阶段得到确认, 随后就被应用程序所信任。
在这种情况下, 尝试在一个阶段提供一名用户的证书(用户名和密码), 然后在下一阶段转换成由另一名用户进行验证(用户名和PIN)。应用程序可能在几个阶段都对同一个数据进行确认, 但执行不同的检查。
5、注意任何通过客户端传送、并不由用户直接输入的数据。应用程序可能使用它们保存登录进展状态信息, 并且信任这些数据。
例如, 如果第三个阶段的请求中包含参数stage2complete=true,那么攻击者就可以通过设置这个值直接进入第三个阶段。尝试修改应用程序提交的值, 确定是否可以使用这种方法进入或省略登录阶段
缺陷假设2:
一些登录机制在其中一个登录阶段提出一个随机变化的问题。例如, 提交用户名和密码后应用程序会向用户提出许多“机密” 问题中的一个(关于用户母亲的姓、出生地、小学名称等), 或者要求其提交一个机密短语中的两个随机字母。采用这种做法的基本原理在于,即使攻击者截获了用户在某个时候输入的全部信息, 他也无法在其他时刻作为该用户登录, 因为这时应用程序将提出不同的问题
在某些执行过程中, 这种功能会遭到破坏, 因而无法实现其目的
1、应用程序可能会提出一个随机选择的问题, 把有关问题的细节保存在隐藏的HTML表单字段中, 而不是服务器上。随后用户提交该问题及其答案。这样, 攻击者就能够选择回答哪个问题. 允许他们截获用户在某个时候的输入后, 重复使用截获的信息进行登录
2、应用程序可能会对每个登录尝试提出一个随机选择的问题, 但如果某个用户无法回答该问题,它并不记住向该用户提出了什么问题。如果该用户稍后又提交一次登录尝试, 应用程序又生成另一个随机问题。这允许攻击者遍历所有问题、直到收到他们知道答案的那个问题从而利用在某个时候载获的用户输入重复进行登录
过程:
1、如果一个登录阶段使用一个随机变化的问题, 确定问题本身是否和回答一起提交。如果是这样, 改变这个问题并提交正确答案, 看看是否仍然能够成功登录
2、如果应用程序并不允许攻击者提交任意问题和答案,用同一个账户进行部分登录, 每次进行到出现不同的问题为止。如果每次都出现不同的问题, 那么攻击者仍然能够选择回答哪个问题。
注:应用程序可能会设置一个持久性cookie,确保向特定用户提出问题, 直到该用户正确回答问题。此时,攻击者需修改或删除这个cookie就能够避开这种防御措施
1.3、不安全的证书存储
简述:
如果应用程序以不安全的方式存储登录证书, 那么即使验证过程本身并不存在缺陷, 登录机制的安全也会被削弱。Web应用程序常常以危险的方式将用户证书存储在数据库中, 这包括以明文形式存储密码
即使使用MDS或SHA等标准算法对密码进行散列处理, 攻击者仍然可以在预先计算的散列值数据库中查找观察到的散列。因为应用程序使用的数据库账户必须能够随时读/写这些证书,攻击者可以利用应用程序中的许多其他漏洞访问这些证书, 例如, 命令、SQL注入漏洞
过程:
1、分析应用程序中所有与验证有关的功能以及任何与用户维护有关的功能。如果发现任何向客户端返回用户密码的情况, 即表明应用程序并未以安全的方式保存密码, 或者密码以明文方式呈现, 或应用程序使用了可还原加密形式保存密码
2、如果发现应用程序中存在任何一种任意命令或查询执行漏洞,设法确定应用程序将用户证书保存在数据库或文件系统的什么位置。
A、找到这些位置, 弄清应用程序是否以非加密形式保存密码
B、如果以散列形式存储密码, 则应检查表明账户分配有常用或默认密码, 以及散列并未经过“加salt"处理的非唯一值
C、如果使用标准算法以“不加salt的散列” 形式存储密码, 则应查询在线散列数据库,以确定对应的明文密码值