一、前言
最近玩王者荣耀,下载了一个辅助样本,结果被锁机了,当然破解它很简单,这个后面会详细分析这个样本,但是因为这个样本引发出的欲望就是解析Android中锁屏密码算法,然后用一种高效的方式制作锁机恶意样本。现在的锁机样本原理强制性太过于复杂,没意义。所以本文就先来介绍一下Android中的锁屏密码算法原理。
二、锁屏密码方式
我们知道Android中现结单支持的锁屏密码主要有两种:
一种是手势密码,也就是我们常见的九宫格密码图
一种是输入密码,这个也分为PIN密码和复杂字符密码,而PIN密码就是四位的数字密码比较简单。
当然现在也有一个高级的指纹密码,这个不是本文研究的范围了。我们只看手势密码和输入密码算法解析。
三、密码算法分析
我们如何找到突破口,其实很简单,在设置锁屏密码界面,用工具分析获取当前的View类,然后一步一步跟入,最终回到了一个锁屏密码工具类:LockPatternUtils.java,因为每个版本可能实现逻辑不一样,这里我用5.1的源码进行分析了,找到这个类之后,直接分析即可。
第一、输入密码算法分析
首先我们来分析一下输入密码算法分析:
这里看到有一个方法:passwordToHash方法,参数为用户输入的密码和当前用户对应的id,一般设备不会有多个用户,所以这里一般userId默认值就是0,下面就是最为核心的加密算法了:原文密码+设备的salt值,然后分别MD5和SHA-1操作,转化成hex值再次拼接就是最终保存到本地的加密密码了。而这里现在最重要的是如何获取设备对应的salt值了,这个可以一步一步跟踪代码:
查看getSalt方法,他首先会根据字段key为:lockscreen.password_salt,进行从一个地方获取salt值,如果发现这个值为0,就随机生成一个,然后将其保存到那个地方去,最后会将salt转化成hex值即可。现在需要找到这个地方,继续跟踪代码:
这里猜想应该是保存到一个数据库中了,继续跟踪代码:
这里是通过SM中获取一个服务来进行操作了,之前我们已经把SM都玩烂了,像这种获取服务,最终实现逻辑都是在XXXService类中,所以这里应该是LockSettingsService.java类中,找到这个类,查看他的getLong方法:
其实到这里就非常肯定是数据库保存的了,继续跟踪代码:
这里果然是保存到一个数据库中,我们继续查看LockSettingStorage.java类:
这里看到了,数据库名字叫做:locksettings.db,那么他保存在哪里呢?继续看这个类:
这里看到有两个key文件,那么这个就是用来保存加密之后的手势密码和输入密码的信息到本地,下次开机解锁就需要读取这个文件内容进行密码比对了。这里看到一个目录是system了,所以数据库和这两个key文件很可能保存到该目录下了:/data/system/,不过为了确保,我们直接用find命令去根目录下搜索这个数据库文件也是可以的。最终确定是该目录:
这里可能会提示找不到find命令,这时候需要安装busybox工具了,才能使用这个命令了。找到这个数据库文件就好办了,直接取出来,然后用SQLite工具进行查看即可,当然也可以直接在手机中查看。我为了方便还是弄出来看:
这里看到了这个表格字段,并且获取到这个值了,那么下面就要用这个值来验证我们的分析是否正确,我们首先给设备设置一个简单的输入密码,这里直接输入简单的"1234"了,然后会在/data/system目录下生成一个密码加密key文件:/data/system/password.key,这时候我们将改文件导出来:
下面我就用就简单的Java代码手动的实现这个算法,看看分析是否正确,加密算法都不用自己写,直接从上面的源码中拷贝出来就可以了:
然后这里的salt值是我们从数据库中拿到的,不过要记得进行hex转化一下:
然后我们用"1234"密码去生成加密之后的信息:
运行直接看结果:
这里发现内容和上面的password.key内容完全一致了,也就验证了,我们的分析完全符合,到这里我们就分析完了输入密码的加密算法,总结一点就是:MD5(输入明文密码+设备的salt).Hex+SHA1(输入明文密码+设备的salt).Hex;就是最终的加密内容了。而这里最重要的是如何获取设备的salt值,这个其实也简单,我们可以用反射机制进行获取,新建一个简单的Android工程:
这样我们就不用去查看数据库获取salt值了,这样方便快捷:
这个是数据库中的long类型值转化成hex之后的值。
第二、手势密码算法分析
下面继续来分析手势密码,代码依然在LockPatternUtils.java中:
这个算法比较简单,就是九宫格图案转化成字节数组,然后在SHA1加密即可,关于九宫格不再多说了,从0开始顺时针计数到8,类似如下:
这里看代码,有行和列之分,所以比如L形状的手势密码应该是:00 03 06 07 08,这样组成的五个长度的字节。这里为了验证手势密码是否正确,我们设置一个简单的手势密码:
然后在/data/system目录下生成一个密码文件:/data/system/gesture.key,弄出来用二进制工具查看,不然可能会看到的是乱码,这里用的是010Editor工具查看:
为了最大化的还原算法,我们依然把源码代码拷贝出来,然后定义一个手势九宫格类,构造出这个手势的点数据:
这个是源码的加密算法,下面在构造出手势点数据:
手势点应该是:00 01 02 05 08,打印看看结果:
非常的激动发现,一模一样,这样就完美的分析完了,Android系统中锁屏密码加密算法了。这里再一次总结一下两种方式锁屏密码算法:
第一种:输入密码算法
将输入的明文密码+设备的salt值,然后操作MD5和SHA1之后在转化成hex值进行拼接即可,最终加密信息保存到本地目录:/data/system/password.key中
第二种:手势密码算法
将九宫格手势密码中的点数据转化成对应的字节数组,然后直接SHA1加密即可。最终加密信息保存到本地目录中:/data/system/gesture.key中
四、锁屏密码破解
上面分析完了Android锁屏密码加密算法原理,下面就来简单分析一下,如何破解Android中锁屏密码。
第一种:输入密码算法
这个如果是针对于PIN类型密码,只是简单的四位数字密码,那么所有的组合也就是10000个,这时候我们只需要将这10000个密码通过加密算法进行加密生成一个密码库即可很容易破解。如果是复杂的输入密码那么就没这么简单了,这个或许就需要非常恶心的暴力破解了,随着密码长度增加,破解时间会很大。不过一般用户密码不会很长的。
第二种:手势密码算法
这个其实网上已经有人给出了一个密码库了,因为九宫格的图案可以全部算出,然后将其转化成字节数据,在用加密算法加密就能生成一个手势密码库了。具体信息可以自行网上搜索了。
到这里,有的同学会有一些坏的想法了,比如捡到一个手机或者是查看老婆手机密码,是否可以直接破解它的密码呢?大致思路应该很简单,首先把设备root,因为我们看到上面分析会发现如果想读key文件,必须有root权限的,当然root操作在对应的系统版本上还是有方法操作的。假如root成功了,那么这时候就获取他的salt值,然后利用密码库开始暴力破解即可。当然这个是悄无声息的不会被发现的破解,不过你root了其实已经被发现了哈哈,假如你是捡到一个手机,其实没这么费劲了,直接删除key文件,这时候你随便输入一个密码都能解锁了,这个因为系统在检查密码的时候发现key文件不存在,就认为这个设备没有密码锁,所以你输入什么都可以解锁了。
可惜到这里上面说的都是扯淡的,因为你在这一系列的操作前,你必须有一个认可,那就是设备连接允许框,我们在将手机首次连接到电脑的时候会弹出一个授权框,如果你不授权,那么什么都干不了。除非这时候利用伟大的漏洞过了这一关,不过一般是办不到的。那么现在的问题是,你捡到了一个手机,当然高兴的插入到电脑破解的时候会发现,先解锁,然后才能看到授权框,所以就悲剧了。你什么都干不了。就老老实实的把手机还给人家,做一个伟大的良民才是正道。
注意:
对于这个加密算法系统是不会在某个系统版本改变的,因为你想如果加密算法变了,加入4.4用户升级到5.0,结果发现加密算法变了,手机解锁失败,用户会疯的,我页查看了2.3的代码,算法是一模一样的。所以就把算法整理了一份Java工程放到github上,感兴趣的同学可以下载查看或者直接使用操作即可。变的可能是设备的salt值,或者数据库文件等发生变化。但是加密算法是不会改变的。
加密算法源码:https://github.com/fourbrother/AndroidScreenOffPwd
五、总结
我相信大家读完这篇文章都是迫不及待的想手动尝试一下,在操作之前一定要记住,先拿到你设备的salt值,这个方式有两种,一种是查看/data/system/locksetting.db文件,一种是用反射获取。然后就要注意的是源码版本,本文介绍的是5.1版本以及5.1设备进行操作,所以你操作的时候一定要注意版本,不过版本不一样,这样的算法不会变的。
更多内容:点击这里
关注微信公众号,最新技术干货实时推送