通过初步分析,请求网址/v4/c是初始化的步骤,请求网址/v4/a/up就是关键的设备参数的上传。
每次登录的操作都会发送这个请求,看来这个包应该就是数据上传的点了,不过很可惜,数据加密了,先到so里去定位吧。
不过当我进到so里的时候,发现so中的字符串都被加密了,运行时才会解密并且是在栈空间里面储存。
不过好在算法很简单,就是异或或者其他的运算,写个脚本批量解就好了,这里大约有5000多行:
即使如此,还是有部分算法没解出来,不过不要灰心,由于解密之后会放到一个栈空间中,之后这块内存将被回收,hook下free函数,也能打印出不少东西:
这些数据就成为线索了,解密出一部分数据之后,找到上面的/v4/a/up的链接,很快就能分析出对应的请求函数了。
这里它是反射java层的函数去请求的,在请求之前就将数据加密了。
请求的数据在收集完成之后,使用protobuf序列化方便传输,然后就被送进加密函数里加密了,数据在请求前放到sub_2CD2A8中去加密,加密算法简单看了下是AES,并且key是随机生成的
这里就不逆加密算法了,直接上frida,把原始protobuf数据拿到手。由于网络请求基本上都会走这里,所以在hook这个函数的同时,hook他的上一跳函数,把请求的URL也打印出来,代码很简单:
这样就能把请求的protobuf数据拿到了。
然后再用protoc反序列化一下,差不多收集上传了有350多条数据。
详细的分析过程有点复杂,但可以大致将设备指纹和环境检测的项说明一下,看看大厂是怎么做的,大厂做的也是基本部分,大部分检测原理还是相似的。
由于这里差不多收集了300多项,这里把部分重点的收集项简单说一下.
基本思路是调用stat函数,去获取/storage/emulated/0目录下的块大小和总数据块数量,还有空闲块的数量。
代码逻辑很明显,通过syscall去调用statfs函数,然后获取stat结构体中的数据,最后算一下:
这个是很多大厂很核心的设备指纹,包括某美,某盾的sdk都在收集。
具体是通过dlsym去导入链接上libmediandk.so,然后调用getPropertyByteArray函数去获取:
这个也不说了,也是必收集的字段,通过system_property_get函数去获取,包括以下字段,其中既有与设备指纹相关的,比如说buildid和fingerprint等等,也有可以用于风控的(sys.usb.state,ro.setupwizard.mode这些)
先看下通用的:
然后还有一些不常见的,可能是其他厂商的设备中才会有的字段:
还有一部分用于设备识别和风控的,我会在后面放出来。
这个就很多了,比如说IMEI、androidID都可以作为设备标识,这里还是把它收集的设备标识列出来。
大概就是这些:
这个也有很多大厂用了,主要针对以下一些文件和文件目录,读取文件结构体,然后上传修改时间等信息。
这个很常见,一般主要有:
cpu核心数以及最大频率
CPU型号
内存(RAM)可用空间和总空间
cpu支持的系统架构
屏幕亮度、屏幕尺寸和屏幕超时时间
传感器生产厂家和类型(重要)
显示设备厂商名称(GL_VENDOR)和渲染器名称(GL_RENDERER)(重要)
内部存储(EMMC或UFS闪存)的序列号:/sys/block/mmcblk0/device/serial (核心)
显示设备序列号:/sys/devices/soc0/serial_number (核心)
内部存储SD卡的CID:/sys/block/mmcblk0/device/cid(核心)
电池相关,例如电压、电池容量、电池温度、电池健康百分比、充电状态等
input设备相关,读取/proc/bus/input/devices,获取注册的input设备信息,比如Name和Sysfs。
比较常见的就是局域网接口ip、mac、子网掩码、dns服务器列表了,这个就不说了,基本上就是SVC获取网卡的信息。
由于部分文件从系统安装后基本上不会有变化,因此很多大厂用了某些路径下的文件,通过一定的策略,比如说stat选择谋个目录下修改时间最早的(一般是1970年几月几日),然后将这个文件算个hash,或者直接调用getdents64函数,去获取某一目录下的文件和文件夹,按照修改时间从小到大排列起来,然后将排列起来的文件名算个hash,亦或者获取文件名+文件inode号(st_ino)+文件结构体长度(d_reclen),然后计算哈希。
总之策略有很多种,效果如何需要运营验证。
一般来说有几个重要的文件目录,大厂的处理方法具有相似性。
1、/data/system
2、/vendor/firmware
3、/system/bin
4、/vendor/lib
5、/system/framework
6、/system/fonts
cat命令读取/proc/sys/kernel/random/boot_id,这个也是大厂必用的一个关键的设备指纹字段。
读取设备上的应用安装列表以及apk路径,然后选择部分包名的路径作为设备指纹。
比如微信的随机路径 ,作为核心的唯一设备指纹,只要你不卸载重装微信,这个随机的路径就不会有变化
例如:
有些SDK会收集设备上安装的输入法列表,一般来说国内的HMOV手机预装的是定制搜狗输入法,谷歌pixel是谷歌原生输入法。
举个栗子,这是SDK上传的输入法信息:
获取输入法列表的方法:
在libNetHTProtect.so中主要检测了crc校验,还有frida和Xposed的一些特征:
进程/proc/self/fd/目录,寻找是否存在关键字 linjector
/data/local/tmp/下是否存在re.frida.server
方法1:检测下列文件或文件路径是否存在:
方法2:Hook loadClass加载类,检查程序加载的Class中是否包含名为de.robv.android.xposed.XposedBridge的类名路径。
方法3:遍历/data/data/目录,寻找有无以下包名:
拿到proc/self/maps中libc.so的基地址,并计算ELF文件中.text+.rodata+.eh_frame+.eh_frame_hdr 段的CRC校验值。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)