DFA攻击背景介绍

传统的密码安全性分析环境被称为黑盒攻击环境,攻击者只能访问密码系统的输入与输出,但随着密码系统部署环境的多样化,该分析模型已经不能够反映实际应用中攻击者的能力。2002年,Chow等人[1]提出了白盒攻击环境的概念,该攻击环境中的攻击者对算法运行环境具备完全的控制权,并且完全掌握算法的设计细节。白盒攻击环境中攻击者的能力包括但不限于:动态观测算法程序运行过程、修改算法程序运行过程中的中间值、对算法程序进行调试分析等,其中包括了差分计算分析(DCA)。

差分计算分析(DCA):DCA不需要攻击者掌握算法的设计细节,只需要采集算法程序在运行过程的中间状态,通过相应的统计分析方法提取密钥。DCA分析只需要掌握白盒实现的底层算法,能够监测白盒实现程序的运行过程即可进行分析,极大地降低了分析的部署难度。

与DCA相似的,Sanfelix,Mune和de Haas在BlackHat Europe 2015上成功提出了针对相同白盒挑战的差分故障分析(DFA)攻击,也就是我们今天要研究的差分故障分析攻击。在大部分白盒攻击模型中,故障非常容易执行且成本低廉,并且不会导致程序自我毁灭

AES算法介绍

AES是著名的非对称算法,通过每轮变换的轮密钥实现加密。它由 10、12 或 14 轮(分别用于 AES-128、AES-192 和 AES-256)组成)通过重复操作逐步转换 16 字节输入。在AES-128里,第一轮的密钥就是AES的密钥,而在AES-256里,第一轮的密钥被拆分为两个轮密钥。

而问题就出在这里,在白盒里面,密钥不会从原地进行轮密钥加,而是在生成白盒时预先计算的,而且轮密钥加会混合在其他轮次中来进行隐藏。

AES的整个加密解密流程如下图



AddRoundKey (轮密钥加)— 矩阵中的每一个字节都与该次轮密钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。

**SubBytes(字节替代) **— 通过非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。

**ShiftRows(行移位) **— 将矩阵中的每个横列进行循环式移位。

MixColumns (列混淆)— 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。

DFA分析AES-128加密

DFA 攻击的一般要求是:

  • 输出必须在没有外部编码的情况下可观察(直接在密码末尾或解码后在应用程序中的其他地方)。
  • 必须能够在同一输入(可以是编码的或未知的)上多次执行密码。在几轮后捕获 AES 的状态并多次恢复它也是一种选择。

由AES加密算法流程可以看出,第10次轮秘钥加之前是没有列混淆的。

所以我们可以知道第九次轮密钥加之前是这样的:



如果我们在第九轮列混淆之前构造如下两组数据:



可以看出这两组数据只有第一个数据不一样,以当前状态继续进行,那么作为状态矩阵的输入就会影响到其余地方,由于

通过上述表达式推算,可以得到一组K10的(0,7,10,13)的位置值,同理,如果换成其他位置的值,可以得到K10的其他位置值,从而推算得到整个K10的值,再根据AES秘钥拓展算法(),最终可以还原原始的加密秘钥。

实战

2023巅峰极客逆向 m1_read

ida打开附件,findcrypto一下发现很明显的AES加密



但是找了很久都没有找到密钥,于是可以联想到是白盒AES(别问怎么联想的),用大爹的模拟执行代码进行还原密钥

我们借用qiling框架来模拟程序执行。

参数传入

函数开头传⼊参数, rcx 存储输⼊的地址

def hook_args(ql: Qiling):
ql.mem.write(0x500000000, b"\x01" * 16)
ql.arch.regs.write("rcx", 0x500000000)
#print(ql.mem.read(0x500000000, 16))
ql.mem.write(0x500000000 + 0x10, b"\x00" * 16)
ql.arch.regs.write("rdx", 0x500000000 + 0x10)
ql.mem.write(0x500000000 + 0x20, b"\x00" * 16)
ql.arch.regs.write("rbx", 0x500000000 + 0x20)
#print("Hook Success")
return
start_addr = 0x140004BF0
ql.hook_address(hook_args, start_addr)

找到插入缺陷数据的地方

上文中,我们说过要将构造多组数据将AES的密钥攻击出来,而我们是在第九次进行轮密钥加之前加入的这种数据,这种数据后文叫缺陷数据。

找到列混合的地方可以很快找到轮密钥加,在本题中我们很容易找到一个对16位字符进行操作的函数,可以肯定这就是列混合的地方。



往下翻,就能找到轮密钥加的地方



每轮v6加了1024*4个字节,也就是1000个字节,在经过八次相加之后就是8000,在这之后加入缺陷代码



在汇编层面上就是下面的代码

def hookcode(ql:Qiling):
if ql.arch.regs.read("r12") == 0x8000:
global index
#第一次需要获取正确的密文,所以不需要插入\x00,也就是说下面的write第一次不用写
ql.mem.write(0x500000000 + index,b'\x00')
index += 1
#此处是获取正确的密文
#print(ql.mem.read(0x500000000,16).hex())
#print(ql.mem.read(0x500000000,16))
return
index_addr = 0x1400052c5#这个地址就是判断是否到第酒次的地址
ql.hook_address(hookcode,index_addr)

获取密文

找到定义密文的地方,如下图所示





所以可以直接hook这个地址,拿到密文

def hook_enc(ql:Qiling):
print(ql.mem.read(0x500000000,16).hex)
return
enc_addr = 0x1400053ca
ql.hook_addr(hook_enc,enc_addr)

运行两次(每次的运行代码不同)验证正确密文和错误密文,看结果是否满足白盒AES原理



可以看出,分别得到了正确密文为

e14d5d0ee27715df08b4152ba23da8e0

第九轮列混淆时,错误的密文为

d24d5d0ee27715ac08b4bf2ba272a8e0

在第0,7,10,13个字节分别与正确密文有错误,和原理一致。

获取所有错误密文

写个for循环即可得到剩下的密文,整个代码如下

from qiling import *
from qiling.const import QL_VERBOSE index = 0
ql = Qiling(
["/home/nian/桌面/examples/m1_read.exe"],
r"/home/nian/桌面/examples/rootfs/x86_windows",
verbose=QL_VERBOSE.OFF,
) def hook_args(ql: Qiling):
ql.mem.write(0x500000000, b"\x01" * 16)
ql.arch.regs.write("rcx", 0x500000000)
#print(ql.mem.read(0x500000000, 16))
ql.mem.write(0x500000000 + 0x10, b"\x00" * 16)
ql.arch.regs.write("rdx", 0x500000000 + 0x10)
ql.mem.write(0x500000000 + 0x20, b"\x00" * 16)
ql.arch.regs.write("rbx", 0x500000000 + 0x20)
#print("Hook Success")
return def hook_code(ql: Qiling):
if ql.arch.regs.read("r12") == 0x8000:
global index
ql.mem.write(0x500000000 + index, b"\x00")
index += 1
#print(ql.mem.read(0x500000000, 16).hex())
#print(ql.mem.read(0x500000000 + 0x10, 16))
return def hook_enc(ql: Qiling):
print(ql.mem.read(0x500000000, 16).hex())
return index_addr = 0x1400052C5
start_addr = 0x140004BF0
end_addr = 0x14000542D
enc_after = 0x1400053CA
ql.hook_address(hook_args, start_addr)
ql.hook_address(hook_code, index_addr)
ql.hook_address(hook_enc, enc_after)
# e14d5d0ee27715df08b4152ba23da8e0
# e14d5d73e27708df0878152b843da8e0
for i in range(16):
ql.run(begin=start_addr, end=end_addr)

得到如下错误密文

"""d24d5d0ee27715ac08b4bf2ba272a8e0
e14d5d73e27708df0878152b843da8e0
e14dd50ee23415df7fb4152ba23da890
e16f5d0e537715df08b415e7a23dc6e0
e11a5d0e057715df08b4151ba23d99e0
574d5d0ee277157508b4df2ba234a8e0
e14d5d49e27785df0840152bff3da8e0
e14db80ee2d215dfceb4152ba23da868
e14dc60ee2bf15dfc4b4152ba23da8bf
e1425d0e5e7715df08b415b6a23d4ce0
5d4d5d0ee277159608b42f2ba297a8e0
e14d5d6ce2773ddf089d152ba93da8e0
e14d5dcde2772adf084b152bba3da8e0
e14df40ee27115df96b4152ba23da881
e11b5d0e337715df08b41544a23df3e0
fa4d5d0ee27715af08b42e2ba2c2a8e0"""

还原第十个密钥

现在已知了正确的密文和所有的错误密文,可以用phoenixAES工具来还原原理中提到的k10

https://github.com/SideChannelMarvels/JeanGrey/tree/master/phoenixAES

代码如下:

import phoenixAES

with open("tracefile","wb") as t:
t.write(
""" e14d5d0ee27715df08b4152ba23da8e0
d24d5d0ee27715ac08b4bf2ba272a8e0
e14d5d73e27708df0878152b843da8e0
e14dd50ee23415df7fb4152ba23da890
e16f5d0e537715df08b415e7a23dc6e0
e11a5d0e057715df08b4151ba23d99e0
574d5d0ee277157508b4df2ba234a8e0
e14d5d49e27785df0840152bff3da8e0
e14db80ee2d215dfceb4152ba23da868
e14dc60ee2bf15dfc4b4152ba23da8bf
e1425d0e5e7715df08b415b6a23d4ce0
5d4d5d0ee277159608b42f2ba297a8e0
e14d5d6ce2773ddf089d152ba93da8e0
e14d5dcde2772adf084b152bba3da8e0
e14df40ee27115df96b4152ba23da881
e11b5d0e337715df08b41544a23df3e0
fa4d5d0ee27715af08b42e2ba2c2a8e0
""".encode("utf-8")
)
phoenixAES.crack_file("tracefile",verbose=0)



运行后得到k10

"""B4EF5BCB3E92E21123E951CF6F8F188E"""

还原原始密钥

得到第十轮的密钥后,就可以着手还原原始密钥了,用到的工具是Stark

https://github.com/SideChannelMarvels/Stark

下载好stark之后要记得在文件目录下面make把三个c文件编译成可执行文件,再用可执行文件操作,如下图



这样一来,就得到原始密钥key0了

"""00000000000000000000000000000000"""

再利用原始密钥解密原始密文,即可得到明文

解密



out.bin里面的密文

"""0B987EF5D94DD679592C4D2FADD4EB89"""

解密即可得到明文

from Crypto.Cipher import AES

enc = bytearray(bytes.fromhex("0B 98 7E F5 D9 4D D6 79 59 2C 4D 2F AD D4 EB 89"))
enc = bytes([enc[i] ^ 0x66 for i in range(16)])
key = bytes.fromhex("00000000000000000000000000000000")
aes = AES.new(key=key, mode=AES.MODE_ECB)
print(aes.decrypt(enc))

运行,得到flag

上述就是基本的AES差分故障分析方法和例题,而除了AES之外,还有DES和SM4的白盒,它们和AES的故障攻击方法基本大同小异

这里给出研究SM4的博客供大家(wo)学习

https://www.anquanke.com/post/id/231483

白盒AES和SM4实现的差分故障分析的更多相关文章

  1. GTest Google的一种白盒单元测试框架 开源项目

    GTest为google开源的白盒单元测试跨平台测试框架,含丰富的断言.类型参数化测试.死亡测试.以及其他的测试选项设置.文件保存等,以下将对该项目C++的实现进行简要的分析,作为学习记录备份. 基本 ...

  2. JAVA语言搭建白盒静态代码、黑盒网站插件式自动化安全审计平台

    近期打算做一个插件化的白盒静态代码安全审计自动化平台和黑盒网站安全审计自动化平台.现在开源或半开源做黑盒网站安全扫描的平台,大多是基于python脚本,安全人员贡献python脚本插件增强平台功能.对 ...

  3. 浅析白盒审计中的字符编码及SQL注入

    尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...

  4. JAVA白盒安全测试需要关注的API

    JAVA白盒安全测试需要关注的APIhttp://blog.csdn.net/testing_is_believing/article/details/19502167

  5. 亿能测试白盒安全测试模板V1.0发布

    亿能测试白盒安全测试模板V1.0发布http://automationqa.com/forum.php?mod=viewthread&tid=2911&fromuid=21

  6. 移动測试技术保护源码!解码全球首款移动端白盒測试工具ThreadingTest (文章转自己主动点科技)

    作者 智晓锋 - 2014/07/14 自从斯诺登曝光美监听丑闻事件之后,我国政府就将信息安全问题上升到了国家安全的高度.基于此.国内的一家创业公司推出了智能型Android真机白盒測试以及开发辅助类 ...

  7. SafeNet推出行业首款白盒password软件保护解决方式

    数据保护领域的全球率先企业SafeNet公司日前宣布,推出行业首款採用白盒安全技术的的软件保护方案.SafeNet 圣天诺 软件授权与保护解决方式如今纳入了新的功能,可在"白盒" ...

  8. testing and SQA_动态白盒測试

    一.软件測试技术: 黑盒:在不知道程序内部结构,仅仅知道程序结构的情况下採用的測试技术或策略. 白盒:在知道程序内部结构的情况下採用的測试技术或策略. 两种測试方法从不同的角度出发,反映了软件的不同側 ...

  9. 商业级别Fortify白盒神器介绍与使用分析

    转自:http://www.freebuf.com/sectool/95683.html 什么是fortify它又能干些什么? 答:fottify全名叫:Fortify SCA ,是HP的产品 ,是一 ...

  10. 白盒-CNN纹理深度可视化: 使用MIT Place 场景预训练模型

    MIT发文:深度视觉的量化表示................ Places2 是一个场景图像数据集,包含 1千万张 图片,400多个不同类型的场景环境,可用于以场景和环境为应用内容的视觉认知任务. ...

随机推荐

  1. [SWPUCTF 2021 新生赛]PseudoProtocols

    [SWPUCTF 2021 新生赛]PseudoProtocols 一.题目 二.WP 1.打开题目,发现提示我们是否能找到hint.php,并且发现URL有参数wllm.所以我们尝试利用PHP伪协议 ...

  2. 好的,以下是我为您拟定的自然语言处理(NLP)领域的100篇热门博客文章标题,以逻辑清晰、结构紧凑、简单易懂的

    目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 1. 机器翻译 2. 文本分类 3. 情感分析 5. 优化与改进 6. 结论与展望 好的,以下是我为您拟定的 ...

  3. celery笔记八之数据库操作定时任务

    本文首发于公众号:Hunter后端 原文链接:celery笔记八之数据库操作定时任务 前面我们介绍定时任务是在 celery.py 中的 app.conf.beat_schedule 定义,这一篇笔记 ...

  4. 【技术积累】Spring Boot中的基础知识【一】

    写在前面 笔者在学校里学习Spring项目的时候,基本上都是老师照着书念PPT,然后演示一些有限的课堂案例,笔者印象很深刻,学校里整个Spring项目也就做了留个课堂练习,而且难度基本上属于连接上数据 ...

  5. 11k+ Star 一款更适合中国用户的开源 BI 工具

    在当今数字化时代,数据分析和可视化成为企业决策和发展的重要支撑,很多 BI 工具昂贵的许可费用,让许多中小型企业用户和个人用户望而却步,开源 BI 工具的出现,让其成为很多用户进行数据分析展示的首选. ...

  6. Sentieon | 每周文献-Tumor Sequencing-第三期

    肿瘤测序系列文章-1 标题(英文):The relationship between genetic characteristics and clinical characteristics and ...

  7. EtherCAT 转CCLINK网关连接三菱plc应用案例

    EtherCAT 现场总线协议是由德国倍福公司在 2003 年提出的,该通讯协议拓扑结构十分灵活,数据传输速度快,同步特性好,可以形成各种网络拓扑结构. 捷米特JM-ECT-CCLK  是自主研发的一 ...

  8. Flutter ListView 不满屏 无法滚动

    场景: flutter ListView 在做上拉加载的时候,未list添加controller后,数据不满屏,无法滚动 解决: 未listview 设置: physics: const Always ...

  9. 【Shell】函数

    函数 1.语法 函数定义语法如下: [ function ] funname [()] { action; [return int;] } 说明 : 函数定义时,function 关键字可有可无. 函 ...

  10. ZEGO 即构音乐场景降噪技术解析

    随着线上泛娱乐的兴起,语聊房.在线 KTV 以及直播等场景在人们的日常生活中占据越来越重要的地位,用户对于音质的要求也越来越高,因此超越传统语音降噪算法的 AI 降噪算法应运而生,所以目前各大 RTC ...