android 安全sdk相关
前述
在网上有看到许多android安全sdk相关的内容,有重复的也有比较新鲜的内容,这里做一个整体的合集,以及后续又看到一些比较新的东西会一起放在这里。
android内sdk目前可以分为以下几个部分(有一些部分可能会存在一些重合)——设备指纹,root相关,环境检测,模拟器特征,改机软件
设备指纹
1.android_id
google给的app唯一id,存放在/data/system/users/0/settings_ssaid.xml文件中,只有在文件存储位置处修改,设备重刷或设备恢复出厂设置等时候才会被修改。可以用Settings.Global.getString() 、Settings.Secure.getString()、Settings.System.getString()来获取(根据/data/system/users/0/下的文件名字推测可用这些方法获取该目录下一些文件的内容)
2.drmid(设备媒体id)
media drm的设备id,同时和app包名以及签名有关,即不同包名或者不同签名,drmid会不一样,可以视为另外一个android_id,缺点是还和包名有关,注意:极少数机型上获取该id的过程存在崩溃且google也在逐渐的废除该id,可参考:https://developer.android.com/identity/user-data-ids
UUID wideVineUuid = new UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L);
try {
MediaDrm wvDrm = new MediaDrm(wideVineUuid);
byte[] wideVineId = wvDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID);
return Utils.md5(wideVineId);
} catch (Exception e) {
return null;
}
3.gsfiid
gsfiid是Google Service Framework ID,Google服务框架 ID
public static String gsfid() {
Context context = DeviceGlobal.getContext();
Uri uri = Uri.parse("content://com.google.android.gsf.gservices");
if (uri != null) {
try (Cursor cursor = context.getContentResolver().query(uri,
null, null,
new String[]{"android_id"}, null)) {
if (cursor.moveToFirst()) {
return Long.toHexString(Long.parseLong(cursor.getString(1)));
}
} catch (Throwable tr) {
Logger.w(TAG, tr.toString());
}
}
return null;
}
4.apk相关
apk安装时间和路径,可以通过getPackageInfo中的firstInstallTime获取,可以作为唯一id和防刷
5.boot_id,oaid,imei,serial number
boot_id可以通过cat /proc/sys/kernel/random/boot_id获取,重启后会更新,是uuid格式字符串格式。
imei是SIM卡相关的信息,谷歌已经删除该属性来保护隐私性
serial number是手机adb devices的一串数字,可以通过getprop ro.serialno获取
oaid是国内android广告标识符,用户可以选择重置和退出广告跟踪。
6.文件哈希
使用stat获取/,/data/,/data/system/vendor/firmware,/system/bin,/vendor/lib,/systen/framework,/system/fonts,或者一些固定app目录的文件名,inode,uid,创建时间,最后修改时间组合等属性组合求hash作为指纹
7.网络相关
这里主要是指机器的ip,mac,网络的类型,这里的信息除了可以做设备指纹之外,也可以用来判断设备的环境等特征。获取方法可以通过ip -a或者ip neigh show命令行执行或者读取/proc/net/arp获取相关信息
root检测
1.path检测
getenv("path") 获取路径,和su或者magisk组合,判断root是否存在
2.属性获取
可以通过以下属性特征来判断设备是不是root了
getprop service.adb.root = "1"
getprop init.svc.adb_root = "running"
getprop ro.secure = "0"
getprop ro.debuggable = "1"
getprop ro.build.tags = "test-keys"
3.内存扫描
内存扫描有以下几种方式——1.检测/proc/self/maps 是否存在名为“/memfd:/jit-cache"的段(加载zygisk模块);2.检测栈空间[stack]的权限是否为"rw-p";3.检测map表是否存在匿名的且具有可执行属性。
4.selinux上下文检测
cat /proc/self/attr/prev,看文件中的内容是否为"u:r:zygote:s0",其中r表示进程,zygote表示进程权限
5.常见root应用检测
可以尝试包名检测,遍历/data/data/目录,看有没有一下目录
com.topjohnwu.magisk
eu.chainfire.supersu
com.noshufou.android.su
com.noshufou.android.su.elite
com.koushikdutta.superuser
com.thirdparty.superuser
com.yellowes.su
com.fox2code.mmm
io.github.vvb2060.magisk
com.kingroot.kinguser
com.kingo.root
com.smedialink.oneclickroot
com.zhiqupk.root.global
com.alephzain.framaroot
io.github.huskydg.magisk
me.weishu.kernelsu
6.其他
可以尝试访问/data,/system,/etc,查询是否有busybox可以执行——尝试which busybox或者是执行busybox
hook检测
1.frida检测
- 默认端口检测——27042
- 常见路径检测——/data/local/tmp/frida-server
- 检查进程/proc/self/fd/目录,寻找是否存在关键字linjector
- 内存模块扫描——frida-agent,frida-gadge,可以去/proc/self/maps文件下找找字符串
- inlinehook检测frida——查询函数头部是不是0xd61f020058000050
2.Xposed检测
- java.lang.ClassLoader.getSystemClassLoader.loadClass("de.robv.android.xposed.XposedHelpers") ——看xposed是否加载
- 遍历/data/data/目录,寻找有无以下包名
de.robv.android.xposed.installer #Xposed框架
org.meowcat.edxposed.manager #EdXposed框架
com.tsng.hidemyapplist #隐藏应用列表
com.tsng.hidemyroot #隐藏Root
org.lsposed.manager #LSPosed框架
me.weishu.exp #VirtualXposed 太极
top.canyie.dreamland.manager #VirtualXposed 夢境
io.va.exposed #VirtualXposed 夢境
io.va.exposed64 #VirtualXposed 夢境
io.virtualapp #VirtualApp
io.virtualapp.sandvxposed64 #VirtualApp
- 检测下列文件或文件路径是否存在
/sbin/.magisk/modules/riru_lsposed
/data/adb/lspd
/sbin/.magisk/modules/zygisk_lsposed
/sbin/.magisk/modules/riru_edxposed
/data/misc/riru/modules/edxp
/data/adb/riru/modules/edxp.prop
/sbin/.magisk/modules/taichi
/data/misc/taichi
/sbin/.magisk/modules/dreamland
/data/misc/riru/modules/dreamland
/data/adb/riru/modules/dreamland
/system/bin/app_process.orig
/system/xposed.prop
/system/framework/XposedBridge.jar
/system/lib/
libxposed_art.so
/system/lib/
libxposed_art.so
.no_orig
/system/lib64/
libxposed_art.so
/system/lib64/
libxposed_art.so
.no_orig
/system/bin/app_process_zposed
/system/framework/ZposedBridge.jar
/system/lib/
libzposed_art.so
- artmethod结构体判断,artmethod中access_flags和entry_point_from_jni_在hook过程中会发生更改。
3.调试检测
- 调试端口检测——读取/proc/net/tcp,ida远程调试端口用的是23946端口
- 调试进程名检测——直接ps -a,看是否有android-server或者adb-server
- tracepid检测——读取/proc/self/status,查看tracepid是不是为0
- ptrace检测——因为每个进程只能被一个ptrace检测,所以可以自己启动一个ptrace或者对ptrace检测
- 断电指令检测——检测bkpt指令
- dalvik模式下可以用libdvm.so中dvmDbgIsDebuggerConnected()函数检测,art模式下使用libart.so中gDebuggerActive中
- 可以读取/proc/self/cmdline查看内容是否为zygote
模拟器检测
1.基于模拟器结构特征
基于qemu底层技术