首页
社区
课程
招聘
[原创]wibu证书 - asn1码流
发表于: 2022-9-8 00:54 9535

[原创]wibu证书 - asn1码流

2022-9-8 00:54
9535

通过上一节的处理,我们拿到了asn1码流,这节我们将使用CodeMeterLin中asn1的定义进行更加有效的解析。

在wibu软授权系统中,大部分相关的数据都是使用asn1编码的,所以

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

除CHOICE和ANY外,每种ASN.1类型都有一个标签,该标签由一个类型号(class)和一个非负标签号(tag)组成。当且仅当它们的标签号相同时,ASN.1类型才抽象地相同。换句话说,ASN.1类型的名称不会影响其抽象含义,只有标签会影响它的抽象含义。
上述是asn1的描述,其中最关键的是每种asn1类型都有一个标签值这句话,这意味者我们通过标签值反过来找到asn1的定义。

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

bits结构如下图所示:

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

p/s用于表示TLV中的V是否为嵌套的TVL结构,当p/s为1时,表示存在嵌套。
tagv为具体的标签值,有效值为0-30,当tagv=31时,表示标签值使用长码表示,后面跟着的八元组为具体的标签值,直到八元组的最高bit不为0为止,此时八元组的最高位用于指示长码是否结束。
06

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

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

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

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

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

EXPLICITIMPLICIT关键字默认使用Context-specific作为cls,此外,可以通过PRIVATEAPPLICATION显示指定cls。

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

这里先放上一节的流程图,在sub_77A950中可以看到asn1码流的解析。
02
每个asn1类型被定义为一个结构体节点,一开始是无法准确地知道每个字段的含义。通过相关查找,确认这些节点都是在github上的开源代码asn1c-0.9.26中定义。于是,我们对这些asn1节点有了较为清晰的了解。
01

通过观察asn1结构体节点,可以发现一般情况下,name字段和xml_tag字段指向同一个字符串,并且所有的节点都在data段内。我们可以在data段找两个即相邻又相同的指针,并且该指针指向的内容同样在data段内。节点之间通过elements字段关联,利用elements,我们可以为这些节点建立树状关系或层级关系,甚至可以恢复出整个asn1定义。下图LIF的asn1定义。

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

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

 
2 bit 1 bit 5 bit
class p/s tagv
 
 
 
 
# !/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())
# !/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())
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 INTEGER
UInt32 ::= [PRIVATE 34] IMPLICIT INTEGER
Clocks ::= SEQUENCE
{
    box-time[PRIVATE 178] IMPLICIT Seconds-Since-2000,
    certified-time[PRIVATE 179] IMPLICIT Seconds-Since-2000
}
Seconds-Since-2000 ::= INTEGER
License-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 ::= INTEGER
Binding-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 ::= IA5String
Telephone-ID ::= INTEGER
Binding-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 ::= IA5String
DCBN-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
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 INTEGER
UInt32 ::= [PRIVATE 34] IMPLICIT INTEGER
Clocks ::= SEQUENCE
{
    box-time[PRIVATE 178] IMPLICIT Seconds-Since-2000,
    certified-time[PRIVATE 179] IMPLICIT Seconds-Since-2000
}
Seconds-Since-2000 ::= INTEGER
License-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 ::= INTEGER
Binding-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 ::= IA5String

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

最后于 2022-12-15 20:51 被bluefish蓝鱼编辑 ,原因: 新增asn1码流解析
上传的附件:
收藏
免费 3
支持
分享
最新回复 (3)
雪    币: 179
活跃值: (375)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
后续有windows平台的?
2022-10-9 22:15
0
雪    币: 10708
活跃值: (7627)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
wcdabcd 后续有windows平台的?
主要在linux平台逆向,后续应该不会在windows平台重新弄了
2022-10-15 16:02
0
雪    币: 179
活跃值: (375)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
什么时候讲讲后续内容?
2022-10-16 09:21
0
游客
登录 | 注册 方可回帖
返回
//