一、相关阅读资料

https://github.com/GDSSecurity/PadBuster  PadBuster – Automated script for performing Padding Oracle attacks

http://hi.baidu.com/aullik5/item/49ab45de982a67db251f40f6  道哥的分析

http://www.di-mgt.com.au/cryptopad.html  Padding原则

http://hi.baidu.com/306211321/item/faa44923c3c07d98b7326387  分组密码的链接模式

http://blog.gdssecurity.com/labs/2010/9/14/automated-padding-oracle-attacks-with-padbuster.html  作者写的分析

http://www.cnblogs.com/JeffreyZhao/archive/2010/09/25/1834245.html  老赵写的分析(和ASP.NET结合)

http://www.isg.rhul.ac.uk/~kp/secretIV.pdf  国外的牛牛写的分析(拓展Padding Oracle的知识面)

http://www.icylife.net/yunshu/attachments/Padding-Oracle-Attack.pdf  云舒写的分析

http://netifera.com/research/poet/PaddingOraclesEverywhereEkoparty2010.pdf  EKOPARTY 2010的演讲PPT

http://netsecurity.51cto.com/art/201101/244089_1.htm  51CT上看到的分析

二、前瞻

2.1 分组的填充Padding

分组密码Block Cipher需要在加载前确保每个分组的长度都是分组长度的整数倍。一般情况下,明文的最后一个分组很有可能会出现长度不足分组的长度:

这个时候,普遍的做法是在最后一个分组后填充一个固定的值,这个值的大小为填充的字节总数。即假如最后还差3个字符,则填充0x03.

这种Padding原则遵循的是常见的PKCS#5标准。http://www.di-mgt.com.au/cryptopad.html#PKCS5

2.2 CBC(Cipher Block Chaining CBC)模式

这是一种分组链接模式,目的是为了使原本独立的分组密码加密过程形成迭代,使每次加密的结果影响到下一次加密。这可以强化加密算法的"敏感性",即实现所谓的"雪崩效应"。

三、Padding Oracle Attack攻击的原理

因为Padding Oracle Attack是针对CBC链接模式的攻击,和具体的加密算法无关(分组)。这里选择DES为例进行阐述。

假设明文为:LittleHann(明文长度为10 8 < 10 < 16即使用2个分组)

经过DES加密(CBC模式)后,其密文为:EFC2807233F9D7C097116BB22E813C5E

加密程序:http://pan.baidu.com/s/1e2o7

密文采用了"ASCII十六进制的表示方法",即两个字符表示一个字节的十六进制数。这是因为密码学算法中得到的密文经常会出现不可打印字符,为了保证在网络上传输的正确而不受不同系统间编码方案的影响,就有必要对密文进行"可视化"转化。除了"ASCII十六进制的表示方法"之外,还可以采用"base64编码方法".

注:PHP的DES及其他密码学算法的加密是通过"PHP加密扩展库Mcrypt"来实现的。

http://www.php100.com/cover/php/2651.html

http://baike.baidu.com/link?url=U8OtBP-IcYLRGrfWpSNhHskzrnA0qPNTsIrgGZcZSjLTGBPfpEI35ry51JtAXFxVuVsXKBK_UUZoXbZWgM-xLK

整个加密过程如下:

初始化向量IV与明文(第一组明文)XOR后,再经过运算得到的结果作为新的IV,用于下一分组(分组2),如果迭代下去。

解密过程是加密过程的逆过程:

注意:前几个分组的解密结果对我们都没有意义,我们重点关注的是最后一个分组的解密结果。如下图:

注意到最后一个分组的末尾的数值为0x04,即表示填充了4个Padding。如果最后的Padding不正确(值和数量不一致),则解密程序往往会抛出异常(Padding Error)。而利用应用的错误回显,我们就可以判断出Padding是否正确。

a)在Padding Oracle Attack攻击中,攻击者输入的参数是IV+Cipher,我们要通过对IV的"穷举"来请求服务器端对我们指定的Cipher进行解密,并对返回的结果进行判断。

b)和SQL注入中的Blind Inject思想类似。

c)攻击成立的两个重要假设前提:

1.攻击者能够获得密文(Ciphertext),以及附带在密文前面的IV(初始化向量);
2.攻击者能够触发密文的解密过程,且能够知道密文的解密结果。

d)可能出现的情况

明文分组和填充就是Padding Oracle Attack的根源所在,但是这些需要一个前提,那就是应用程序对异常的处理。当提交的加密后的数据中出现错误的填充信息时,不够健壮的应用程序解密时报错,直接抛出"填充错误"异常信息(这个错误信息在不同的应用中是不同的体现,在web一般是报500错误)。

攻击者就是利用这个异常来做一些事情,假设有这样一个场景,一个WEB程序接受一个加密后的字符串作为参数,这个参数包含用户名、密码。参数加密使用的最安全的CBC模式,每一个block有一个初始化向量IV(注意:这个IV在服务器第一次生成这个密文的时候就产生了,并保存在服务器上,攻击者需要在提交数据的时候也提交这个IV,攻击者实际上就是在"穷举"这个IV)。

当提交参数时,服务端的返回结果会有下面3种情况:

a.参数是一串正确的密文,分组、填充、加密都是对的(程序运行本身没出问题),包含的内容也是正确的(业务逻辑是对的),那么服务端解密、检测用户权限都没有问题,返回HTTP 200.

b.参数是一串错误的密文,包含不正确的bit填充(程序运行本身出现致命错误),那么服务端解密时就会抛出异常,返回HTTP 500 server error.

c.参数是一串正确的密文(程序运行本身没出问题),包含的用户名是错误的(业务逻辑是错的),那么服务端解密之后检测权限不通过,但是依旧会返回HTTP 200或者HTTP 302,而不是HTTP 500。

攻击者无需关心用户名是否正确,只需要提交错误的密文(因为这里有4中变量情况,为了构造出二值逻辑推理,我们要定住其中2个情况,即让业务逻辑恒错,对Bit Padding的情况进行逻辑推理),根据HTTP Code即可作出攻击。

我们继续回到原理上来。假设有这样一个应用http://sampleapp/home.jsp?UID=0000000000000000EFC2807233F9D7C097116BB33E813C5E

(中间用箭头隔开了,前面的16个字母(即8字节ASCII十六进制表示法两个字母为一个字节)为攻击者输入的IV。后面的32个字母(即16字节)为攻击者输入的密文)

我们向服务器发送这样一个请求:

Request: http://sampleapp/home.jsp?UID=0000000000000000EFC2807233F9D7C097116BB33E813C5E
Response: 500 - Internal Server Error

此时在解密时Padding是不正确的(填充的值和填充的数量不一致)

例如:

程序判断Padding是否出错一般是去检验末尾的那个字节的值,这里是0x3D,显然不对。这里我们再次回忆一下Padding原则:

1个字节的Padding为0x01
2个字节的Padding为0x02
3个字节的Padding为0x03
4个字节的Padding为0x04
5个字节的Padding为0x05
6个字节的Padding为0x06
7个字节的Padding为0x07
8个字节的Padding为0x08(当原始的明文正好是分组的整数倍的时候,Padding一个整组的填充值)

也就是说,Padding的值只可能是0x01~0x08之间。

我们接下来要利用密文攻击的思想,不断调整,修正IV。来对Intermediary Value进行猜测。

1) Padding 0x01

我们不断地调整IV的值,以希望解密后,最后一个字节的值为正确的Padding Byte,这里是0x01。因为Intermediary Value是固定的(我们此时不知道Intermediary Value),因此从0x00~0xFF之间,只可能有一个IV的值与Intermediary Value的最后一个字节进行XOR后,结果是0x01(思考:因为0x01只有最后1 bit为1,其他都是0,所以根据XOR的性质,只能存在一个值能XOR得到0x01)。攻击者通过遍历这255个值,可以找出IV需要的最后一个字节。

Request: http://sampleapp/home.jsp?UID=0000000000000066EFC2807233F9D7C097116BB33E813C5E

Respose: 200 OK

通过XOR运算,可以马上推导出此Intermediary Byte的值:

if(Intermediary Byte) ^ 0x66 == 0x01 {Intermediary Byte = 0x66 ^ 0x01 }
so:Intermediary Byte = 0x67

在回过头来看看加密过程:

初始化向量IV与明文进行XOR运算得到了Intermediary Value,因此将刚才得到的Intermediary Byte(0x67)与"真实"的IV的最后一个字节0x0F(攻击者事先获取到的)进行XOR运算,即能得到明文:

0x67 ^ 0x0F = 0x68 : H

即得到明文(第一个分组)的最后一个字母H!

1.我们在得出明文的那次XOR计算中用到的IV(0x0F)和我们攻击者不断"注入"的IV(0x01~0xFF)不是一回事,要区分开来。在计算明文的那个IV(0x0F)是我们事先就获取到的,回想我们之前说的这个Padding Oracle Attack攻击的成立条件:

这个IV(0x0F)是服务器端在发送密文的时候(可能是cookie形式)附带在密文的头部发给我们的。一般情况下,如果跨系统发送这种"带盐"的密文,都要把"盐(IV)"附带在密文的头部或其他位置一起发送给接收方。这里我们接收到的IV就是0x0F,在不同的环境中这个IV必然是不一样的,关键是要理解原理。

2.按理来说,IV不是在服务器第一次生成这段密文的时候就生成好了吗?然后在每次发送的时候都附带在密文的头部,不会再变了....  的确是这样,但这说的是在正常的解密情况下发生的事,而我们攻击者现在做的事并不是在解密(事实上攻击者这个时候也不知道IV和KEY),我们只是在通过不断的修改IV来对目标解密系统进行"试探",从返回的结果来进行"侧信道攻击",从而进行二值逻辑推理。

在正确"匹配"了Padding 0x01之后,需要做的事继续推导出剩下的Intermediary Byte。根据Padding原则,在需要Padding两个字节的时候,其值应该是0x02.

2) Padding 0x02

这个攻击过程是一个循环迭代的过程,上一步的结果就是作为下一步的基础。我们之前已经知道Intermediary Byte的最后一个字节为0x61,因此可以"更新"IV(攻击者输入的IV)的第8个字节为0x66^0x02=0x64.

(思考:这个Padding Oracle Attack的过程中,攻击者需要不断地调整输入IV的值,之前因为在Padding 0x01中,我们只是在假设Padding 0x01的情况,在这个假设下,我们通过得出IV的最后字节,从而计算出Intermediary Byte,进而算出明文的最后一个字节"H"。这里要注意的是,这个假设的IV没有任何意义,只是我们进行"选择密文攻击"过程中的一个路人甲而已。而接下来我们要继续假设Padding 0x02的情况,为了使在假设Padding 0x02中,Intermediary Value的最后一个字节依然为"0x67(之前算出来的)",所以我们要对IV的最后一个字节进行迭代更新:0x66^0x02 = 0x64)。

这个时候,本质上攻击者是固定住了IV的最后一个字节不变,开始循环"盲注"倒数第二个字节。开始依照第一步时的方法对倒数第二个字节进行"盲注"逻辑判断。

Request: http://sampleapp/home.jsp?UID=0000000000007064EFC2807233F9D7C097116BB33E813C5E
Respose: 200 OK

通过遍历可以得出,IV的第7个字节为0x70.

if(Intermediary Byte) ^ 0x70 == 0x02 {Intermediary Byte = 0x70 ^ 0x02 }
so:Intermediary Byte = 0x72

对应的Intermediary Byte为0x72。知道了Intermediary Byte的倒数第二个字节为0x72,就可以得出明文的倒数第二个字节:

0x72 ^ 0x17 = 0x65 : e

(这里的IV:0x17是我们从服务端接收到的附带在密文头部的IV的倒数第二个字节)

接下来,要继续对IV进行推理,同理,这次"选择密文攻击"假设是Padding 0x03,对IV进行迭代更新,然后对IV的倒数第三个字节进行"穷举"循环探测。

Padding 0x03
Padding 0x04
Padding 0x05
Padding 0x06
Padding 0x07
Padding 0x08

最终得到这个分组的明文LittleH。这是第一个分组的明文。

注意,Padding Oracle Attack是以单个分组进行的。到了这一步,我们会发现,我们的攻击目标其实就是那个临时中间值变量Intermediary Value,得到了这个值,再加上我们本来就可以获取到IV(服务器端生成的附在密文头部的那个IV),我们可以通过XOR运算得到这个分组的明文。

对于多个分组的密文来说,我们继续观察一下CBC的解密流程:

第二个分组使用的IV(对于第一组来说是附带在密文头部的那段)是第一组分组的密文。因此我们就把第一组的密文带入第二组的计算中。继续对第二组的Intermediary Value进行逻辑推导,最终得到第二组的密文:ann。

多分组的密文可以以此类推,由此即可以仅根据密文和IV还原出明文。

4.Padding Oracle Attack的攻击利用场景

一旦我们通过暴力破解得到中间值Intermediary Value之后,IV便可以用来生成我们想要的任意值。新的IV可以被放在前一个示例的前面,这样便可以得到一个符合我们要求的,包含两个数据块的密文了。这个过程可以不断重复,这样便能生成任意长度的数据了。

使用PadBuster加密任意的值      https://github.com/GDSSecurity/PadBuster

5.防御方法

Padding Oracle Attack的关键在于攻击者能够获知解密的结果是否符合Padding。在实现和使用CBC模式的分组加密算法时,注意这一点即可。比如加上try catch机制。

6.模拟实验

这是道哥写的python脚本,可以用来模拟实验出Padding Oracle Attack的原理: http://pan.baidu.com/s/1eitwK

记录我对Padding Oracle攻击的分析和思考之抄写相关推荐

  1. 详解ASP.NET的最新安全漏洞,Padding Oracle攻击原理及其他

    微软在9月17日中午正式对外公布了ASP.NET平台下的安全漏洞,即Microsoft Security Advisory (2416728). SecurityFocus上已将此漏洞定义成了&quo ...

  2. Padding Oracle Attack填充提示攻击-渗透测试

    漏洞简介 最近学习了一个shiro的 Critica级漏洞的验证,利用Padding Oracle Vulnerability破解rememberMe Cookie,达到反序列化漏洞的利用,攻击者无需 ...

  3. 第5篇 | Shiro Padding Oracle无key的艰难实战利用过程

    ‍ Part1 前言  大家好,上期分享了银行站的一个Java 的SSRF组合洞案例,这期讲讲分享一个Shiro Padding Oracle漏洞利用过程. Shiro反序列化漏洞自16年公布以来,至 ...

  4. padding oracle attack相关之padding oracle attack

    前段时间遇到一个挺有意思的题目,用到了padding oracle attack的相关知识,于是恶补了一下padding oracle attack相关内容,本着取之于民用之于民同时也可以方便自己以后 ...

  5. shiro 721 反序列化漏洞复现与原理以及Padding Oracle Attack攻击加解密原理

    文章目录 1. 前置知识 1.1 shiro550利用条件 原理 1.2 shiro721利用条件 原理 shiro-721对cookie中rememberMe的值的解析过程 1.3 基于返回包的sh ...

  6. oracle 语法分析表,Oracle 语句优化分析说明

    Oracle 语句优化分析说明 更新时间:2009年09月17日 21:52:20   作者: Oracle 语句优化技巧,大家可以参考使用,使你的oracle运行效率更高更好. 1. ORACLE ...

  7. ORACLE 执行计划分析

    http://www.cnblogs.com/rootq/archive/2008/09/06/1285779.html ORACLE 执行计划分析 一.什么是执行计划 An explain plan ...

  8. Oracle递归查询示例分析

    Oracle递归查询示例分析 start with connect by 层次查询(Hierarchical Queries) 从顶级向下级查询 Select  a.areaid,a.name,a.p ...

  9. 【深度长文】循序渐进解读Oracle AWR性能分析报告

    [深度长文]循序渐进解读Oracle AWR性能分析报告 原创 2016-10-19 韩锋 DBAplus社群 http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEw ...

最新文章

  1. ELK日志服务使用-kafka传输日志(bbotte.com)
  2. wkhtmltopdf:wkhtmltopdf(将html转换成pdf的利器)简介、安装、使用方法详细攻略
  3. Java培训教程分享:变量与常量
  4. android webview loadurl本地,Android WebView 使用loadUrl方法执行本地JavaScript
  5. Java Fork / Join进行并行编程
  6. linux 我的世界 跨平台联机,我的世界跨平台联机 PC、手机等平台数据互通
  7. One2One主键关联的实现
  8. live writer不能首行缩进的问题
  9. 程序员需知的 58 个网站!个个经典
  10. oracle 字符串等于,ORACLE in (字符串,字符串,字符串)
  11. 黑马程序员—黑客与画家——工作3年再转型(附赠大绝招)
  12. 创新数据基础设施打通“数据”瓶颈,成就智慧院区建设
  13. 转 OFBiz财务模型-金融账户
  14. Windows下编译apr、apr-util
  15. 第11章-ThreadSpecificStorage
  16. 弹球打砖块游戏java,Unity 弹球打砖块游戏(简易)
  17. matlab legend颜色不变,关于MATLAB画图中legend标注曲线颜色不匹配问题
  18. 9、Python xlsxwriter模块
  19. Nlp SBD 文本断句 包含中文 和英文断句
  20. SpringCLoud实战微服务之——微服务简介以及入门使用

热门文章

  1. linux 安装tomcat遇到的问题
  2. 蓝桥杯 试题 基础练习 字母图形——13行代码AC
  3. 瞬间带你了解如何优化 Mysql 数据库,老板再也不担心客户投诉了
  4. TCP三次握手四次断开(图解)
  5. 在Web中如何运用JavaScript实现打印功能
  6. cfile 修改某些位_王者荣耀:打野刀效果再次修改,自定义房间配置试运行!
  7. python文件解除占用_如何使用Python解锁锁定的文件和文件夹(mac)
  8. java判断是否是doc文件_java判断文件类型
  9. java委托机制教程_通过反射实现Java下的委托机制代码详解
  10. echarts 雷达图_如何把Echarts用成在线数据可视化工具