接着上篇, 上篇使用的是 frida 注入故障, 我们这篇使用 unidbg 来注入故障
先补环境, 给出完整代码, 很简单
1 | package com.aes; |
注意哦, 静态注册的函数, 不需要context 这个函数, 否则会报错
1 | java.lang.ClassCastException: class com.github.unidbg.linux.android.dvm.DvmObject cannot be cast to class com.github.unidbg.linux.android.dvm.array.ByteArray |
我们来看看运行结果.
可以看到结果已经出来了
我们先hook 列混淆函数看看, 我们使用的是 arm64 的so文件
1 | public void hook20D2C(){ |
看看结果
可以看到 hook 成功了
我们尝试打印一下入参 state
1 | public void hook20D2C(){ |
看看结果
那如何patch 呢,在最后一次列混淆的时候,能不能hook 的时候就patch 呢?
答曰: 可以!
1 | public static int count = 0; |
我们来跑一下, 看看将第一个字节改为 2 后, 结果变成了什么
可以看到 结果变成了 2ee457698cd1c4cc0da65a8591ba75bc
再来看看正常运行 不使用dfa 攻击, 正常的 AES ECB 的值是多少?
答曰: d4e457698cd1c4930da6cb8591f075bc, 可以看到 我们成功了,结果差几个字节而已.
我们来批量注入.
1 | public static void main(String[] args) { |
运行看看
可以看到 多次注入结果已经打印出来了, 把日志copy 到文件中, 写个脚本批量匹配 ret, 或者改代码, 把结果保存到文件中. 我们选择后者.
1 | public void callNsign(){ |
然后我们在文件首行加入正确的密文. d4e457698cd1c4930da6cb8591f075bc
交给 phoenixAES 执行看看
1 | import phoenixAES |
呃, 好像结果并没有出来, why????
是因为太少了吗? 我们注入500次试试
果然 200次太少, 一辈子太长, 只求天长地久.
ok, AES ECB 已知某一轮密钥, 怎么推出其他密钥,甚至初始密钥?
答曰: Stark.
cyberchef 验证看看
yyds!!