目录
1.1、简介:
所有Web应用程序都通过逻辑实现各种功能,即用编程语言编写代码就是把一个复杂的进程分解成一些非常简单而又相互独立的逻扣步骤。将一项对人类有用的功能转换成一系列计算机能够执行的细微操作, 需要掌握大量的技巧并进行周密的安排。顺利、安全地完成任务,如果由背景各不相同的开发者与程序员并行开发同一个应用程序, 那么在这个过程中可能会发生很多错误
在所有即使是非常简单的Web应用程序中, 每个阶段都会执行数目庞大的逻辑操作。这些逻辑代表着一个复杂的受攻击面,从未消失, 但往往被人们忽略。许多代码审查与渗透测试主要针对常见的"头条"式漏洞, 如SQL注入和跨站脚本, 因为它们具有容易辨别的签名, 人们对它们的利用方法也进行了广泛的研究。相反, 应用程序的逻辑缺陷更难以辨别:每一种缺陷似乎都是唯一的, 通常自动漏洞扫描器也无法发现它们。因此它们并未受到应有的重视与关注
1.2、逻辑缺陷的本质
简述:
1、Web应用程序中的逻辑缺陷各不相同(包括代码中的简单错误, 以及几种应用程序核心组件互操作方面的极其复杂的漏洞)有的缺陷非常明显,很容易发现,但有些缺陷可能极其饭妙, 能够避开最为严格的代码审计或渗透测试。
2、与SQL注入或跨站脚本漏洞不同,逻辑缺陷没有共有的"签名"。当然, 定义特性是指应用程序执行的逻辑存在某种缺陷。有时逻辑缺陷表现为开发者在思考过程中做出的特殊假设存在明显或隐含的错误。即程序员可能没有考虑到假设以外的情形,在许多情况下, 这种错误的假设会选成大让的安全漏洞。
3、防范常见Web应用程序漏洞的意识已经增强, 一些漏洞的出现几率与严重程度也显著降低。但鉴于逻辑缺陷的本质, 即使是实施安全开发标准、使用代码审查工具或常规渗透测试,仍然无法避免这种缺陷。逻辑缺陷的多样性本质, 以及探查与防止它们往往需要从各个不同的角度思考问题,预示背在很长一段时期内, 逻辑缺陷仍将大量存在。因此攻击者会特别注意目标应用程序采用的逻辑方式,设法了解开发者做出的可能假设,然后考虑如何攻破这些假设
2.1、示例1:征求功能
说明:
应用程序实施"记住密码"功能, 允许应用程序在浏览器中设置一个永久cookie, 用户从而无须登录即可访问应用程序。这个cookie受到一个加密算法的保护,以防止篡改或披露。该算法基于一个由姓名、用户ID和不定数据组成的字符串,以确保合成值是唯一的,并且无法预测。为确保能够访问该cookie的攻击者无法实施重放攻击, 应用程序还收集机器专用的数据,包括1P地址。
于是, 这个cookie被视为一个可靠的解决方案, 用于保护业务功能中易受攻击的部分。
除“记住密码” 功能外,应用程序还具有另一项功能, 将用户的昵称存储在一个名为ScreenName的cookie中,在用户下次访问该站点时,就可以在站点的角落位置收到个性化的问候。鉴于这个名称也属于安全信息, 因此也应对它进行加密。
设计:
开发者认为,与RememberMe cookie相比,ScreenName cookie对攻击者而言价值不大,于是决定使用相同的加密算法来保护这两个cookie,但因为用户可以指定自己的昵称, 并在屏幕上查行该名称。这在无意间使用户能够访问用于保护永久身份验证令牌RememberMe的加密功能(及加密密钥)
攻击:
在一个简单的攻击中, 用户提交其RememberMe cookie的加密值来替代加密的ScreenName cookie,在向用户显示昵称时, 应用程序将解密该值, 如果解密成功, 将在屏幕上显示结果。这
个过程生成消息问题在于, 用户能够指定他们的昵称。因此用户可以选择自己的昵称
如:
admin|11111|192.168.190.131,值
如果用户退出系统然后重新登录, 应用程序就会加密这个价, 将它作为加密的ScreenName cookie存储在用户的浏览器中,如果攻击者提交这个加密的令牌, 将它作为RememberMe cookie的值, 应用程序就会解密该cookie,读取用户ID并让攻击者以管理员身份登录。即使应用程序采用三重DES加密, 使用强大的密钥并阻止重放攻击, 攻击者仍然可以将应用程序作为"加密提示" ,以解密并加密任意值
过程:
这种类型的漏洞表现在许多不同的情况下, 包括账户恢复令牌、基于令牌访问经过验证的资源、向客户端发送的需要防篡改或对用户不可读的任何其他值
1、在应用程序中查找任何使用加密(而非散列)的位置。确定任何应用程序加密或解密用户提交的值的位置,并尝试替代在应用程序中发现的任何其他加密值。尝试在应用程序中导致可以揭示加密值, 或可以在屏幕上“有意” 显示加密值的错误
2、确定应用程序中可以通过提交加密值导致在响应中显示对应的解密值的位置,以查找"提示"漏洞,确定这种漏洞是否会导致敏感信息泄露。
3、确定可以通过提交明文值导致应用程序返回对应的加密值的位置,以查找“提示加密”漏洞。确定是否可以通过指定任意值,或应用程序将会处理的恶意有效载荷, 对这种漏洞加以利用。
2.2、示例2:修改密码功能
说明:
应用程序为终端用户提供密码修改功能,并要求用户填写用户名、现有密码、新密码与确认新密码字段
应用程序为管理员提供密码修改功能,允许他们修改任何用户的密码,而不必提交现有密码
这两项功能在同一个服务器端脚本中执行
设计:
应用程序为用户和管理员提供的客户端界的不同:在管理员界面中没有用于填写现有密码的字段。当服务器端应用程序处理密码修改请求时, 它通过其中是否包含现有密码参数确定请求是来自管理员,还是来自普通用户,即它认为普通用户总会提交现有密码参数
攻击:
确定开发者设计后,逻辑缺陷变得非常明显,普通用户也可以提交并不包含现有密码参数的请求, 因为用户控制着他们提出的请求的每一个方面。这种逻辑缺陷可能给应用程序造成巨大破坏。攻击者可利用这种缺陷重新设置任何用户的密码, 完全控制他们的账户
过程:
1、在关键功能中探查逻辑缺陷时, 尝试轮流删除在请求中提交的每一个参数, 包括cookie、查询字符串字段与POST数据项
2、既要删除参数名称, 也要删除参数值,(不要只提交一个空字符串,因为服务器会对这种字符串另做处理)
3、一次仅攻击一个参数, 确保到达应用程序中所有与参数有关的代码路径。
4、如果控制的请求属于多阶段过程, 一定要完成整个过程, 因为后面的一些逻辑可能会处理在前面的步骤中提交并在会话中保存的数据
2.3、示例3:直接结算功能
说明:
下订单的步骤:
(1) 浏览产品目录并往购物车中添加商品
(2) 返回购物车并最终确认订单
(3)输入支付信息
(4)输入交货信息
设计:
开发者认为用户总会按预定的顺序执行每一个步骤,因为这是应用程序通过显示在浏览器中
的导航链接和表单向用户提供的处理顺序。因此认为任何完成订购过程的用户一定已经提交了令人满意的支付信息
攻击:
用户控制着他们向应用程序提出的每一个请求, 因此能够按任何顺序访问订购过程的每一个阶段。如果直接从第2步进入第4步,可生成一个最终确定交货但实际上并未支付的订单。
过程:
通过强制浏览发现并利用这种缺陷, 包括避开浏览器导航对应用程序功能访问顺序实施的任何控制
1、如果一个多阶段过程需要按预定的顺序提交一系列请求, 尝试按其他顺序提交这些请
求。尝试完全省略某些阶段、几次访问同一个阶段或者推后访问前一个阶段2、各阶段的结果可通过一系列指向特殊URL的GET或POST请求进行访问,或者需要向同一个URL提交不同的参数。被访问的阶段可通过在被请求的参数中提交功能名称或索引来指定,确保完全了解应用程序访问特殊阶段所使用的机制
3、根据执行功能的情形,试图了解开发者做出的假设及主要受攻击面位于何处。设法找到违反这些设计,从而在应用程序中造成反常行为的方法
4、如果不按顺序访问多阶段功能, 应用程序常常表现出一系列异常现象, 如变址值为空字符或未被初始化、状态仅部分定义或相互矛盾以及其他无法预料的行为。应用程序可能会返回有用的错误消息与调试结果,充分了解其内部机制并对当前或其他攻击进行优化。应用程序可能会进入一种完全出乎开发者意料的状态, 导致严重的安全缺陷