首页
社区
课程
招聘
[原创]联通营业厅App登录分析
发表于: 2026-1-19 20:24 1069

[原创]联通营业厅App登录分析

2026-1-19 20:24
1069

本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

同事王二狗有2个联通号码,但是手机上只能登录一个账号,于是就有了接下来的分析。

掏出Charles抓包,如图,只有2个参数是加密的,mobile和password
图片描述

在IDA中搜索mobile
图片描述
这就直接终结了!!!
两个参数全在这里,相同算法相同密钥!!!
边分析边写帖子,这突然就结束了。

由千问老师赞助

总结本次分析难度较低,已经分析了,就发出来吧。

import secrets
import string
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
 
 
def random_string_with_length(length):
    """生成指定长度的随机字母数字字符串"""
    characters = string.ascii_letters + string.digits
    return ''.join(secrets.choice(characters) for _ in range(length))
 
 
def rsa_encrypt_with_public_key(data_str, public_key_str):
    """
    使用公钥字符串对字符串数据进行 RSA 加密 (PKCS1_v1_5 填充)
    """
    # 将 PEM 格式的公钥字符串加载为 RSA 对象
    public_key = RSA.import_key(public_key_str)
 
    # 创建加密器
    cipher_rsa = PKCS1_v1_5.new(public_key)
 
    # 将输入字符串编码为 UTF-8 字节
    data_bytes = data_str.encode('utf-8')
 
    # 执行加密
    encrypted_bytes = cipher_rsa.encrypt(data_bytes)
 
    # 将加密后的字节转换为 Base64 编码的字符串
    encrypted_b64_str = base64.b64encode(encrypted_bytes).decode('utf-8')
 
    return encrypted_b64_str
 
 
def prepare_login_info(username, password):
 
    # 步骤 1: 处理密码
    # 生成 6 位随机盐
    password_salt = random_string_with_length(6)
    # 拼接密码和盐
    salted_password = password + password_salt
    # 加密拼接后的密码
    encrypted_password = rsa_encrypt_with_public_key(salted_password, PUBLIC_KEY)
 
    # 步骤 2: 处理用户名
    # 生成 6 位随机盐
    username_salt = random_string_with_length(6)
    # 拼接用户名和盐
    salted_username = username + username_salt
    # 加密拼接后的用户名
    encrypted_username = rsa_encrypt_with_public_key(salted_username, PUBLIC_KEY)
 
    # 步骤 3: 构建结果字典 (模拟原始代码返回的 NSMutableDictionary)
    login_info_dict = {
        "keyVersion": "2",
        "mobile": encrypted_username,  # 注意:这里用 'mobile' 键存储用户名
        "password": encrypted_password,
        "loginStyle": "0"
    }
 
    return login_info_dict
 
 
# --- 配置 ---
PUBLIC_KEY = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc+CZK9bBA9IU+gZUOc6FUGu7y
O9WpTNB0PzmgFBh96Mg1WrovD1oqZ+eIF4LjvxKXGOdI79JRdve9NPhQo07+uqGQ
gE4imwNnRx7PFtCRryiIEcUoavuNtuRVoBAm6qdB0SrctgaqGfLgKvZHOnwTjyNq
jBUxzMeQlEC2czEMSwIDAQAB
-----END PUBLIC KEY-----'''
 
# --- 示例用法 ---
if __name__ == "__main__":
    my_username = "your_username_here"
    my_password = "your_password_here"
 
    result = prepare_login_info(my_username, my_password)
    print("Prepared Login Info Dictionary:")
    for key, value in result.items():
        print(f"  {key}: {value}")
 
    print("\n--- Individual Encrypted Values ---")
    # 如果你只需要单独的加密值
    username_salt = random_string_with_length(6)
    password_salt = random_string_with_length(6)
 
    # 由于 random_string_with_length 是随机的,上面函数内部已经计算了一次
    # 为了演示单独调用,我们再次计算(结果会不同)
    temp_salted_user = my_username + random_string_with_length(6)
    temp_salted_pass = my_password + random_string_with_length(6)
 
    # 实际上,你应该像 prepare_login_info 函数那样,在同一次调用中使用相同的盐
    # 重新执行以获取一致的值
    final_result = prepare_login_info(my_username, my_password)
    print(f"Encrypted Mobile (Username): {final_result['mobile']}")
    print(f"Encrypted Password: {final_result['password']}")
import secrets
import string
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
 
 
def random_string_with_length(length):
    """生成指定长度的随机字母数字字符串"""
    characters = string.ascii_letters + string.digits
    return ''.join(secrets.choice(characters) for _ in range(length))
 
 
def rsa_encrypt_with_public_key(data_str, public_key_str):
    """
    使用公钥字符串对字符串数据进行 RSA 加密 (PKCS1_v1_5 填充)
    """
    # 将 PEM 格式的公钥字符串加载为 RSA 对象
    public_key = RSA.import_key(public_key_str)
 
    # 创建加密器
    cipher_rsa = PKCS1_v1_5.new(public_key)
 
    # 将输入字符串编码为 UTF-8 字节
    data_bytes = data_str.encode('utf-8')
 
    # 执行加密
    encrypted_bytes = cipher_rsa.encrypt(data_bytes)
 
    # 将加密后的字节转换为 Base64 编码的字符串
    encrypted_b64_str = base64.b64encode(encrypted_bytes).decode('utf-8')
 
    return encrypted_b64_str
 
 
def prepare_login_info(username, password):
 
    # 步骤 1: 处理密码
    # 生成 6 位随机盐
    password_salt = random_string_with_length(6)
    # 拼接密码和盐
    salted_password = password + password_salt
    # 加密拼接后的密码
    encrypted_password = rsa_encrypt_with_public_key(salted_password, PUBLIC_KEY)
 
    # 步骤 2: 处理用户名

传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 16
支持
分享
最新回复 (15)
雪    币: 155
活跃值: (4096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享。
2026-1-20 15:49
0
雪    币: 155
活跃值: (4096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享。
2026-1-20 15:50
0
雪    币: 155
活跃值: (4096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享。
2026-1-20 15:50
0
雪    币: 155
活跃值: (4096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

网络问题,重复发了。麻烦版主删除重复的帖子。

最后于 2026-1-20 15:53 被xingbing编辑 ,原因:
2026-1-20 15:50
0
雪    币: 8810
活跃值: (6642)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2026-1-20 16:09
0
雪    币: 2163
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2026-1-20 17:35
0
雪    币: 209
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
66
5天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
66
5天前
0
雪    币: 225
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
666666
2天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
6666
2天前
0
雪    币: 6260
活跃值: (6055)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
6
1天前
0
雪    币: 153
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
6666
1天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
111
1天前
0
雪    币: 54
活跃值: (3375)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
666
18小时前
0
雪    币: 0
活跃值: (66)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
瞧瞧看········
18小时前
0
游客
登录 | 注册 方可回帖
返回