padding oracle攻击原理分析(附带rsa资料)

本文深入探讨了padding oracle攻击的原理,重点分析了在RSA加密中如何利用这种攻击。内容包括四种分组加密方式及填充规则,以及在CBC模式下如何通过错误的padding判断和猜解明文。文章提供了测试代码和通用POC,帮助读者更好地理解和实践padding oracle攻击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前引

最近恶补各种加解密。。把之前学的笔记放一放,本来还想放放自己的rsa笔记,不过这里有一份更好的了,我自己的就不拿出来了。

flappypig rsa:http://bobao.360.cn/learning/detail/3058.html?from=groupmessage&isappinstalled=0

另外这个oj https://www.jarvisoj.com上加上sctf2016都有比较典型的rsa的题目,比较好练手。

另外有个推荐的博客http://bluereader.org/rss/12594/p-1,这个是比较系统的讲了rsa,很不错,理论比上面flappypig那个讲的详细些,逻辑性更强,要是flappypig的暂时看不懂的话可以先看这个再去看那个。

1.1 四种分组加密方式及padding

http://www.cnblogs.com/happyhippy/archive/2006/12/23/601353.html

简单总结下:

其中提到填充方法,以分组8个字节为例:需要填充n个字节,则n个字节都填充0x0n。如果恰好全满,填充8个0x08组成新块。OFB和CFB不需要填充。

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

这里写图片描述

而这个类似二分盲注的思想,因为明文是看不到的,但是明文解密失败是会有反应的。比如在web应用中,如果Padding不正确,则应用程序很可能会返回500的错误(程序执行错误);如果Padding正确,但解密出来的内容不正确,则可能会返回200的自定义错误(这只是业务上的规定),所以,这种区别就可以成为一个二值逻辑的“注入点”。

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

所以攻击成立两个重要的前提

  1. 攻击者能够获得密文(Ciphertext),以及附带在密文前面的IV(初始化向量)

  2. 攻击者能够触发密文的解密过程,且能够知道密文的解密结果

1.2 猜解明文

根据之前的分析,padding只可能有以下几种情况:


1个字节的Padding0x01
2个字节的Padding0x02
3个字节的Padding0x03
4个字节的Padding0x04
5个字节的Padding0x05
6个字节的Padding0x06
7个字节的Padding0x07
8个字节的Padding0x08(当原始的明文正好是分组的整数倍的时候,Padding一个整组的填充值)

cbc解密模式图如下:

这里写图片描述

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

1.2.1 padding 0x01

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

即我们可以控制iv,然后我们能够知道原本正确的iv是啥,然后我们只需要构造iv使得明文解出来是0x01就行了,这样就推到了中间值,加上我们知道正确的iv,异或一下就能够得到第一组明文的最后一个字节的了:


Intermediary Value ^ iv = 0x01

这个iv是我们通过尝试不断构造的,这样子推出了Intermediary Value,那么之前说了我们掌握了真正的iv,这样子就能够知道最终的明文了
1.2.2 padding 0x02

通过上述操作我们能够知道第一个字节,假设为0x??,因此可以”更新”IV(攻击者输入的IV)的第8个字节为0x?? ^ 0x02,然后开始随机构造iv的倒数第二个字节,直至解密出来的第一个分组的倒数第二个字节为0x02,此时的iv异或上0x02之后再和正确iv的倒数第二个字节异或,即可得到明文的第一分组的倒数第二个字节。

至于padding 0x03,0x04…..就不再赘述了。

二、测试代码

这里我自己写了个简单的服务器测试了下,写的比较挫,只是帮助自己更好的理解下原理。。然后自己写了poc。写的非常难看,大家将就着看,另外把自己的草稿也保留在其中了。

服务端代码:


<?php

$string = 'bendawang';

$key = '12345678';

$cipher = MCRYPT_DES;

$modes = MCRYPT_MODE_CBC;

/*



#cipher:01af3d443c84ae0d859755ee9b3e2933

#iv:38b740ea94706e9b



$iv=hex2bin("38b740ea94706e9b");

#iv=hex2bin($_GET['$iv']);

#$i
### Padding Oracle 攻击CTF竞赛中的应用 Padding Oracle 攻击是一种针对加密模式(如CBC模式)的安全漏洞利用技术。它通过观察解密过程中的错误反馈来逐步恢复明文数据。以下是关于该攻击的一些核心概念及其在CTF竞赛中的典型题目解析。 #### 1. 基本原理 Padding Oracle 攻击的核心在于利用目标系统的错误响应机制。如果服务器能够区分填充错误和其他类型的解密失败,则可以将其作为Oracle用于推断消息的内容[^2]。这种攻击通常发生在AES-CBC等分组密码模式中,其中最后一个字节表示填充长度。 #### 2. Java框架下的实现细节 在基于Java的应用程序中,`javax.crypto.BadPaddingException` 是一种常见的异常类型,当解密后的数据不符合预期的PKCS#7填充标准时会被触发。此行为可被攻击者用来判断特定条件是否成立,从而泄露部分信息。 #### 3. 实际案例分析 - SESS Cookie篡改 在一个具体的Web安全场景里,假设存在一个网站允许用户登录并存储其会话状态于名为“SESS”的HTTP-only cookie之中。如果开发者未正确处理输入验证逻辑或者暴露过多调试信息给客户端的话,那么就可能存在Padding Oracle风险点。此时,参赛选手可以通过修改本地保存下来的cookie值并向服务端发送请求的方式来测试不同情况下返回的结果差异,最终达到伪造管理员身份的目的[^4]。 ```python import requests def padding_oracle_attack(url, ciphertext): block_size = 16 # 初始化变量 plaintext = b"" for i in range(len(ciphertext), 0, -block_size): current_block = ciphertext[i-block_size:i] intermediate_values = bytearray([0]*block_size) prefix_padding = bytes([0]*(block_size-(len(plaintext)%block_size))) for j in reversed(range(block_size)): target_byte_value = (block_size-j)^prefix_padding[j]^intermediate_values[j] found_char = False for guess in range(256): modified_ciphertext = list(current_block[:j]) + \ [(current_block[j]^target_byte_value^guess)] + \ list(intermediate_values[(j+1):]) response = send_request_with_modified_cipher(url, bytes(modified_ciphertext)+ciphertext[i:]) if is_valid_padding(response): intermediate_values[j] = guess ^ target_byte_value guessed_plaintext_character = intermediate_values[j]^((block_size-j)) plaintext += chr(guessed_plaintext_character).encode('latin-1') break return plaintext[::-1].decode() def send_request_with_modified_cipher(base_url, new_cipher_text): cookies={"SESS":new_cipher_text.hex()} r=requests.get(base_url,cookies=cookies) return r.status_code,r.text def is_valid_padding(http_response): status_code,content=http_response return 'BadPadding' not in content and str(status_code)[0]=='2' ``` 上面展示了一个简单的Python脚本来模拟如何执行一次完整的padding oracle attack流程。 #### 4. 练习平台推荐 对于希望深入学习此类技巧的人来说,Jarvis OJ 提供了一系列高质量练习题,其中包括但不限于SCTF2016赛事里的某些经典RSA挑战项目[^3]。这些资源非常适合初学者入门以及中级玩家提升技能水平。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值