首页
社区
课程
招聘
关于Matlab的exe文件解析
2023-6-5 00:49 6354

关于Matlab的exe文件解析

2023-6-5 00:49
6354

每次github上有人提issue时都要重新看代码来回顾整个过程,遂写下这篇文章减少复习的时间。

什么是exe文件

这里的exe文件专门指由Matlab使用mcc命令编译出来的exe文件,可以在Windows环境中运行。

 

mcc命令的部分说明如下:

您可以使用 将 MATLAB 程序打包和部署为独立应用程序、Excel 加载项、Spark™ 应用程序或 Hadoop 作业。

如果你有一个 MATLAB 编译器SDK™许可证,可用于创建C/C++共享库, .NET 汇编、Java 包、Python 包、MATLAB 生产服务器™可部署存档,或用于 MATLAB 的 Excel 加载项 生产服务器。

mcc -m [选项] mfilename 将函数编译为独立的应用程序。可执行文件类型由 您的操作系统。

 

从描述上看,Windows的exe文件只是mcc命令众多功能的一个子集,但是本文的视角仅聚焦在Windows下的exe文件。

 

既然是exe文件,文件结构当然是一个标准的PE结构。

 

DIE截图

 

上述信息展示了overlay是一个ZIP文件,可以用任何压缩软件解压。

 

overlay预览

overlay的压缩包

overlay的压缩包主要包含了两类文件,一种是包含各种信息的xml文件,另一种是Matlab的加密脚本文件(有固定的开头),还有一些数据、界面、依赖等不是特别重要的信息本文将忽略。

manifest.xml

xml中最为重要的是.META目录下的manifest.xml,该文件包含了用于解密加密脚本的密钥,其本身也受到哈希保护。

 

manifest.xml的signature字段用于校验自身,当signature为128字节时采用SHA512保护(v2),当signature为40字节时采用SHA1保护(v1)。

 

manifest.xml包含两个重要的密钥,解决方案密钥(solution-key)和编译密钥(compiler-key),分别由session-key字段和public-key字段提供。

密钥

由于在解密过程出现很多的密钥,下面先对这些密钥进行归纳

名称 来源 用途
session-key manifest.xml 作为solution-key
public-key manifest.xml 作为compiler-key
solution-key manifest.xml 用于导出symmetric-key,导出时需要私钥matlab-key,动态的候选密钥
compiler-key manifest.xml 用于验证加密脚本的完整性
matlab-key mclmcr.dll 用于解密solution-key导出symmetric-key
toolbox-key ctfrtcrypto.dll 用于导出symmetric-key,导出时需要私钥matlab-key,静态的候选密钥
symmetric-key solution-key或toolbox-key 用于计算aes-key(symmetric-key的SHA256)
aes-key symmetric-key 用于解密加密脚本,验证加密脚本完整性

加密脚本

加密脚本目前收录了两个版本,分别以V1MCC4000MEC1000MCR1000V2MCC8000MEC2000MCR2000开头。这两个版本在结构和算法上有较大的区别,下文会按两种版本分别阐述。

序号 开头特征 适用版本
1 V1MCC4000MEC1000MCR1000 R2018B之前版本(含)
2 V2MCC8000MEC2000MCR2000 R2019A之后版本(含)

V1版本

以下展示加密脚本的部分截图:

 

V1-file

 

从上图可以看到,V1版本的文件结构主要分为两个部分,记为body1和body2。body1有一个Int型指示大小,剩下的就是body2。

body1

V1-body1

 

body1使用AES128-CFB进行加密,解密则需要aes-key和aes-iv。

 

根据上述密钥章节,solution-key和toolbox-key都可以导出aes-key,所以存在两份aes-key,至于使用哪一份aes-key,需要通过HMAC来确认。分别对两份aes-key进行HMAC\<SHA1\>算法,其中一份aes-key的结果将与HMAC相匹配。

 

aes-iv由8字节的AES-IV-DATA派生。首先取AES-IV-DATA的SHA256,得到32字节结果,再将32字节对折异或,得到16字节的aes-iv。简单的过程如下所示:

1
2
3
4
5
6
7
8
9
ArrayByte sha256_result;
SHA256 sha256;
StringSource(iv_data, true, new HashFilter(sha256, new StringSink(sha256_result)));
 
int i;
for (i = 0; i < 16; i++)
{
    sha256_result[i] ^= sha256_result[i + 16];
}

在得到aes-key和aes-iv后,就可以解密,以下是解密后的数据:

 

V1-body1-dec

 

解密后的数据先分成3部分,第一部分是开头7个字节,含义不明;第二部分是signature,用于检验下面的message;第三部分是message,存放一些matlab的配置信息。

 

message使用了非对称算法进行签名,密钥固定为complier-key,具体算法为RSASS<PKCS1v15, SHA1>,关于签名的编码规则、哈希算法、签名算法等有太多细节,请自行查阅相关资料,本文不再赘述。

message

V1-body1-message

 

如上图所示,message包含了多个部分的内容。

  1. 选中的20字节为solution-key的SHA1结果,如果修改了manifest.xml中的session-key,则此处将要同步修改。
  2. 下滑红线的数据是一个日期时间字符串,通常为25字符串,并以0x0A结尾。该日期是本文件构建的时间。
  3. 紧跟日期时间字符串未作任何标记的部分目前含义不明。
  4. 红框包围的部分是一段用户字符串,最大128字节,最后必须以0结尾。
  5. 橙框包围的一个字节是demo标志,当该值为1时,程序为演示模式,只能自本文件构建的时间起30天内运行。

body2

v1-body2

 

body2结构与body1相近,HMAC和AES-IV-DATA的用法与body1相同。

 

解密后,得到以下结构:

 

v1-body2-dec

 

从图中可以得知,结构主要分为3部分:

  1. 紫框包围的数据,含义不明,第一个字节的低4位(+3)指示了这部分数据的长度。例:0xAB低4位为0xB,+3后为0xE,故数据长度为14字节。
  2. 选中的128字节为signature,用于校验红框数据(解压后)。
  3. 剩余被红框包围数据是使用了zlib压缩的数据,使用zlib库即可解压。

uncompressed-data

红框数据解压后即可得到原始的脚本文件,见下图:

 

v1-body2-uncompressed

 

和原始的脚本文件比较,发现所有注释都被删除了,其他部分不变。以下是一部分的比较图:

 

V1-output-cmp

V2版本

以下展示加密脚本的部分截图:

 

V2-file

 

从上图可见,V2版本和V1版本在文件结构上稍有差别。

  • V2版本中HMAC校验是对整个文件进行的,V1版本是body1和body2分别进行的
  • V2版本用了8个字节来记录body2解压后的大小
  • V2版本body1和body2共用一份AES密钥,V1版本则需要分开独立计算。
  • V2版本直接提供aes-iv,V1版本提供的AES-IV-DATA需要转换一下才能得到aes-iv

body1

与V1版本类似,可以通过HMAC确定aes-key,不同的是,aes-iv是直接给出,无需计算。得到aes-key和aes-iv后,则可以使用AES128-CFB来进行解密。

 

V2-body1-dec

 

解密后的结构同样分为signature和message部分,signature部分用于检验message部分的完整性,使用的算法为 RSASS<PSS, SHA512>,密钥同样为complier-key。

message

V2-body1-message

  1. 位于最初的64字节是SHA512的16进制字符串,用于验证manifest.xml中的session-key的完整性。
  2. 下滑绿线的数据是一个日期时间字符串,通常为25字符串,并以0x0A结尾。该日期是本文件构建的时间。
  3. 后面跟着一推字符串,有UTF8编码的,也有UTF16编码的,目前这些字符串用途不明。
  4. 最后一个字节同样是demo_flag,用于与V1一致。

body2

body2同样需要解密,解密过程与body1一致(使用相同的aes-key和aes-iv)。

 

解密后还需要进行zlib解压。

uncompressed-data

v2-body2-uncompressed

 

解压后的数据结构很简单,一个signature部分和一个message部分。其中signature部分256字节,用于校验message部分的完整性,使用方法和body1一致。

 

message部分是明文脚本,与V1不同的是,V2版本中脚本的注释被保留下来了。

其他

  • 每个maltab运行库都有一个很好的参考例子(mps_check.ctf)。
  • mcc本质是个打包指令,根据内容的不同,打包的结构可能会有所不同。

普通的脚本文件打包结构正如本文所描述;而一些应用程序可能存在如下图情况:

 

应用程序打包结构

 

其中的mlapp并不是一个加密脚本,而是一个压缩包。真正的加密脚本被已经被打包到mlapp中,为了应对这种情况,在解析代码增加嵌套解压的过程(或许应该根据后缀名做不同的处理)。

  • matlab-key位于mclmcr.dll中,但无法直接在mclmcr.dll中搜索到该值,因为matlab-key使用比较简单的编码(加扰),如下图所示:

get-matlab-key


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞4
打赏
分享
打赏 + 61.00雪花
打赏次数 3 雪花 + 61.00
 
赞赏  mb_cueumvfu   +50.00 2023/07/18 感谢分享~
赞赏  mb_cueumvfu   +10.00 2023/07/18 感谢分享~
赞赏  mb_cueumvfu   +1.00 2023/07/18 感谢分享~
最新回复 (1)
雪    币: 19270
活跃值: (28900)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-6-5 09:24
2
1
mark
游客
登录 | 注册 方可回帖
返回