【Android安全-字节某条设备注册算法分析】此文章归类为:Android安全。
基于“9.5.4”版本分析还原设备注册代码,测试通过
设备注册接口请求及返回内容如下:
在 Jadx 中搜索 device_register 找到类 X.1pd,trace 发现堆栈都带 Applog类:
继续跟踪Applog的函数(数据量有点大,重定向到文件中分析),看到堆栈中有一个网络接口的实现类:
继续 trace 该类,发现某次调用返回和抓包得到的数据匹配
类似的逻辑层层关联分析(绕了不少弯路),最终找到直接打印请求及加密结果的类 X.1rb ,请求体原文如下:
{ "header":{ "os":"Android", "os_version":"9", "os_api":28, "device_model":"Pixel", "device_brand":"google", "device_manufacturer":"Google", "cpu_abi":"arm64-v8a", "channel":"article_download_page", "not_request_sender":1, "aid":13, "release_build":"1111111111111111", "custom":{ "cold_start":true }, "density_dpi":420, "display_density":"mdpi", "resolution":"1794x1080", "display_density_v2":"xxhdpi", "resolution_v2":"1920x1080", "language":"zh", "timezone":8, "region":"CN", "tz_name":"Asia\/Shanghai", "tz_offset":28800, "access":"wifi", "package":"com.ss.android.article.news", "app_version":"9.5.4", "app_version_minor":"", "version_code":954, "update_version_code":95407, "manifest_version_code":9540, "app_name":"news_article", "tweaked_channel":"article_download_page", "display_name":"今日头条", "rom":"5670241", "rom_version":"PQ3A.190801.002", "sig_hash":"11111111111111111", "clientudid":"1111111111111111", "openudid":"1111111111111111", "cdid":"1111111111111111111", "appkey":"4fd805175270154a3c000005", "mc":"111111111111111", "sim_serial_number":[ ], "oaid_may_support":false, "device_platform":"android", "git_hash":"8a70419", "sdk_version_code":4000184, "sdk_target_version":30, "req_id":"11111111111111111111", "sdk_version":"4.0.1-rc.34-toutiao", "guest_mode":0, "sdk_flavor":"cnInner", "pre_installed_channel":"", "apk_first_install_time":1111111111, "is_system_app":0 }, "magic_tag":"ss_app_log", "_gen_time":11111111 }
直接查看 X.1rb 类中加密过程:
加密函数实现:
创建一个 Android 工程,直接把相关代码抠出来:
编写设备注册类:
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
package
com.example.deviceregister;
import
android.net.Uri;
import
android.util.Log;
import
com.bytedance.frameworks.encryptor.EncryptorUtil;
import
org.json.JSONObject;
import
java.io.BufferedReader;
import
java.io.ByteArrayOutputStream;
import
java.io.DataOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.InputStreamReader;
import
java.net.HttpURLConnection;
import
java.net.URL;
import
java.util.UUID;
import
java.util.zip.GZIPOutputStream;
public
class
DeviceRegister {
static
String TAG =
"DeviceReg"
;
private
static
String bodyTemplate =
"{\"header\":{\"os\":\"Android\",\"os_version\":\"9\",\"os_api\":28,\"device_model\":\"Pixel\",\"device_brand\":\"google\",\"device_manufacturer\":\"Google\",\"cpu_abi\":\"arm64-v8a\",\"channel\":\"article_download_page\",\"not_request_sender\":1,\"aid\":13,\"release_build\":\"11111111\",\"custom\":{\"cold_start\":true},\"density_dpi\":420,\"display_density\":\"mdpi\",\"resolution\":\"1794x1080\",\"display_density_v2\":\"xxhdpi\",\"resolution_v2\":\"1920x1080\",\"language\":\"zh\",\"timezone\":8,\"region\":\"CN\",\"tz_name\":\"Asia\\/Shanghai\",\"tz_offset\":28800,\"access\":\"wifi\",\"package\":\"com.ss.android.article.news\",\"app_version\":\"9.5.4\",\"app_version_minor\":\"\",\"version_code\":954,\"update_version_code\":95407,\"manifest_version_code\":9540,\"app_name\":\"news_article\",\"tweaked_channel\":\"article_download_page\",\"display_name\":\"今日头条\",\"rom\":\"5670241\",\"rom_version\":\"PQ3A.190801.002\",\"sig_hash\":\"aea615ab910015038f73c47e45d21466\",\"clientudid\":\"11111111\",\"openudid\":\"11111111\",\"cdid\":\"11111111\",\"appkey\":\"4fd805175270154a3c000005\",\"mc\":\"11111111\",\"sim_serial_number\":[],\"oaid_may_support\":false,\"device_platform\":\"android\",\"git_hash\":\"8a70419\",\"sdk_version_code\":4000184,\"sdk_target_version\":30,\"req_id\":\"11111111\",\"sdk_version\":\"4.0.1-rc.34-toutiao\",\"guest_mode\":0,\"sdk_flavor\":\"cnInner\",\"pre_installed_channel\":\"\",\"apk_first_install_time\":11111111,\"is_system_app\":0},\"magic_tag\":\"ss_app_log\",\"_gen_time\":11111111}"
;
public
static
byte
[] gzipAndEnc(String str) {
if
(str ==
null
|| str.length() ==
0
) {
return
null
;
}
ByteArrayOutputStream out =
new
ByteArrayOutputStream();
GZIPOutputStream gzip;
try
{
gzip =
new
GZIPOutputStream(out);
gzip.write(str.getBytes(
"UTF-8"
));
gzip.close();
}
catch
(IOException e) {
Log.e(TAG,
"gzip error:"
+ e.getMessage());
}
byte
[] gzipout = out.toByteArray();
Log.e(TAG,
"gzip out-len:"
+ Integer.toHexString(gzipout.length));
byte
[] ret = EncryptorUtil.ttEncrypt(gzipout, gzipout.length);
Log.e(TAG,
"encrypt out-len:"
+ Integer.toHexString(ret.length));
return
ret;
}
public
static
byte
[] genBody(String req_id) {
try
{
JSONObject json =
new
JSONObject(bodyTemplate);
JSONObject header = json.getJSONObject(
"header"
);
header.put(
"release_build"
,
"11111"
);
header.put(
"clientudid"
, UUID.randomUUID().toString());
header.put(
"openudid"
,
"111111"
);
header.put(
"cdid"
, UUID.randomUUID().toString());
header.put(
"mc"
,
"02:00:00:00:00:00"
);
header.put(
"req_id"
, req_id);
header.put(
"apk_first_install_time"
, System.currentTimeMillis());
json.put(
"header"
, header);
json.put(
"_gen_time"
, System.currentTimeMillis());
Log.d(TAG, json.toString());
return
gzipAndEnc(json.toString());
}
catch
(Exception e) {
throw
new
RuntimeException(e);
}
}
public
static
String request() {
String req_id = UUID.randomUUID().toString();
String reqUri =
"https://log.snssdk.com/service/2/device_register/"
;
Uri uri = Uri.parse(reqUri);
Uri.Builder uriBuilder = uri.buildUpon();
uriBuilder.appendQueryParameter(
"req_id"
, req_id);
uriBuilder.appendQueryParameter(
"tt_data"
,
"a"
);
uriBuilder.appendQueryParameter(
"cronet_version"
,
"ff3f7153_2023-10-11"
);
uriBuilder.appendQueryParameter(
"ttnet_version"
,
"4.2.137.21-toutiao"
);
uriBuilder.appendQueryParameter(
"use_store_region_cookie"
,
"1"
);
String result =
""
;
try
{
URL url =
new
URL(uriBuilder.build().toString());
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod(
"POST"
);
connection.setRequestProperty(
"Content-Type"
,
"application/octet-stream;tt-data=a"
);
connection.setRequestProperty(
"Accept-Encoding"
,
"gzip, deflate"
);
connection.setRequestProperty(
"User-Agent"
,
"com.ss.android.article.news/9540 (Linux; U; Android 9; zh_CN_#Hans; Pixel; Build/PQ3A.190801.002; Cronet/TTNetVersion:ff3f7153 2023-10-11 QuicVersion:ec35dc6e 2023-10-11)"
);
connection.setRequestProperty(
"x-ss-req-ticket"
, String.valueOf(System.currentTimeMillis()));
connection.setDoInput(
true
);
connection.setDoOutput(
true
);
DataOutputStream outputStream =
new
DataOutputStream(connection.getOutputStream());
outputStream.write(genBody(req_id));
outputStream.flush();
outputStream.close();
InputStream inputStream = connection.getInputStream();
int
status = connection.getResponseCode();
Log.d(TAG,
"reponse-status: "
+ String.valueOf(status));
if
(inputStream !=
null
){
BufferedReader bufferedReader =
new
BufferedReader(
new
InputStreamReader(inputStream));
String line=
""
;
while
((line = bufferedReader.readLine()) !=
null
) {
Log.d(TAG,
"reponse-line: "
+ line);
result += (line+
"\n"
);
}
}
else
{
result =
"post ret null!"
;
}
}
catch
(Exception e) {
Log.d(TAG,
"post err: "
+ e.toString());
}
Log.d(TAG,
"post ret: "
+ result);
return
result;
}
}
|
更多【Android安全-字节某条设备注册算法分析】相关视频教程:www.yxfzedu.com