hen*_*nes 3 encryption ios firebase firebase-analytics
我们注意到我们的iOS应用正在将请求发送到http://app-measurement.com。主体似乎已被加密或压缩
:method: POST
:scheme: https
:path: /a
:authority: app-measurement.com
accept: */*
content-type: application/x-www-form-urlencoded
content-encoding: gzip
accept-language: en-gb
content-length: 371
accept-encoding: br, gzip, deflate
;
_uwa
_pfoq
_oauto
_r
_c_fݶ-
...
Run Code Online (Sandbox Code Playgroud)
我已经检查了它是否是gzip,但事实并非如此。
有谁知道如何解密才能看到请求内容?
它是一个 gzip 压缩的协议缓冲区 (protobuf)。使用解码工具,您可以看到所有有用的值和类型。尽管没有 .proto 定义,但很难弄清楚它的含义。
要解码请求,首先以原始形式获取它。我通过导出 HTTP .trace 文件并仅提取正文来完成此操作。我自己进行 gzip 解压的运气更好。
获得原始请求正文后,按如下方式对其进行解码:
$ gunzip - < request_body > request_uncompressed.bin
$ protoc --decode_raw < request_uncompressed.bin
Run Code Online (Sandbox Code Playgroud)
这是一个简单的 CyberChef 公式,也可以为您解码:https://gchq.github.io/CyberChef/#recipe=Gunzip()Protobuf_Decode('',false,false)
当它工作时,你会看到原始的 protobuf 值。它们看起来像这样(实际值随机化):
1 {
1: 1
2 {
1 {
1: "_si"
3: 161212808641
}
1 {
1: "_et"
3: 57
}
1 {
1: "_sc"
2: "SomeControllerName"
}
1 {
1: "_o"
2: "auto"
}
2: "_e"
3: 161236824
4: 163120534
}
2 {
1 {
1: "_si"
3: 1358166110
}
1 {
1: "_sc"
2: "SomeControllerName"
}
1 {
1: "_o"
2: "auto"
}
2: "_ab"
3: 161336826
4: 163123680
}
3 {
1: 163129524107
2: "_fi"
4: 1
}
3 {
1: 15514295
2: "_fot"
4: 15514241
}
3 {
1: 1530783276
2: "_sid"
4: 1530783376
}
...
8: "ios"
9: "13.5"
10: "iPhone12,3"
...
Run Code Online (Sandbox Code Playgroud)
来自 @lari 的更新:创建自定义 protobuf 定义来解码请求
在 Android 上,您可以启用详细日志记录,并在设备日志中查看 Firebase Analytics 以原始格式发送到服务器的内容。这是一个例子:
FA-SVC com.google.android.gms V Uploading data. app, uncompressed size, data: com.my.app, 9332,
batch {
bundle {
protocol_version: 1
platform: android
gmp_version: 46000
config_version: 1679644809123456
gmp_app_id: 1:123456789:android:aaaaaaaaaa
app_id: com.my.app
app_version: 1.0.0
app_version_major: 100
firebase_instance_id: xx_xxxx_xx
upload_timestamp_millis: 1681470819289
start_timestamp_millis: 1681468977430
app_instance_id: f8s9fa09vsa4a4lk2983fsdf
os_version: 9
user_property {
set_timestamp_millis: 1631520687985
name: first_open_time(_fot)
string_value:
int_value: 1631523600000
}
user_property {
set_timestamp_millis: 1681468712345
name: ga_session_id(_sid)
string_value:
int_value: 1681468788
}
event {
name: user_engagement(_e)
timestamp_millis: 1681468977430
previous_timestamp_millis: 1681468884057
param {
name: ga_event_origin(_o)
string_value: auto
}
param {
name: engagement_time_msec(_et)
string_value:
int_value: 90654
}
param {
name: ga_screen_class(_sc)
string_value: MyViewController
}
param {
name: ga_screen_id(_si)
string_value:
int_value: -13918239812398123
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过将其与编码版本(以数字作为键的版本)进行比较,您可以非常轻松地重新创建 .proto 定义的部分内容。
例如:
等等...
在此基础上,您可以创建自定义定义,例如:
// app-measurement.proto
syntax = "proto3";
package app_measurement;
message Bundle {
message Event {
string name = 2;
}
repeated Event event = 2;
}
message Batch {
repeated Bundle bundle = 1;
}
Run Code Online (Sandbox Code Playgroud)
并用它来解码消息:
FA-SVC com.google.android.gms V Uploading data. app, uncompressed size, data: com.my.app, 9332,
batch {
bundle {
protocol_version: 1
platform: android
gmp_version: 46000
config_version: 1679644809123456
gmp_app_id: 1:123456789:android:aaaaaaaaaa
app_id: com.my.app
app_version: 1.0.0
app_version_major: 100
firebase_instance_id: xx_xxxx_xx
upload_timestamp_millis: 1681470819289
start_timestamp_millis: 1681468977430
app_instance_id: f8s9fa09vsa4a4lk2983fsdf
os_version: 9
user_property {
set_timestamp_millis: 1631520687985
name: first_open_time(_fot)
string_value:
int_value: 1631523600000
}
user_property {
set_timestamp_millis: 1681468712345
name: ga_session_id(_sid)
string_value:
int_value: 1681468788
}
event {
name: user_engagement(_e)
timestamp_millis: 1681468977430
previous_timestamp_millis: 1681468884057
param {
name: ga_event_origin(_o)
string_value: auto
}
param {
name: engagement_time_msec(_et)
string_value:
int_value: 90654
}
param {
name: ga_screen_class(_sc)
string_value: MyViewController
}
param {
name: ga_screen_id(_si)
string_value:
int_value: -13918239812398123
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您将看到已识别的部分被 .proto 文件中的键名称替换,而其余部分仍保留为数字,例如:
bundle {
event {
name: "_e"
1 {
1: "_et"
3: 10856
}
1 {
1: "_o"
2: "auto"
}
3: 1680595820225
4: 1680595807912
}
...
Run Code Online (Sandbox Code Playgroud)
如果您需要其他工具的编译“描述符”,您可以使用以下--descriptor_set_out=标志创建它:
// app-measurement.proto
syntax = "proto3";
package app_measurement;
message Bundle {
message Event {
string name = 2;
}
repeated Event event = 2;
}
message Batch {
repeated Bundle bundle = 1;
}
Run Code Online (Sandbox Code Playgroud)
您可能会注意到,Firebase Analytics 还缩短了默认事件、参数和用户属性名称。例如 _e = user_engagement 和 _o = ga_event_origin。原始名称可以在 Android 和 iOS 的设备日志中看到。
我已经为 app-measurement.com 请求创建并发布了协议缓冲区定义的开源版本,并在 GitHub 中共享: https: //github.com/lari/firebase-ga4-app-measurement-protobuf
还有一篇博客文章提供了更多详细信息:https://larihaataja.com/firebase-ga4-app-measurement-com-calls/
在这里放火
此请求是Google Analytics for Firebase的一部分,用于报告来自客户端的分析事件。它经过高度压缩以最大程度地减少带宽使用。
没有API可以查看请求的原始内容,但是您可以在这里找到有关所收集数据的更多信息: