首页
社区
课程
招聘
[分享]local Key Attestation 验证饶过
发表于: 2023-12-24 01:17 9009

[分享]local Key Attestation 验证饶过

2023-12-24 01:17
9009

书接上文 https://bbs.kanxue.com/thread-279799.htm

自己做了一个本地绕过的脚本效果不是很理想,又去研究大佬的脚本,这个大佬的每次commit 基本我都看了,被大佬的底蕴折服,也印证了一句话,知识面越广,攻击面越广。

https://github.com/chiteroman/BootloaderSpoofer

思路1

评论里hook verify的思路,逻辑如图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class Xposed implements IXposedHookLoadPackage {
    private static int indexOf(byte[] array) {
        final byte[] PATTERN = {48, 74, 4, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 10, 1, 2};
        outer:
        for (int i = 0; i < array.length - PATTERN.length + 1; i++) {
            for (int j = 0; j < PATTERN.length; j++) {
                if (array[i + j] != PATTERN[j]) {
                    continue outer;
                }
            }
            return i;
        }
        return -1;
    }
 
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            KeyStoreSpi keyStoreSpi = (KeyStoreSpi) XposedHelpers.getObjectField(keyStore, "keyStoreSpi");
            XposedHelpers.findAndHookMethod(keyStoreSpi.getClass(), "engineGetCertificateChain", String.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    Certificate[] certificates = (Certificate[]) param.getResultOrThrowable();
                    if (certificates[0] instanceof X509Certificate cert) {
 
                        for (Method method : cert.getClass().getMethods()) {
                            if (method.getName().toLowerCase(Locale.ROOT).contains("verify")) {
                                // verify 不抛出异常表示验证通过
                                XposedBridge.hookMethod(method, XC_MethodReplacement.DO_NOTHING);
                            }
                        }
 
                        //获取证书编码,修改部分偏移的数据
                        //修改Device locked:true
                        //修改Verified boot state: Verified
                        byte[] bytes = cert.getEncoded();
                        if (bytes == null || bytes.length == 0) return;
                        int index = indexOf(bytes);//这个索引?
                        if (index == -1) return;
                        bytes[index + 38] = 1;
                        bytes[index + 41] = 0;
 
                        //替换证书
                        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                        X509Certificate modCert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(bytes));
                        certificates[0] = modCert;
                        param.setResult(certificates);
                    }
                }
            });
        } catch (Throwable t) {
            XposedBridge.log(t);
        }
    }
}

这一版问题很明显,challenge 没有饶过,被修改的证书内容,实际无法通过公钥验证

new

又更新了一个版本,卧槽 被大佬深厚的底蕴震撼 v3.5 , 这个版本的思路, 弥补之前的短板:

  1. challenge 没有修复
  2. 证书被修改后,实际没法通过公钥验证

那chiteroman怎么做的呢?

  1. hook generateKeyPair ,返回插件预置的公私钥
  2. hook setAttestationChallenge ,实时获取challenge
  3. 替代 engineGetCertificateChain 函数,伪造整条证书链、并写入challenge

是吧 这个思路看起来很nice ,不过也存在问题 , 始终使用的内置的公私钥。换句话说,无论生成几次公私钥,始终是同一个公私钥,这一点问题。

正常产生的公钥

有问题

怎么解决呢?

  1. 内置多个证书
  2. 中间人实时生产证书

我正在开发的脚本,思路就是直接走一个中间人发证书。

因为个人兴趣原因,后续可能也会做很多设备异常判定的研究,有相同志向的小伙伴 不做黑产!!纯研究,可以私信我。我看人多的话,就拉个群大家一起交流。

https://github.com/chiteroman/BootloaderSpoofer
https://github.com/doom-man/bypasskeyattestation/blob/main/docs/other.md


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (18)
雪    币: 2948
活跃值: (30846)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-12-24 16:39
1
雪    币: 2328
活跃值: (10364)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享,已经发了私信,看到拉我一下
2023-12-25 09:52
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这个内容干货很多,已经发了私信,能拉一下一起研究吗?
2023-12-28 11:46
0
雪    币: 231
活跃值: (117)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yyb
5
咦,这个是52早还是看雪早,两边同时有这个贴?
2023-12-28 19:01
0
雪    币: 225
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
拉我一下。一起研究
2023-12-30 12:55
0
雪    币: 1167
活跃值: (2189)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这个内容干货很多,已经发了私信,能拉一下一起研究吗?
2023-12-31 08:29
0
雪    币: 124
活跃值: (374)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
谢谢大神分享!
2024-1-1 10:26
0
雪    币: 0
活跃值: (105)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
“伪造整条证书链、并写入challenge”,证书链可以怎么获取呢?
2024-1-16 19:00
0
雪    币: 69
活跃值: (360)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
大佬 拉我入群
2024-1-20 18:44
0
雪    币: 225
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
实际上上使用中间人产生多个证书不可行。因为中间人证书也是在手机安全环境中生成。除非用最后生成的用户证书继续派生下一级用户证书,这样会存在两个证书都包含extensionOID 。这个问题需要特殊处理一下
2024-2-1 08:55
0
雪    币: 225
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
大家有兴趣的。我拉个群一起探讨?企鹅 383156428
2024-2-1 09:00
0
雪    币: 463
活跃值: (2696)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
13
空空的爸爸 实际上上使用中间人产生多个证书不可行。因为中间人证书也是在手机安全环境中生成。除非用最后生成的用户证书继续派生下一级用户证书,这样会存在两个证书都包含extensionOID 。这个问题需要特殊处理一 ...
中间人 生成完整的证书链, extensionOID有什么问题吗
2024-2-19 15:27
0
雪    币: 463
活跃值: (2696)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
14
相关研究方向的 可以进电报 https://t.me/+V4B4K7LtH4U0NTU1 ,最近研究方向偏移,近期可能不会更新,更新了,会发的
2024-2-19 15:36
0
雪    币: 225
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
pareto 中间人 生成完整的证书链, extensionOID有什么问题吗
中间人怎么生成完整的证书链?从手机里面拿到的只能是用户证书、
2024-3-4 13:23
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16

官网明确只有根证书可信,这样也改不了根证书吧? 另外为什么需要hook 生成密钥对的地方,返回内置密钥?很奇怪的操作

最后于 2024-6-26 10:44 被gunkkk编辑 ,原因:
2024-6-21 16:52
0
雪    币: 698
活跃值: (1426)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
还是过不了keyattention的检测啊?
2024-6-24 11:43
0
雪    币: 463
活跃值: (2696)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
18
理论上没有泄露的私钥搞不了
2024-6-24 12:49
0
雪    币: 3347
活跃值: (13988)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
19
文章不错,这块分享一下一个通用的思路 。
1、服务端先hook 告诉客户端不支持tee和沙箱 ,这样客户端只能在证书初始化的时候设置第一种最弱的内存模式 。
2、客户端直接参考BootloaderSpoofer 配合无痕hook去掉。
(如果服务端有能直接bypass的更好)
2024-6-24 14:09
1
游客
登录 | 注册 方可回帖
返回
//