RWCTF2022 Trust_or_not 复现

2023-11-21 06:30
文章标签 复现 trust rwctf2022

本文主要是介绍RWCTF2022 Trust_or_not 复现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RWCTF2022 Trust_or_not复现

RWCTF2022中有道逆向和TEE有关,准备复现一遍,顺便学习一下TEE。

TEE简介

TEE 全称叫做 Trust Executed Environment 可信执行系统,TEE 主要应用在手机以及 iot 设备上,比如用户的指纹识别以及支付相关的敏感操作都是在 TEE 中进行处理的,敏感的信息也是通过 TEE 加密之后存储在一个可信的位置。

TEE Feature

TEE有几个特别的名词,在此进行说明

REE:指非安全系统,手机上指的就是Android

bl1.binbl2.binbl31.binbl32.binbl33.bin、前两个 bl* 主要和 boot 以及镜像加载有关,bl31 负责管理 SMC(Secure Monitor Control) 执行处理和中断,bl32 就是 TEE 系统镜像,bl33 为 REE 系统镜像也就是 Linux Kernel、uboot 之类的。调用流程如下图所示

img

TA 的全称是 Trusted Application 可信应用,既然有可信应用那么也就有不可信应用,不可信应用叫做 CA(Client Application) ,REE 通过调用 CA 来获取 TEE 提供的服务,每一个 CA 对应都有一个 TA ,TA 中调用 TEE 提供的 API 来满足 CA 发来的请求。每一个 TA 都被一个唯一的 UUID 标识。

TEE Secure Storage

接下来是很重要的TEE的安全存储。整体的流程如下

img

图中出现了很多密钥,HUK,SSK,TSK,FEK。

翻文档可以知道,这几个密钥分别的作用和存储位置

HUK

在这里插入图片描述

硬件唯一密钥,主要用于生成其他的密钥,文档里说明了这个永远不能被直接从软件中读到,secure side也不行,代表其重要性。

下方提及到,如果要在OP-TEE里寻找HUK,直接在tee_otp_get_hw_unique_key这个函数里面寻找,路径也标了出来。

SSK

在这里插入图片描述

SSK(安全存储密钥)的作用是生成TSK(可信程序存储密钥),是和设备相关的key。SSK是由HUK和静态字符串进行加密后得出的,且目前OP-TEE OS里我们只有一个SSK。

TSK

在这里插入图片描述

可信程序存储密钥由SSK和TA(可信程序)的UUID加密后得到,用处是用来保护FEK,也就是对FEK进行加密和解密

FEK

在这里插入图片描述

文件加密密钥。当TEE文件生成时,密钥管理器将用PRNG(伪随机数生成器)生成一个新的FEK,然后把加密后的FEK存储到元文件之中。FEK的作用是可以对存储在TEE的元文件的信息和块中的数据进行加密和解密。

元数据的加密流程

流程图如下

../_images/meta_data_encryption.png

首先用TSK作为密钥,将FEK进行AES的MODE ECB 加密,得到的Encrypted FEK作为AAD(附加消息),FEK作为密钥,然后用Meta IV对Meta Data进行AES的MODE GCM加密,生成密文,tag(就是身份验证标签,MAC值,检测消息的完整性)和元IV,从而完成一套加密流程。

当需要更新元数据时,PRNG 将生成新的元 IV。meta IV 的大小在core/include/tee/fs_htree.h中定义

题目分析

对TEE稍作了解后,我们直接看题目。

HUK

首先我在Ubuntu 20.04上运行了一下这个TEE,发现这个题目是运行在qemu-system-aarch64中的,由HUK的定义我们可以知道它只和平台有关,而上方也说明了HUK永远都不应该被读到,

(以下是我的想法)

所以这里要找HUK应该是找不到的,如果可以做的话应该是初始值。

搜索源代码可知,初始值是全部memset为0

__weak TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
{memset(&hwkey->data[0], 0, sizeof(hwkey->data));return TEE_SUCCESS;
}

Static String

谷歌了半天,终于在文档里找着了
在这里插入图片描述

直接和pattern一起复制粘贴下来,这样我们就可以求SSK了

SSK

(本文的代码借鉴了https://www.anquanke.com/post/id/267183#h3-8 大佬的代码)

from hashlib import sha256
from hmac import HMACdef byte_to_string(s):return ''.join(["%02X " %i for i in s])
HUK = b'\x00'*0x10
chip_id = b'BEEF'*8
static_string = b'ONLY_FOR_tee_fs_ssk'
message = chip_id + static_string
SSK = HMAC(HUK, message, digestmod=sha256).digest()
print ("SSK: " + byte_to_string(SSK))

得出SSK

SSK: D0 23 CE 37 07 F6 CF 82 5E 2F 7C 1C 6A F8 2A 8B F1 E8 CF 9D E7 17 3D 74 31 2A A0 E2 77 6F 93 41 

TSK

SSK我们已经知道,接下来是求ta文件的UUID。此处有三个做法

法一 直接通过偏移获得

搜索资料可知,ta的uuid存储在ta_head结构体之中,也存放在ta_head节中
在这里插入图片描述

然后010搜索ta_head节,这里的TA_STACK_SIZE搜索源码可知是4096,也就是0x1000
在这里插入图片描述

上方说了ta文件的代码用的是TA_STACK_SIZE,我就尝试了一下搜索0x1000的偏移,再加上ta文件头的偏移0x148后,就找到了uuid

不过感觉stack size不应该这么小(?

这里没有完全搞懂,希望有知道的师傅们指点一下

法二 拖进ida观察

查询资料可知,除类型为SEC4以外的ta文件删除了ta的文件头后是elf文件,证明我们可以直接拖进熟悉的ida来分析。于是我尝试了一下删除ta的文件头
在这里插入图片描述

在这里插入图片描述

然后拖进ida。在文件头中发现了uuid

法三 直接看文件名(草

在这里插入图片描述

笑死。
在这里插入图片描述

只能说一模一样

综上,我们可以得出uuid为

b'\xbb\x50\xe7\xf4\x37\x14\xbf\x4f\x87\x85\x8d\x35\x80\xc3\x49\x94'

然后计算TSK

from hashlib import sha256
from hmac import HMAC
def byte_to_string(s):return ''.join(['%02X ' % i for i in s])
HUK = b'\x00'*0x10
chip_id = b'BEEF'*8
static_string = b'ONLY_FOR_tee_fs_ssk'
message = chip_id + static_string
SSK = HMAC(HUK, message, digestmod=sha256).digest()
ta_uuid =  b'\xbb\x50\xe7\xf4\x37\x14\xbf\x4f\x87\x85\x8d\x35\x80\xc3\x49\x94'
TSK = HMAC(SSK, ta_uuid, digestmod=sha256).digest()
print ("TSK: " + bytesToHexString(TSK))
TSK: 7E BE 82 6A A4 F4 57 AE FB EA EA 6E 34 BC D6 AA 14 A6 DD C7 EE 90 4C E4 9F 8F 20 71 3F 40 E6 CC 

FEK

寻找encrypted FEK

参考https://cxybb.com/article/shuaifengyun/73655723

TEE保存敏感数据时,会将被secure storage保存的用户文件放在/data/tee,并以数字命名。还会生成一个dirf.db文件,保存整个安全存储保护的文件的所有节点和目录信息。

本题/data/tee目录下只有个数字命名的文件,也就是用户的加密后的数据。之前提到了加密后的文件会保存Encrypted FEK

struct tee_fs_htree_image {uint8_t iv[TEE_FS_HTREE_IV_SIZE];//加密iv+enc_fek时使用的iv值,每次保存head时会使用随机数更新uint8_t tag[TEE_FS_HTREE_TAG_SIZE];//加密iv+Enc_fek生成的数据的tag部分uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE];//使用TSK加密一个安全文件的fek生成的uint8_t imeta[sizeof(struct tee_fs_htree_imeta)];//加密iv+Enc_fek生成的数据的imeta部分uint32_t counter;//用于计算在保存tee_fs_htree_image的时候是存到ver0还是ver1
};

该结构体的enc_fek即保存着加密后的FEK,而根据下图的安全文件保存格式

img

我们知道文件头里就是我们想要找的enc_fek,搜索源码可知,TEE_FS_HTREE_IV_SIZE=16,TEE_FS_HTREE_TAG_SIZE=16,TEE_FS_HTREE_FEK_SIZE=16

于是在0x20的位置可以提取出enc_fek。
在这里插入图片描述

b"\xe4\x9a\x95\xf2\xb5\xf4\x9c\x04\xf6\x07\x9f\xfb\xf0\x2e\xd2\xef"

ver0和ver1的enc_fek都一样,找一个就够了。

然后可以计算出FEK了

计算结果

以下是我整个题最不解的地方。

网上搜索资料可知iv和tag存储在tee_fs_htree_node_image结构体里面

去看了源码的TEE_FS_HTREE_HASH_SIZE的大小,发现是32

在这里插入图片描述在这里插入图片描述

TEE_FS_HTREE_HASH_SIZE是由TEE_SHA256_HASH_SIZE赋值的

然后综合这个图,我就去0x1000+0x20处找iv和tag,结果发现是错的

img

看了wp后发现,iv的偏移是0x1062。这个困扰了我很久,希望师傅们指点一下(哭

按答案的iv和tag,可以算出正确的flag

(因为不怎么会密码,直接复制粘贴
Resery师傅的脚本了)

此处解密的数据是上图的data block,也就是从0x2000开始的data

import os
import struct
from hashlib import sha256
from hmac import HMAC
from Crypto.Cipher import AES 
import binasciidef bytesToHexString(bs):return ''.join(['%02X ' % b for b in bs])def AES_Decrypt_ECB(key, data):cipher = AES.new(key, AES.MODE_ECB)text_decrypted = cipher.decrypt(data)return text_decryptedfp = open("2","rb")
data = fp.read()
fp.close()HUK = b'\x00'*0x10
chip_id = b'BEEF'*8
static_string = b'ONLY_FOR_tee_fs_ssk'
message = chip_id + static_string + b'\x00'SSK = HMAC(HUK, message, digestmod=sha256).digest()
# print ("SSK: " + bytesToHexString(SSK))ta_uuid =  b'\xbb\x50\xe7\xf4\x37\x14\xbf\x4f\x87\x85\x8d\x35\x80\xc3\x49\x94'
TSK = HMAC(SSK, ta_uuid, digestmod=sha256).digest()
# print ("TSK: " + bytesToHexString(TSK))Enc_FEK = b'\xe4\x9a\x95\xf2\xb5\xf4\x9c\x04\xf6\x07\x9f\xfb\xf0\x2e\xd2\xef'
FEK = AES_Decrypt_ECB(TSK, Enc_FEK)
# print ("FEK: " + bytesToHexString(FEK))# print ("........ decrypt block data ...........")
block_0 = data[0x2000:0x3000]Tee_fs_htree_node_image_1_iv = b'\xB4\xC9\x6A\x22\xE6\x36\x72\xCF\x6A\x44\x8F\x10\xA3\x11\x44\x68'
Tee_fs_htree_node_image_1_tag = b'\xCE\x65\xDE\x73\x08\xF9\x21\x09\xF2\xD2\x99\x9F\xA4\xB4\xE7\x51'cipher = AES.new(FEK, AES.MODE_GCM, nonce = Tee_fs_htree_node_image_1_iv)cipher.update(Enc_FEK)
cipher.update(Tee_fs_htree_node_image_1_iv)plaintext = cipher.decrypt_and_verify(block_0, Tee_fs_htree_node_image_1_tag)
print (plaintext)

得出flag为 rwctf{b5f3a0b72861b4de41f854de0ea3da10}

总结

回头看了一看,发现没我当时感觉的难,努力一下说不定也能做出来,而当时却打了退堂鼓。希望以后能自信一点。

还有RWCTF的题目真的很好,学到了很多东西,很开心。本题中没有搞懂的部分,之后会请教师傅们,争取能吃透。

参考

https://elixir.bootlin.com/op-tee/latest/source/core/kernel/

https://www.anquanke.com/post/id/267183#h2-12(参考的wp)

https://www.anquanke.com/post/id/236483#h2-5

https://cxybb.com/article/shuaifengyun/73655723

https://blog.csdn.net/shuaifengyun/article/details/74594861

https://github.com/OP-TEE/optee_os

这篇关于RWCTF2022 Trust_or_not 复现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400476

相关文章

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的

UMI复现代码运行逻辑全流程(一)——eval_real.py(尚在更新)

一、文件夹功能解析 全文件夹如下 其中,核心文件作用为: diffusion_policy:扩散策略核心文件夹,包含了众多模型及基础库 example:标定及配置文件 scripts/scripts_real:测试脚本文件,区别在于前者倾向于单体运行,后者为整体运行 scripts_slam_pipeline:orb_slam3运行全部文件 umi:核心交互文件夹,作用在于构建真

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

【vulhub】thinkphp5 2-rce 5.0.23-rce 5-rce 漏洞复现

2-rec 1.启动环境  cd /.../vulhub/thinkphp/2-rce # cd进入2-rce靶场文件环境下docker-compose up -d # docker-compose启动靶场docker ps -a # 查看开启的靶场信息 2.访问192.168.146.136:8080网页 3.构造payload http

【漏洞复现】赛蓝企业管理系统 GetJSFile 任意文件读取漏洞

免责声明:         本文内容旨在提供有关特定漏洞或安全漏洞的信息,以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步,并非出于任何恶意目的。阅读者应该明白,在利用本文提到的漏洞信息或进行相关测试时,可能会违反某些法律法规或服务协议。同时,未经授权地访问系统、网络或应用程序可能导致法律责任或其他严重后果。作者不对读者基于本文内容而产生的任何行为或后果承担

深度学习每周学习总结N9:transformer复现

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 目录 多头注意力机制前馈传播位置编码编码层解码层Transformer模型构建使用示例 本文为TR3学习打卡,为了保证记录顺序我这里写为N9 总结: 之前有学习过文本预处理的环节,对文本处理的主要方式有以下三种: 1:词袋模型(one-hot编码) 2:TF-I

【达梦数据库】误删数据库目录问题复现解决方式

目录 1、环境搭建1.1、查询数据库版本1.2、创建表1.3、插入数据1.4、查询数据 2、故障重演2.1、服务器内直接删除整个库文件2.2、查询数据:数据可查2.3、查看进程:进程存在2.4、查看proc进程文件:deleted 3、数据恢复3.1、逻辑导出导入-(数据丢失,废弃)3.1.1、全库导出3.1.2、重新初始化库3.1.3、全库导入3.1.4、查询数据:数据丢失

【漏洞复现】锐捷 校园网自助服务系统 login_judge.jsf 任意文件读取漏洞

免责声明:         本文内容旨在提供有关特定漏洞或安全漏洞的信息,以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步,并非出于任何恶意目的。阅读者应该明白,在利用本文提到的漏洞信息或进行相关测试时,可能会违反某些法律法规或服务协议。同时,未经授权地访问系统、网络或应用程序可能导致法律责任或其他严重后果。作者不对读者基于本文内容而产生的任何行为或后果承担

海外合规|新加坡网络安全认证计划简介(三)-Cyber Trust

一、 认证简介:         Cyber Trust标志是针对数字化业务运营更为广泛的组织的网络安全认证。该标志针对的是规模较大或数字化程度较高的组织,因为这些组织可能具有更高的风险水平,需要他们投资专业知识和资源来管理和保护其 IT 基础设施和系统。Cyber Trust 标志采用基于风险的方法来指导组织了解其风险状况并确定减轻这些风险所需的相关网络安全准备领域。

外泌体相关基因肝癌临床模型预测——2-3分纯生信文章复现——5.拷贝数变异及突变图谱(2)

内容如下: 1.外泌体和肝癌TCGA数据下载 2.数据格式整理 3.差异表达基因筛选 4.预后相关外泌体基因确定 5.拷贝数变异及突变图谱 6.外泌体基因功能注释 7.LASSO回归筛选外泌体预后模型 8.预后模型验证 9.预后模型鲁棒性分析 10.独立预后因素分析及与临床的相关性分析 11.列线图,ROC曲线,校准曲线,DCA曲线 12.外部数据集验证 13.外泌