特别警告

文章仅供学习参考,严禁非法使用,如非法使用,而导致的一切后果,由使用者自行承担。


算法分析

ZTE系列 WEB交互是由goahead程序负责

使用编程器提取固件 解包 提取程序 (解包教程可以参考上一篇文章)

使用IDA分析程序 使用Shift+F12 进入字符串模式 Alt+T搜索 sim select 等字样

image.png

定位进入

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
.text:00015CF8                 PUSH.W          {R4-R11,LR}
.text:00015CFC SUB SP, SP, #0x24
.text:00015CFE ADD.W R10, SP, #0x48+s
.text:00015D02 ADD R4, SP, #0x48+var_44
.text:00015D04 MOV R5, R0
.text:00015D06 MOVS R1, #0 ; c
.text:00015D08 MOVS R2, #0x10 ; n
.text:00015D0A MOV R0, R10 ; s
.text:00015D0C LDR R6, =(byte_2A19B - 0x15D1C)
.text:00015D0E BLX memset
.text:00015D12 MOVS R1, #0 ; c
.text:00015D14 MOVS R2, #0xA ; n
.text:00015D16 MOV R0, R4 ; s
.text:00015D18 ADD R6, PC ; byte_2A19B
.text:00015D1A BLX memset
.text:00015D1E LDR R1, =(aSimSelect - 0x15D28) ; "sim_select"
.text:00015D20 MOV R2, R6
.text:00015D22 MOV R0, R5
.text:00015D24 ADD R1, PC ; "sim_select"
.text:00015D26 BL sub_DCE8
.text:00015D2A MOV R8, R0
.text:00015D2C LDR R0, =(aAlkSimSelectSi - 0x15D34) ; "alk_sim_select:sim_select->%s\n"
.text:00015D2E MOV R1, R8
.text:00015D30 ADD R0, PC ; "alk_sim_select:sim_select->%s\n"
.text:00015D32 BLX printf
.text:00015D36 LDR R1, =(aAdminPwd - 0x15D40) ; "admin_pwd"
.text:00015D38 MOV R0, R5
.text:00015D3A MOV R2, R6
.text:00015D3C ADD R1, PC ; "admin_pwd"
.text:00015D3E BL sub_DCE8
.text:00015D42 MOV R9, R0
.text:00015D44 LDR R0, =(aAlkSimSelectAd - 0x15D4C) ; "alk_sim_select:admin_pwd->%s\n"
.text:00015D46 MOV R1, R9
.text:00015D48 ADD R0, PC ; "alk_sim_select:admin_pwd->%s\n"
.text:00015D4A BLX printf
.text:00015D4E CMP.W R8, #0
.text:00015D52 BNE loc_15D64
.text:00015D54 LDR R0, =(aAlkSimSelectEm - 0x15D5A) ; "alk_sim_select:empty!\n"
.text:00015D56 ADD R0, PC ; "alk_sim_select:empty!\n"
.text:00015D58 BLX printf
.text:00015D5C LDR R1, =(aFailure - 0x15D64) ; "failure"
.text:00015D5E MOV R0, R5
.text:00015D60 ADD R1, PC ; "failure"
.text:00015D62 B loc_15E66
.text:00015D64 ; ---------------------------------------------------------------------------

选定Push Alt+P Create Function 再F5转伪C

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
// 这里只粘贴了部分关键代码
if (++v8 == 15) {
sprintf(v15, "%c%c", (unsigned __int8) s[3], (unsigned __int8) s[6]);
// 取IMEI 4位/7位 拼接
printf("[%s]:admin_code %s\n", "alk_sim_select", v15);
v9 = atoi(v15) + 125;
// v15 与 125 相加
memset(v15, 0, 0xA u);
sub_15C9C(v15, (int) s, 15);
// 调用sub_15C9C方法计算
v10 = 4 * (atoi(v15) + v9);
// 得到sub_15C9C计算结果与v9相加 再*4 得到密码
printf("[%s]:pwd_code %d\n", "alk_sim_select", v10);
memset(v15, 0, 0xA u);
sprintf(v15, "%d", v10);
if (strlen(v3) && !strcmp(v3, v15)) {
v11 = cfg_set( & unk_2D55D, v2);
cfg_save(v11);
cfg_set("switch_sim_flag", "1");
v12 = strcmp(v2, "1");
if (v12) {
v12 = 0;
v13 = "AT+ZCARDSWITCH=3\r\n";
} else {
v13 = "AT+ZCARDSWITCH=0\r\n";
}
get_modem_info(v13, v12, v12);
sleep(1 u);
v4 = a1;
v5 = "success";
} else {
printf("alk_sim_select:wrong pwd!\n");
v4 = a1;
v5 = "failure";
}
return sub_1B0E4(v4, v5);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// sub_15C9C 方法
int __fastcall sub_15C9C(char *a1, int a2, int a3)
{
char v6; // r3
char s[36]; // [sp+4h] [bp-24h] BYREF

memset(s, 0, 0xAu);
strcpy(s, (const char *)(a3 - 6 + a2));
// 取末尾6位
v6 = s[1];
s[1] = s[2];
s[2] = v6;
// 交换取值2-3位
sprintf(a1, "%s", s);
return printf("[%s] generate pwd %s\n", "alk_generate_password", a1);
}

算法转写

1
2
3
4
5
6
7
8
9
10
11
12
# Python版本
imei = "123456789012345"
a = imei[3] + imei[6] # 47 = 4 + 7
b = int(a) + 0x7d # 172 = 47 + 125
c = imei[-6:] # 012345
d = c[0x0] + c[0x2] + c[0x1] + c[-3:] # 021345
f = int(d) + b # 021345 + 172
e = 0x4 * f # 4 * 021517
print(e) # 86068

# 一句话版本
4 * (int(imei[-6:][0] + imei[-6:][2] + imei[-6:][1] + imei[-6:][-3:]) + (int(imei[3] + imei[6]) + 125))
1
2
3
// Javascript版本
const imei = "123456789012345";
console.log(4 * (parseInt(imei.slice(-6)[0x0] + imei.slice(-6)[0x2] + imei.slice(-6)[0x1] + imei.slice(-6).slice(-3)) + (parseInt(imei[3] + imei[6]) + 0x7d)))

在线计算