查看原文
其他

wibu证书 - asn1码流

bluefish蓝鱼 看雪学苑 2023-03-04


本文为看雪论坛优秀文章

看雪论坛作者ID:bluefish蓝鱼





前言


本文将使用CodeMeterLin中asn1的定义进行解析。在wibu软授权系统中,大部分相关的数据都是使用asn1编码的,所以asn1码流十分重要!





环境


python3.7

asn1tools





知识储备


ASN.1


ASN全称为Abstract Syntax Notation dotone,是定义抽象数据类型形式的标准,描绘了与任何表示数据的编码技术无关的通用数据结构,目前只定义一个版本(ASN.1)。ASN.1有四种类型:

简单类型,是"原子的"并且没有任何组件;

具有组件的结构化类型;

标记类型,从其他类型派生;

其他类型,包括CHOICE类型和ANY类型。


除CHOICE和ANY外,每种ASN.1类型都有一个标签,该标签由一个类型号(class)和一个非负标签号(tag)组成。当且仅当它们的标签号相同时,ASN.1类型才抽象地相同。换句话说,ASN.1类型的名称不会影响其抽象含义,只有标签会影响它的抽象含义。

上述是asn1的描述,其中最关键的是每种asn1类型都有一个标签值这句话,这意味者我们通过标签值反过来找到asn1的定义。


TLV结构


ber编码是asn1中最基础一种的编码方式,它传输格式是TLV(Tag-Length-Value)三元组。

Tag,指定结构的类型和嵌套关系。

Length,长度字段,指示结构的体长

Value,该字段用来存放具体的数据或嵌套的TLV结构。


Tag


bits结构如下图所示:


class用于表示tagv所在的类属,分为以下四类:

Universal,asn1中最基础的类型都属于这个类属,如BOOLEAN、INTEGER,除该类属外,其他类属都是复合类型。

Application,特定于应用程序的类型都属于这个类属,目前已不推荐使用。

Private,特定于特定企业的类型都属于这个类属,本次分析的码流使用了该类属下的多个类型。

Context-specific,特定于特定结构化的类型都属于这个类属,用于标记特定的上下文,不同的上下文可能具有相同的tagv但其含义不同,在本次分析的码流也会出现这种情况。


p/s用于表示TLV中的V是否为嵌套的TVL结构,当p/s为1时,表示存在嵌套。

tagv为具体的标签值,有效值为0-30,当tagv=31时,表示标签值使用长码表示,后面跟着的八元组为具体的标签值,直到八元组的最高bit不为0为止,此时八元组的最高位用于指示长码是否结束。

Length


length表示TLV中的V的长度,不包含T和L的长度。
当length=0x80时,表示V为不定长数据,V最后要以两个00结尾。
当length=0x8?时,表示length使用长码,低7位表示长码的八元组数量。
当length为其他值时,表示length使用短码,该八元组就是具体长度。

Value


value为TLV结构中的具体数据,该数据既可以是表示特定内容的数据,也可以嵌套的TLV结构。根据tag的不同,Value有着不同的表现形式。


EXPLICIT和IMPLICIT关键字


默认情况下,大部分的asn1定义最终都是由Universal类属中的基础类型定义。

当使用EXPLICIT和IMPLICIT关键字修饰时,表示使用中括号[]中指定的tag来描述该定义。

EXPLICIT和IMPLICIT关键字的区别在于,前者直接使用中括号[]中的tag的替换原数据的tag,后者在原数据前额外增加新的tag,而原来的tag保留不变。

EXPLICIT和IMPLICIT关键字默认使用Context-specific作为cls,此外,可以通过PRIVATE和APPLICATION显示指定cls。


测试代码

# !/usr/bin/env python3# -*- coding:utf-8 -*- import asn1tools asn_def = "TEST DEFINITIONS ::= BEGIN\n"\ "Test ::= SEQUENCE\n"\ "{\n"\ "val1 INTEGER,\n"\ "val2[0] IMPLICIT INTEGER,\n"\ "val3[1] EXPLICIT INTEGER,\n"\ "val4[PRIVATE 2] IMPLICIT INTEGER,\n"\ "val5[PRIVATE 3] EXPLICIT INTEGER\n"\ "}\n"\ "END" asn_def = asn1tools.compile_string(asn_def, "der")asn_res = asn_def.encode("Test", {"val1":10,"val2":10,"val3":10,"val4":10,"val5":10})print(asn_res.hex().upper())


python .\test_asn.py

301302010A80010AA10302010AC2010AE30302010A

30 13 #cls=0(Universal) tag=16(SEQUENCE) len=19

02 01 0A #正常情况:cls=0(Universal) tag=2(INTEGER) len=1 data=10

80 01 0A #加IMPLICIT修饰符并使用tag=0描述该定义:cls=2(Context-specific) tag=0 len=1 data=10

A1 03 #加EXPLICIT修饰符,在原来的数据前额外添加tag:cls=2(Context-specific) tag=1 len=3

02 01 0A #与正常情况的数据相同,cls=0(Universal) tag=2(INTEGER) len=1 data=10

C2 01 0A #同时指定cls和tag,cls=3(Private) tag=2 len=1 data=10

E3 03 #cls=3(Private) tag=3 len=3

02 01 0A #与正常情况的数据相同,cls=0(Universal) tag=2(INTEGER) len=1 data=10





参考资料


asn.1 格式学习
ASN/1 TLV





开始分析


asn1节点


这里先放上一节的流程图,在sub_77A950中可以看到asn1码流的解析。

每个asn1类型被定义为一个结构体节点,一开始是无法准确地知道每个字段的含义。通过相关查找,确认这些节点都是在github上的开源代码asn1c-0.9.26(https://github.com/vlm/asn1c/tree/v0.9.26)中定义。于是,我们对这些asn1节点有了较为清晰的了解。


获取所有asn1节点


通过观察asn1结构体节点,可以发现一般情况下,name字段和xml_tag字段指向同一个字符串,并且所有的节点都在data段内。我们可以在data段找两个即相邻又相同的指针,并且该指针指向的内容同样在data段内。节点之间通过elements字段关联,利用elements,我们可以为这些节点建立树状关系或层级关系,甚至可以恢复出整个asn1定义。下图LIF的asn1定义。
LIF-CONTENT DEFINITIONS ::= BEGIN LIF-Content ::= [PRIVATE 228] IMPLICIT SEQUENCE{ sw-specs[PRIVATE 161] IMPLICIT Software-Specs, clocks[PRIVATE 100] IMPLICIT Clocks, license-description[PRIVATE 125] IMPLICIT License-Description, binding[PRIVATE 136] IMPLICIT Binding-Scheme, cmact-options[PRIVATE 133] IMPLICIT CmAct-Options, mask[PRIVATE 142] IMPLICIT Mask OPTIONAL}Software-Specs ::= SEQUENCE{ creator-name[PRIVATE 181] IMPLICIT UTF8String, creator-version[PRIVATE 165] IMPLICIT Format-Version, required-version[PRIVATE 122] IMPLICIT Format-Version}Format-Version ::= SEQUENCE{ sfl[PRIVATE 78] IMPLICIT UInt8, sfh[PRIVATE 84] IMPLICIT UInt8, feature-flags[PRIVATE 32] IMPLICIT UInt32}UInt8 ::= [PRIVATE 31] IMPLICIT INTEGERUInt32 ::= [PRIVATE 34] IMPLICIT INTEGERClocks ::= SEQUENCE{ box-time[PRIVATE 178] IMPLICIT Seconds-Since-2000, certified-time[PRIVATE 179] IMPLICIT Seconds-Since-2000}Seconds-Since-2000 ::= INTEGERLicense-Description ::= SEQUENCE{ license-description[PRIVATE 30] IMPLICIT OCTET STRING, -- BMPString, it does't work well in asn1tools, beacase asn1tools only support utf-8, but here is utf-16 firm-code[PRIVATE 114] IMPLICIT Firm-Code}Firm-Code ::= INTEGERBinding-Scheme ::= SEQUENCE{ cmact-id[PRIVATE 148] IMPLICIT CmAct-ID, telephone-id[PRIVATE 127] IMPLICIT Telephone-ID, binding-method[PRIVATE 128] EXPLICIT Binding-Method}CmAct-ID ::= IA5StringTelephone-ID ::= INTEGERBinding-Method ::= CHOICE{ smartbind[PRIVATE 129] IMPLICIT SmartBind-Parameters, custom-binding[PRIVATE 131] IMPLICIT CustomBinding-Parameters, dcbn-classic[PRIVATE 132] IMPLICIT DCBN-Parameters, nonebind[PRIVATE 231] IMPLICIT NULL, cm-server-ip[PRIVATE 232] IMPLICIT NULL, serial-number[PRIVATE 233] IMPLICIT NULL, random[PRIVATE 234] IMPLICIT NULL}SmartBind-Parameters ::= SEQUENCE{ heuristic[PRIVATE 31] IMPLICIT UInt8, redundancy-level[PRIVATE 130] IMPLICIT Redundancy-Level}Redundancy-Level ::= INTEGER CustomBinding-Parameters ::= IA5StringDCBN-Parameters ::= SEQUENCE{ disk[PRIVATE 1] IMPLICIT BOOLEAN, cpu-type[PRIVATE 1] IMPLICIT BOOLEAN, board[PRIVATE 1] IMPLICIT BOOLEAN, network[PRIVATE 1] IMPLICIT BOOLEAN, tolerance[PRIVATE 2] IMPLICIT UInt8 OPTIONAL}CmAct-Options ::= SEQUENCE{ allow-vm[PRIVATE 219] IMPLICIT BOOLEAN, allow-reimport[PRIVATE 220] IMPLICIT BOOLEAN}Mask ::= INTEGER END

解析asn1码流

有了这些节点和节点关系,我们就可以用它来解析码流了。接下来我们就来看看LIF文件里面到底有什么东西。先说结论吧,LIF文件包含一段LIF-content、两个证书和一段签名值。其中LIF-content包含一些授权信息和一些限制条件。两份证书和签名值用于验证LIF文件是否被修改。

以下是我使用asn1tools解析的Terra2314.WibuCmLIF(这个LIF我都不记得是从哪里弄来的,见附件)
<signed> <contentType> 1.2.840.113549.1.7.2 </contentType> <content> <version> 1 </version> <digestAlgorithms> <0> <0> 2.16.840.1.101.3.4.2.1 </0> </0> </digestAlgorithms> <contentInfo> <contentType> 1.3.6.1.4.1.44485.2.1 </contentType> <content> FF 81 64 81 C7 FF 81 21 37 DF 81 35 08 63 6D 62 6F 78 70 67 6D FF 81 25 12 DF 4E 02 00 01 DF 54 02 00 01 DF 20 05 00 00 00 00 00 FF 7A 12 DF 4E 02 00 01 DF 54 02 00 01 DF 20 05 00 00 00 00 00 FF 64 12 DF 81 32 05 00 27 2A DC 71 DF 81 33 05 00 27 04 8F 5F FF 7D 3A DE 30 54 00 65 00 72 00 72 00 61 00 20 00 43 00 6F 00 6E 00 74 00 61 00 69 00 6E 00 65 00 72 00 20 00 76 00 32 00 2E 00 33 00 2E 00 31 00 2E 00 34 00 DF 72 05 00 00 5B 91 26 FF 81 08 28 DF 81 14 04 32 30 30 31 DF 7F 05 00 00 00 00 00 FF 81 00 14 FF 81 04 10 C1 01 FF C1 01 FF C1 01 FF C1 01 00 C2 02 00 01 FF 81 05 0A DF 81 5B 01 00 DF 81 5C 01 00 </content> </contentInfo> <certificates> <0> 30 82 01 7B 30 82 01 28 A0 03 02 01 02 02 04 B2 D0 5E 01 30 0A 06 08 2A 86 48 CE 3D 04 03 02 30 26 31 15 30 13 06 03 55 04 0A 0C 0C 57 49 42 55 2D 53 59 53 54 45 4D 53 31 0D 30 0B 06 03 55 04 03 0C 04 52 6F 6F 74 30 1E 17 0D 31 35 30 31 30 31 30 30 30 30 30 30 5A 17 0D 33 35 31 32 33 31 32 33 35 39 35 39 5A 30 31 31 15 30 13 06 03 55 04 0A 0C 0C 57 49 42 55 2D 53 59 53 54 45 4D 53 31 18 30 16 06 03 55 04 03 0C 0F 57 69 62 75 2D 50 72 6F 64 75 63 74 69 6F 6E 30 4E 30 10 06 07 2A 86 48 CE 3D 02 01 06 05 2B 81 04 00 21 03 3A 00 04 32 37 DD 50 E5 A0 A5 A9 38 E2 88 47 36 13 12 39 26 B1 C2 FB 11 52 77 BE 21 88 45 BD A6 E0 14 EC F1 D1 99 05 8F 77 05 78 80 ED 3C C5 83 F9 EF 09 B9 E4 80 D7 8E 30 F2 4A 81 15 00 78 A4 68 59 55 F6 77 32 49 E8 57 6C 2A 5D 48 FB BB EA C6 E2 82 15 00 C6 8C 60 C4 C5 15 26 82 20 5B 1F 40 55 A3 F8 2D B9 A6 08 87 A3 16 30 14 30 12 06 03 55 1D 13 01 01 FF 04 08 30 06 01 01 FF 02 01 01 30 0A 06 08 2A 86 48 CE 3D 04 03 02 03 41 00 30 3E 02 1D 00 E1 5D F5 35 01 59 75 89 1E 7F 1A C8 F0 B1 7E 07 7C C1 0E 67 45 27 46 67 5A E0 52 26 02 1D 00 B6 E5 A1 AB CA 94 D5 B8 FE AB C7 94 94 10 07 83 92 61 F7 79 B4 DF F4 B3 4B 7B C7 74 </0> <1> 30 82 01 AF 30 82 01 5E A0 03 02 01 02 02 04 B2 D0 64 B3 30 0A 06 08 2A 86 48 CE 3D 04 03 02 30 31 31 15 30 13 06 03 55 04 0A 0C 0C 57 49 42 55 2D 53 59 53 54 45 4D 53 31 18 30 16 06 03 55 04 03 0C 0F 57 69 62 75 2D 50 72 6F 64 75 63 74 69 6F 6E 30 1E 17 0D 31 35 30 31 30 31 30 30 30 30 30 30 5A 17 0D 33 35 31 32 33 31 32 33 35 39 35 39 5A 30 20 31 10 30 0E 06 03 55 04 0A 0C 07 36 30 30 30 39 33 34 31 0C 30 0A 06 03 55 04 03 0C 03 4C 50 4B 30 4E 30 10 06 07 2A 86 48 CE 3D 02 01 06 05 2B 81 04 00 21 03 3A 00 04 50 54 29 9D 03 A7 3F 13 EB 24 35 3D BE 91 E9 A6 80 33 C3 01 57 52 81 3D AA 0B 6B 50 EB 57 59 44 07 92 E9 7B 0A 39 A2 9A 73 38 D2 B7 83 95 7B 85 26 00 C4 DB 37 35 68 C9 81 15 00 C6 8C 60 C4 C5 15 26 82 20 5B 1F 40 55 A3 F8 2D B9 A6 08 87 82 15 00 0B EB FF D7 68 9A 1C 9B 08 7A 60 5E 46 32 DB A3 96 26 42 92 A3 52 30 50 30 0F 06 03 55 1D 13 01 01 FF 04 05 30 03 01 01 00 30 0F 06 03 55 1D 0F 01 01 FF 04 05 03 03 00 0F 00 30 2C 06 0A 2B 06 01 04 01 82 DB 45 03 01 01 01 FF 04 1B FF 76 18 DF 72 03 5B 91 26 FF 78 0F DF 81 5D 01 FF DF 81 5E 01 FF DF 81 5F 01 FF 30 0A 06 08 2A 86 48 CE 3D 04 03 02 03 3F 00 30 3C 02 1C 34 EA 5B EB AD F0 70 17 22 A1 5B D0 E1 D0 B0 7A 16 16 2B CC CF E4 30 2F F8 D7 14 2B 02 1C 09 11 EB F5 07 49 36 AA B9 D7 6B 62 6F 7B 49 35 9E 1E EA 60 C0 2E 5B A2 DF D7 87 AF </1> </certificates> <signerInfos> <0> <version> 1 </version> <signerIdentifier> <subjectKeyIdentifier> 0B EB FF D7 68 9A 1C 9B 08 7A 60 5E 46 32 DB A3 96 26 42 92 </subjectKeyIdentifier> </signerIdentifier> <digestAlgorithm> <0> 2.16.840.1.101.3.4.2.1 </0> </digestAlgorithm> <digestEncryptionAlgorithm> <0> 1.2.840.10045.4.3.2 </0> </digestEncryptionAlgorithm> <encryptedDigest> 30 3D 02 1C 49 1D 06 76 D5 BE D1 E8 38 77 4B E5 64 A7 7C DF 9B 50 EB 1E 63 27 C5 3C 13 9A 86 73 02 1D 00 E4 3D 0E F8 FC CD 80 FD D1 57 3C 18 70 95 D6 8C 9E BF 85 6D A0 D7 EC 0D D9 9A 54 43 </encryptedDigest> </0> </signerInfos> </content></signed>




后续


接下来将会详细讲解如何使用asn1tools解析文件后缀为WibuCmLIF、WibuCmRaC,WibuCmRaU,并讲述其中几个关键密钥的生成和使用。




看雪ID:bluefish蓝鱼

https://bbs.kanxue.com/user-home-674195.htm

*本文由看雪论坛 bluefish蓝鱼 原创,转载请注明来自看雪社区


# 往期推荐

1.CVE-2022-21882提权漏洞学习笔记

2.wibu证书 - 初探

3.win10 1909逆向之APIC中断和实验

4.EMET下EAF机制分析以及模拟实现

5.sql注入学习分享

6.V8 Array.prototype.concat函数出现过的issues和他们的POC们



球分享

球点赞

球在看


点击“阅读原文”,了解更多!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存