前言

大部分采用智慧课堂教学的学校都是用某平板管理软件进行对平板的管控,能实现限制网络连接,限制APP的安装,实时获取设备信息等。这里将会介绍解除平板管控的一些已经验证过可用的思路。这是一个两年半之前实施的项目,因为一些数据丢失的原因这里无法进行整个系统的环境复现,也没有太多成果截图,这里只能根据好友共享的系统镜像最大限度地还原当时的思路。

环境概述

拿到平板之后,简单的测试了一下,发现许多可以利用的点:

  • 平板采用高度定制的安卓7.1.1系统
  • 平板使用验证APK包名的方法来判断是否属于白名单
  • 平板的网络防火墙并未限制192.168.0.0/16以及172.16.0.0/16
  • 虽然系统将USB设置为仅充电但是在系统开机加载时有短暂的几秒能使用ADB
  • Bootloader可被解锁
  • 存在一个“管理员设置”并由密码保护,密码可能随云端更新
  • 平板管理始终没有调用ROOT权限

准备工作

为了更加透彻地了解这个系统,我利用短暂的ADB进入bootloader并解锁bootloader,然后刷入TWRP,将系统的镜像提取了出来,检视应用列表后发现,对平板的限制极有可能是由包名为com.android.launcher3的定制桌面操控,于是开始整活。

解除过程

尝试卸载桌面

既然是有可能由桌面操控,那么卸载掉桌面极有可能会解除管控,对桌面使用dex2jar进行简单逆向,发现在设备从未联网时,管理员默认密码为xunfei!!@,于是在bootloader双清设备,启动系统,断网并进入管理员登录界面,输入默认密码成功进入管理员界面,管理员界面功能如下:

defupass

源码中的默认密码

admin

管理员设置界面

虽然那个解除限制十分诱人,但是后期的逆向发现这是对平板使用限制的解除而非App或TCP/IP的限制。回到正题,我们打开usb连接电脑,并连接电脑,顺利进入adb调试界面,于是执行adb uninstall com.android.launcher3以及adb install newdesk.apk,完成后重启设备,由于其内置的部分App有内嵌Web访问以访问登录或重置密码的网页,我们可以使用ARP劫持使其强行访问我们指定的网站,测试结果发现卸载com.android.launcher3后,网址白名单已被解除,然而App的安装限制仍未解除,这更加印证了com.android.launcher3对平板的限制有着千丝万缕的联系。也意味着我们需要进行进一步的逆向。

baidu

卸载桌面并使用ARP劫持后成功访问白名单外的网页

攻破管理员登录

从前面的研究结果来看,管理员界面是一个极为关键的跳板,如果能绕过管理员界面或得到密码将会对后面对操作有极大的帮助,于是开始审阅源码。在逆向出来的jar包里,很容易发现一个名为LoginActivity的类控制着管理员登录界面,得到了登录相关的方法

login

登录方法的Java源码

显然我们可以修改源文件以将“用户名且密码正确”的逻辑改成“用户名或密码正确”或者“用户名正确且密码错误”以达到输入任意值即可进入管理员界面。但是我们并不能直接编辑dex2jar得到的java文件,我们需要更深一层,通过对照java源代码去编辑Smali文件,好在Smali语言不算特别难理解,很快发现逻辑判断的地方,如图:

loginsmali

判断逻辑的Smali代码解析

于是,我们可以把密码判断的if-eqz替换成if-nez,这样如果用户输入错误的密码就不跳转,进行登录成功的流程,不仅如此,我们可以更进一步,在line 104中调用sPFTool来读取管理员密码时插入一个弹窗,把密码值通过弹窗弹出来,在move-result-object v1后面插入如下代码:


const/4 v5, 0x1
invoke-static {p0, v1, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v4
invoke-virtual {v4}, Landroid/widget/Toast;->show()V

即可在登录中程序调用密码时将密码弹出来,由于我使用的是早期版本的平板管理软件,密码直接以明文方式存储,十分方便进行hook,而后续版本则存储了密码的MD5,但是实验表明这段MD5并没有使用任何数据加salt,对其进行解密难度不是特别大。

网址白名单的解除

虽然管理员界面有方法添加网址白名单,但是只能一个一个网址地添加而且有被服务端配置覆盖的风险,自然不可取,而前文提到卸载平板管理软件后重启系统网址白名单即解除,那么可以推出在设备开机之后平板管理手动启动了网址白名单,至少有一个管理开机后的操作或者初始化的类包含了白名单的开关,于是我们继续逆向,发现一个叫“BootCheckReceiver”类操控着开机启动后的操作,在里面发现了相关方法,Java代码如下:

firewall

这段代码十分好理解,读取配置如果为limit则启用防火墙,我们自然不会去修改可能被服务端覆盖的配置来达到效果,而enableFireWall前面名为“MDM”的类引起了我的注意,根据import的索引,我跳转到这个类,发现是一个根据设备型号进行类索引的“中枢”,而我手上的平板对应的类如下:

device

于是我们前往这个类,发现许多有意思的方法,这里列举一部分:

![DDDD](https://cdn.starryloki.com/2023/07/41ad7df19172d0ed3b09620ea60659e8.png) DDDD

于是我们现在前往BootCheckReceiver对应的Smali文件,找到了对enableFirewall的调用:

.line 51
sget-object v1, Lcom/linspirer/rom/MDM;->x:Lcom/linspirer/rom/IMDM;
invoke-interface { v1 }, Lcom/linspirer/rom/IMDM;->enableFireWall()

直接把enable修改成disable即可,至此,网络访问限制已被解除。

MDM.x的第三方调用

我们已经大致了解了平板管控的原理,定制的系统提供API,平板管理软件通过MDM.x的方法与API对接,而在调用API时并未发现任何验证措施,如果我们自己写一个安卓APP,引入MDM相关的类和方法,是否也可以调用系统提供的API呢?

答案是肯定的,如果有安卓APP开发基础,我们可以直接将与MDM调用API有关联的类导入到自己的APP,做好索引后即可使用MDM.x.调用系统API;如果不会开发相关APP,我们可以在平板管理里找到一个有交互性且调用了MDM类的Activity,比如管理员设置。

我们可以直接前往管理员设置所对应的Smali文件,将已存在的方法调用替换成对MDM.x的调用,比如:

MDM

管理员设置中的MDM调用

可以替换成enableSDCard之类的方法。

应用白名单的解除

虽然我从MDM的类中挖出了绝大部分的控制方法,但是遍历后并没有发现有解除app白名单方法,仅有写入或读取,由此可见这个公司还是比较保守,没有把如此关键的方法放出来,初步猜测这个方法位于PackageManagerService中但是目前没有办法逆向出来,于是逆向了framework里面的PackageInstaller和pm,并没有发现白名单的实现机制,于是只能从逻辑推测。

首先回顾一下系统逻辑,如果存在不在白名单内的非system应用,会被平板管理卸载掉,而平板管理和智慧课堂套件都不是system应用,并且在平板管理里面有一些方法将自身和智慧课堂套件写入白名单,于是可以推测当白名单为空的时候,应该不存在限制,否则当白名单为空时,平板管理等一系列附属APP将会被系统卸载,平板管理被卸载后就无法从云端读取新的白名单写入系统,平板就此报废。于是我在上面调用MDMAPI的app中新增了一个功能:利用MDM.x.appWhiteListWrite()写入一个空的名单,然后利用修改包名将这个APP改成白名单内存在的app,装入系统,运行方法,限制顺利被解除,之后进一步修改源码,将平板管理内所有调用MDM.x.appWhiteListWrite()的方法的赋值替换为空值,防止平板管理写入白名单导致限制被重新启用,至此应用白名单已被解除。

![APP](https://cdn.starryloki.com/2023/07/01fb66d54d1254ef80b6c2b58e0c08a4.png) 把MDM相关的类导入到自己的APP就能直接调用了

解除云端监控

之前有一部分的平板出现系统故障,上报学校网管之后被后台远程重置,于是推测系统内有服务器远程操控的方法,于是继续阅读源码。在一个叫CommandManager.class的类里面找到了一个服务器发送命令让本地执行的方法,于是在Smali将命令改成服务器基本不会发送的字符串,这样就大致脱离了服务端对平板的控制。

![CMD](https://cdn.starryloki.com/2023/07/08beda2bf717723397eed6e64b0026e7.png) 远程操控的相关类

顺着上传应用列表的方法,在其他类中找到了自动上传位置和应用列表的类,于是在Smali中将将要上传的返回值用空白变量劫持,这样就大致脱离了服务器对设备的监控。

伪装成客户端从服务器爬数据

前文提到管理员密码等配置会随服务器更新,于是我找到了这个类,我们可以依照上面调用MDM.x的思路,在第三方APP引入这个类及其依赖的类,在输入schoolid等数据之后,即可直接获取管理员密码等关键信息。

code1
code2

CMD

解除限制后安装第三方APP以及使用DEX注入劫持背景图

总结

这个逆向的项目还是非常简单的,目标系统简直是一个筛子。不过后期得到了许多“修复”:

  • 密码采用MD5存储(源码中的初始密码仍然为明文)
  • 对源码进行了混淆(源码中内置mapping且有未混淆版本源码做对照)
  • com.android.launcher3不可卸载(可以用pm disable禁用然后用破解版替代)

code1


解除这类平板使用限制的方法还有很多,比如从万能的xda下载机型的官方系统包直接刷入等等,虽然十分简单粗暴,但是却少了许多逆向的乐趣。

EOF