返回首页

电子日记中的 BAC 漏洞:无需权限即可成为教师

研究揭示学校电子日记中关键访问控制破坏漏洞。该漏洞通过更改本地参数允许访问教师功能。尽管数百万学生数据泄露风险,相关部门仍忽略问题。

如何通过学校日记 BAC 漏洞获取教师权限?
Advertisement 728x90

## 学校电子日记 App 存在严重 BAC 漏洞:无需权限即可变身教师

在对一款流行学校电子日记 App 进行逆向工程的过程中,发现了一个严重的访问控制失效(BAC)漏洞,该漏洞允许任意用户获得教师功能的完全访问权限。代码分析显示,缺少服务器端权限检查,并且密钥以明文形式存储。

逆向工程揭示安全弱点

调查从使用 JADX 反编译器分析 App 的 APK 文件开始。初步发现令人震惊:

  • 日志中的调试 Cookie: 会话 Cookie X1_SSO 以未加密形式记录到 logcat,从而可能劫持会话。
  • 自制加密: 并非声称的 AES,而是使用硬编码密钥(App 的包名 ru.vendor.schoolapp)的简单 XOR 加密。
  • 通用后备: 没有设备密钥时,App 默认使用固定 ID 000xpda

这些缺陷已足以实现对学生个人数据的自动化访问。但更深入的 API 分析揭示了一个更严重的问题:缺少服务器端权限检查。只需在请求中替换用户的 guid,而无需 X1_SSO 令牌,即可访问任意学生的数据。

Google AdInline article slot

值得注意的是,至少三个俄罗斯地区使用的相同 App 也存在相同漏洞,数百名中小学生的数百万条数据面临风险。

负责任披露:威胁被忽视

作者尝试通过负责任披露程序通知相关机构。联系数字发展部后,被转介至地区机构,特别是作为开发者的地区信息技术中心(RCIT)。

RCIT 回复承诺“解决问题”,但修复措施流于表面:

Google AdInline article slot
  • 移除易于检测的 XOR 加密。
  • 用 AES 替换,但密钥仍留在 App 代码中。

Crypt.java 类中的示例:

package ru.vendor.schoolapp2.common;

import android.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/* JADX INFO: loaded from: classes2.dex */
public class Crypt {
    public static String alt_api_key = "gqhy671nmn3478fhsdjf4f09f45sf4fg4lf842d1";
    private static Cipher cipher = null;
    public static String encryptedTOKEN = "";
    private static SecretKeySpec key = null;
    public static String session_apikey = "0xt25240s9s12xv767v1ll17757e32e34x12ppix332vdi2i";
    private static String transformation = "AES/ECB/PKCS5Padding";

    private static byte[] encrypt(SecretKeySpec secretKeySpec, byte[] bArr) {
        try {
            Cipher cipher2 = Cipher.getInstance(transformation);
            cipher = cipher2;
            cipher2.init(1, secretKeySpec);
            return cipher.doFinal(bArr);
        } catch (Exception unused) {
            return null;
        }
    }

    private static byte[] decrypt(SecretKeySpec secretKeySpec, byte[] bArr) {
        try {
            Cipher cipher2 = Cipher.getInstance(transformation);
            cipher = cipher2;
            cipher2.init(2, secretKeySpec);
            return cipher.doFinal(bArr);
        } catch (Exception unused) {
            return null;
        }
    }

    public static String encryptString(String str) {
        return Base64.encodeToString(encrypt(key, str.getBytes()), 2);
    }

    public static String decryptString(String str) {
        byte[] bArrDecrypt = decrypt(key, Base64.decode(str, 2));
        if (bArrDecrypt != null) {
            return new String(bArrDecrypt);
        }
        return "";
    }

    public static void initKey() {
        key = createSecretKey();
    }

    private static SecretKeySpec createSecretKey() {
        return new SecretKeySpec(new byte[]{10, 20, 30, 40, 50, 23, 19, 31, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 16, "AES");
    }
}

后续通过 Roskomnadzor 跟进,也未能修复其他地区的漏洞。该系统继续依赖客户端角色检查,使得 BAC 漏洞尤为致命。

访问控制失效:一分钟变身教师

核心漏洞源于 App 将会话数据以明文形式存储在 shared_prefs 文件中。两个参数控制访问权限:

Google AdInline article slot
  • user_sys_guid — 用户标识符。
  • rolename — 角色字符串("Student" 或 "Teacher")。

实验在具有 root 权限的 Waydroid(容器化 Android)上进行:

  • 使用学生账户登录。
  • 编辑 /data/data/ru.vendor.schoolapp/shared_prefs/ 文件:

* 将 rolename 改为 "Teacher"。

* 替换为教师的 user_sys_guid(先前通过 API 获取)。

  • 重启 App。

结果:界面立即切换到教师模式,完全访问成绩册,包括“SAVE”和“ADD COLUMN”按钮。服务器未检查用户角色,盲目信任客户端提交的数据。

这是访问控制失效(BAC)的典型案例,服务器未在每个请求上验证访问权限。

经验教训:安全形同虚设

研究暴露了政府 IT 解决方案开发中的系统性缺陷:

  • 缺少基本安全措施: 密钥存储在代码中且跳过权限检查是致命错误。
  • 表面修复: 仅将 XOR 换成 AES 而未进行架构大修,无法解决问题。
  • 威胁规模: 漏洞影响多个地区,数百万中小学生数据岌岌可危。

此类缺陷为大规模未授权访问铺平道路,包括篡改成绩和个人数据。尽管有证据,相关机构仍继续忽视威胁。

要点

  • BAC 漏洞只需修改本地文件中的两个参数,任意用户即可变身教师。
  • API 和加密密钥硬编码在 App 中,反编译后易于提取。
  • 官方仅作表面修复,忽略根本原因。
  • 问题波及多个地区,表明开发模板在安全上偷工减料。

— Editorial Team

Advertisement 728x90

继续阅读