【JS 逆向百例】steam 登录 Protobuf 协议详解
字数 1248 2025-08-18 11:36:53

Steam登录Protobuf协议逆向分析教程

1. 目标分析

目标网站:Steam登录页面(已脱敏处理)
主要接口:

  1. GetPasswordRSAPublicKey/v1 - 获取RSA公钥信息
  2. BeginAuthSessionViaCredentials/v1 - 登录接口

2. Protobuf协议基础

Protocol Buffers (Protobuf) 是Google开发的一种数据序列化协议,特点:

  • 根据特定语法定义数据结构
  • 发送和接收数据需要预先约定数据字段
  • 体积小、解析速度快

常见数据类型:

数据类型 描述
int32/int64 有符号整数
uint32/uint64 无符号整数
float/double 浮点数
bool 布尔值
string 字符串
bytes 二进制数据
enum 枚举类型
message 消息类型(可嵌套)
map 键值对映射
repeated 数组/列表

3. 第一个接口:GetPasswordRSAPublicKey/v1

3.1 请求参数分析

请求参数为 input_protobuf_encoded,其生成过程:

  1. 构造包含账号信息的对象
  2. 序列化为Protobuf二进制格式
  3. Base64编码

JavaScript关键代码:

o = n.SerializeBody();
a = r.JQ(o); // Base64编码

3.2 Protobuf消息定义

账号请求消息结构:

syntax = "proto3";

message CAuthenticationGetPasswordRsaPublicKeyRequest {
  string account_name = 1;
}

3.3 Python实现

生成Python代码:

protoc --python_out=. steam.proto

请求示例:

import base64
from steam_pb2 import CAuthenticationGetPasswordRsaPublicKeyRequest

message = CAuthenticationGetPasswordRsaPublicKeyRequest(
    account_name="a123456789"
)
protobuf = base64.b64encode(message.SerializeToString()).decode()

3.4 响应解析

响应消息结构:

message CAuthenticationGetPasswordRsaPublicKeyResponse {
  string publickey_mod = 1;   // RSA模数
  string publickey_exp = 2;   // RSA指数
  uint64 timestamp = 3;      // 时间戳
}

Python解析响应:

from steam_pb2 import CAuthenticationGetPasswordRsaPublicKeyResponse

response = CAuthenticationGetPasswordRsaPublicKeyResponse.FromString(response.content)
print(response.publickey_mod)
print(response.publickey_exp)
print(response.timestamp)

4. 第二个接口:BeginAuthSessionViaCredentials/v1

4.1 请求参数分析

请求消息结构:

message CAuthenticationBeginAuthSessionViaCredentialsRequest {
  string device_friendly_name = 1;
  string account_name = 2;
  string encrypted_password = 3;       // RSA加密后的密码
  uint64 encryption_timestamp = 4;     // 时间戳
  bool remember_login = 5;
  int32 platform_type = 6;
  int32 persistence = 7;
  string website_id = 8;
  DeviceDetails device_details = 9;    // 自定义类型
  string guard_data = 10;
  uint32 language = 11;
  int32 qos_level = 12;
}

message DeviceDetails {
  // 设备详情字段定义
  // 根据实际JS代码补充具体字段
}

4.2 密码加密过程

使用第一个接口返回的公钥信息进行RSA加密:

  1. 使用 publickey_modpublickey_exp 构造公钥
  2. 对密码进行RSA加密
  3. 将加密结果作为 encrypted_password 字段

JavaScript加密代码:

h.IC(a, t)  // a为密码明文,t为公钥信息

5. 完整Python实现

5.1 获取RSA公钥

import base64
import requests
from steam_pb2 import CAuthenticationGetPasswordRsaPublicKeyRequest

def get_rsa_public_key(username):
    origin = 'https://steamcommunity.com'
    message = CAuthenticationGetPasswordRsaPublicKeyRequest(
        account_name=username
    )
    protobuf = base64.b64encode(message.SerializeToString()).decode()
    
    url = 'https://api.steampowered.com/IAuthenticationService/GetPasswordRSAPublicKey/v1'
    params = {
        "origin": origin,
        "input_protobuf_encoded": protobuf
    }
    
    response = requests.get(url, params=params, headers=headers)
    return response.content

5.2 登录请求

from steam_pb2 import CAuthenticationBeginAuthSessionViaCredentialsRequest

def login(username, encrypted_pwd, timestamp):
    message = CAuthenticationBeginAuthSessionViaCredentialsRequest(
        account_name=username,
        encrypted_password=encrypted_pwd,
        encryption_timestamp=timestamp,
        # 其他必填字段...
    )
    
    protobuf = base64.b64encode(message.SerializeToString()).decode()
    
    url = 'https://api.steampowered.com/IAuthenticationService/BeginAuthSessionViaCredentials/v1'
    params = {
        "input_protobuf_encoded": protobuf
    }
    
    response = requests.get(url, params=params, headers=headers)
    return response.content

6. 关键点总结

  1. Protobuf消息定义:必须严格按照JS代码中的字段定义
  2. 序列化与编码:Protobuf序列化后需要Base64编码
  3. RSA加密:使用第一个接口返回的模数和指数构造公钥
  4. 设备信息device_details 是自定义类型,需要根据实际情况定义
  5. 响应解析:使用对应的Protobuf消息类解析响应内容

7. 注意事项

  1. 本教程仅供学习交流使用
  2. 严禁用于商业用途和非法用途
  3. 实际实现时需要补充完整的字段定义
  4. 网站接口可能随时变更,需要动态调整

通过以上步骤,可以完整实现Steam登录的Protobuf协议逆向分析。实际应用中还需要处理加密、会话管理等其他细节。

Steam登录Protobuf协议逆向分析教程 1. 目标分析 目标网站:Steam登录页面(已脱敏处理) 主要接口: GetPasswordRSAPublicKey/v1 - 获取RSA公钥信息 BeginAuthSessionViaCredentials/v1 - 登录接口 2. Protobuf协议基础 Protocol Buffers (Protobuf) 是Google开发的一种数据序列化协议,特点: 根据特定语法定义数据结构 发送和接收数据需要预先约定数据字段 体积小、解析速度快 常见数据类型: | 数据类型 | 描述 | |---------|------| | int32/int64 | 有符号整数 | | uint32/uint64 | 无符号整数 | | float/double | 浮点数 | | bool | 布尔值 | | string | 字符串 | | bytes | 二进制数据 | | enum | 枚举类型 | | message | 消息类型(可嵌套) | | map | 键值对映射 | | repeated | 数组/列表 | 3. 第一个接口:GetPasswordRSAPublicKey/v1 3.1 请求参数分析 请求参数为 input_protobuf_encoded ,其生成过程: 构造包含账号信息的对象 序列化为Protobuf二进制格式 Base64编码 JavaScript关键代码: 3.2 Protobuf消息定义 账号请求消息结构: 3.3 Python实现 生成Python代码: 请求示例: 3.4 响应解析 响应消息结构: Python解析响应: 4. 第二个接口:BeginAuthSessionViaCredentials/v1 4.1 请求参数分析 请求消息结构: 4.2 密码加密过程 使用第一个接口返回的公钥信息进行RSA加密: 使用 publickey_mod 和 publickey_exp 构造公钥 对密码进行RSA加密 将加密结果作为 encrypted_password 字段 JavaScript加密代码: 5. 完整Python实现 5.1 获取RSA公钥 5.2 登录请求 6. 关键点总结 Protobuf消息定义 :必须严格按照JS代码中的字段定义 序列化与编码 :Protobuf序列化后需要Base64编码 RSA加密 :使用第一个接口返回的模数和指数构造公钥 设备信息 : device_details 是自定义类型,需要根据实际情况定义 响应解析 :使用对应的Protobuf消息类解析响应内容 7. 注意事项 本教程仅供学习交流使用 严禁用于商业用途和非法用途 实际实现时需要补充完整的字段定义 网站接口可能随时变更,需要动态调整 通过以上步骤,可以完整实现Steam登录的Protobuf协议逆向分析。实际应用中还需要处理加密、会话管理等其他细节。