上节的最后,我们拿到asn1码流定义和几份证书,这节将会讲讲这些证书是如何使用的,以及证书的密钥到底从何而来。计算证书密钥的篇幅较长,可能会分为几部分进行讲解。
大多数人对于证书的概念都是从https中来的,而https中的证书只是证书的其中一种用法。证书存在的目的是保护数据不被篡改,这些数据包括了类似https这种通信过程中的流式数据,也包括了如驱动等这种文件形式的静态数据。
一份证书既要保证数据不能被黑客篡改,也要保证证书自身不被黑客篡改。证书保证自身不被篡改可以通过保存自身的哈希值,校验时从新计算哈希值再比较是否匹配即可,由于该过程无需其他信息介入,一般称之为自校验。另一种方法就是证书链,验证时需要依赖其他信息。证书链首先需要由机构(如CA)或个人颁发可信的根证书,再由根证书派生子证书,子证书的有效性需要由其父证书来验证,这样构成一条信任链。那么根证书又由谁来验证呢?根证书通常使用自校验来保护自身,在联网的情况下,还可以由颁发机构来确认根证书的有效性,所以证书的来源很重要。在访问https网址时,如果证书不是由权威机构颁发的,浏览器会提醒不安全的证书,不要输入任何银行相关信息,是不是很有画面感。
在CodeMeterLin中,通过binwalk发现一份写死的X509格式的证书,将该证书dump出来,发现其就是CodeMeter在授权过程中的根证书。在之后的crack中有可能需要替换该证书。
证书密钥生成依赖很多信息,其中绝大部分是系统的一些信息,这些信息会保存在cache目录下以wbc结尾的文件,下面是其中一份例子
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
|
[WIBU
-
SYSTEMS Control
File
]
Guid
=
{
000B0002
-
0000
-
1100
-
8005
-
0000C06B5161
}
Description
=
WIBU
-
SYSTEMS CmAct Inventory
Version
=
1.00
Encoding
=
UTF
-
8
[Inventory]
Nonce
=
FC614509DC105107F383B7990E0F8A8B7CC662BD019AF955CD412279D54058B0
RedundancyData
=
05917CAB89A1B76386E7841BED35007AC36939E593BAC650041A53DE4F1877E7486CDF7807B570004BF8F552410316398377D2382989750C6451519F41ADFB4D74FD2B4985C938EFA7BBF9A5BBB1FA5FC81AC3C6AA865999FD38D37F42DED58FBC512C342100
Version0
=
6
Version1
=
60
Version2
=
2869
Version3
=
0
Heuristic
=
2
Flags
=
0
ItemCount
=
3
[Item_0]
ID
=
8FC89925A8E3F0C4A12D831E74D3DBC1C53A71AA4D9366C0722E38A43281F3F8
Position
=
0
Length
=
242
Params
=
6735224F4F6BF13A0EA1691175CB0019
[Item_1]
ID
=
BFC045FC85508E4D26BBAD1671F2455222714D31093E35625E84C48B3D9BBF46
Position
=
242
Length
=
200
Params
=
FBCC39E7D3A7CA9D9DDED0A11524E4DF
[Item_2]
ID
=
FA7F259568064DF79A6892D62040528FABC75A58232F9251FE12E6CABFBE60CB
Position
=
442
Length
=
70
Params
=
DD99FE19AF93879E2793554558ADEB3C
[IdList]
ItemCount
=
12
ID_0
=
EAA4B2E09B3F5EBAE9A84DEA627A5A3D5505003B345A841A3146DD85B3998115
ID_1
=
2BCF074AD7FA3D8AD0FE5712FA7A59B5CD88BF3473BF28ADA934B2F8C6327ED5
ID_2
=
C719A8790F480388124654A0C4B1F8DAC3946AF7AB93A125DF2C8914672658A0
ID_3
=
8E84B3E94AE3167CE9195D7F69D4294B03CCF8886C4EA5EB5E20463000ECEFE7
ID_4
=
C30F4A5B326065A41656E137C8E313F8B76C8B4C415BD9AB380C99BE9B9DA176
ID_5
=
B336DB389BB24290FAFF0F413AF8E866B3C0620C8E87C09600C0FB1C580C70FB
ID_6
=
B881E0BE59EAD13303C2F272BAFAC4C13573699013384412EBD57F31B4D07AD6
ID_7
=
D39F76D2C477EB9B3A59A9928F2DF463963981139EA42E78AB87583E6A6B8CD8
ID_8
=
9E0E8B51704E9232188DBBC42DADD018A7BA38018EFD5F7F039A74E1DBEB21A9
ID_9
=
E1EA68645A901744AC0F1ECC59950B6B69DA55DF9D917EA20CF02E35A69B7088
ID_10
=
FD3A5CEAE15252CC1E41EED8A460C7E2D51F1B2568DA25B1308A8007C72A00A0
ID_11
=
83DEE544FC050F85B2B93A87B933757F8663B16EBD416C0ACE54DEE809B32310
|
每个item是系统参数的sha256值,只有每个sha256对上了,这份wbc文件才会被使用。
每一个获取系统参数的函数都对应一个编号,下图左侧是在间接调用函数获取系统信息,右侧是绑定编号和函数的过程。
以编号5001的函数为例,先看看该函数体。可以看到有一串奇怪的字符串,它的解码方式也很简单,ascii值减1就是正确的值,所以最后的字符串应该为/proc/sys/kernel/hostname,显然这个函数获取的是主机名。其他函数也有类似的编码字符串,解码方式都十分简单的。
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
|
_QWORD
*
__fastcall sub_70EE90(_QWORD
*
a1)
{
int
v2;
/
/
eax
int
v3;
/
/
ebp
unsigned __int64 v4;
/
/
rax
__int64 v5;
/
/
rdx
__m128i v6[
2
];
/
/
[rsp
+
0h
] [rbp
-
1C8h
] BYREF
struct stat stat_buf;
/
/
[rsp
+
20h
] [rbp
-
1A8h
] BYREF
char buf[
280
];
/
/
[rsp
+
B0h] [rbp
-
118h
] BYREF
*
a1
=
&qword_BB1640[
3
];
strcpy(v6[
0
].m128i_i8,
"0qspd0tzt0lfsofm/hostname"
);
v6[
0
]
=
_mm_add_epi8((__m128i)
-
1LL
, v6[
0
]);
if
( __xstat(
1
, v6[
0
].m128i_i8, &stat_buf) )
return
a1;
v2
=
open
(v6[
0
].m128i_i8,
0
);
v3
=
v2;
if
( v2 <
0
)
return
a1;
v4
=
read(v2, buf,
0x100uLL
);
v5
=
255LL
;
if
( v4 <
=
0xFE
)
{
LOBYTE(v5)
=
0
;
if
( v4 )
v5
=
v4
-
1
;
}
buf[v5]
=
0
;
sub_80BCF0(a1, buf, strlen(buf));
close(v3);
return
a1;
}
|
下面总结了不同编号对应的功能
编号 | 功能 |
---|---|
5001 | /proc/sys/kernel/hostname |
5002 | /sys/bus/i2c/drivers/i2c_adapter/module/srcversion |
5003 | |
6001 | |
6101 | /sys/class/dmi/id/product_name |
6102 | /sys/class/dmi/id/product_version |
6103 | /sys/class/dmi/id/sys_vendor |
6104 | /sys/class/dmi/id/board_version |
6105 | /sys/class/dmi/id/board_vendor |
6106 | /sys/class/dmi/id/board_name |
6107 | /sys/class/dmi/id/bios_date |
6108 | /sys/class/dmi/id/bios_vendor |
6109 | /sys/class/dmi/id/bios_version |
6110 | 运行/usr/bin/codemeter-info命令 |
7001 | 硬盘相关 |
7002 | 硬盘相关 |
7003 | 硬盘相关 |
8001 | |
8002 | /sys/class/power_supply |
8003 | /sys/class/drm |
8004 | |
8005 | 运行/usr/bin/codemeter-info命令 |
未完待续
更多【wibu证书 - 安全证书(一)】相关视频教程:www.yxfzedu.com