通过Xposed的hook机制探究加固的app的密码盐值实战

原文章发表在 https://www.jianshu.com/p/5cc402b67aaa 现在有了自己的静态博客,特意搬过来

1. 前言

此文章仅适用于兴趣研究,不可作为损坏他人或其他机构等利益之用,本文只是提出一个设想,并不保证具有普适性

2. 开题

对于安全来说,app是毫无安全性可言的。

不管您是用了proGuard来混淆app,还是用了360加固宝,腾讯加固,等加固产品,最终都会被以各种方法破解。

例如使用IDA Pro,来进行dump,很容易就可以进行还原未加固的.dex文件,源代码就会暴露出来

因为app要运行,总会把加固的东西还原进内存,总是会有一些工具可以做到脱壳。

所以与其想办法在前端做加密,不如使用SSL和安全的服务器端

本讲主要介绍如何利用手写xposed模块,hook(钩出我们想要的密码的盐值

注,此方法对于native method: C/C++代码编译的.so文件无解

3. 需求

3.1. 需求的出现

我学校有个查成绩的app,抓包发现使用的是RESTful风格的WebService,配合手机端的app

抓包发现登录数据包

原理是

使用用户名和加密的密码登录,返回一个由时间和用户信息共同决定的token,以后的各种请求都由此token来确定请求者身份,可以很容易把此WebService搬到网页上面来,而不用为了安装一个一年只用2次的app而到处求包

于是决定搞清楚p字段(密码加密的原理

3.2. 分析p字段

p字段的长相

c98f9b47a56d685001b94a9827feef36

他的特点有:32位,最大字母是f

由此可以初步判断,他可能是使用了较为常见的MD5消息摘要算法进行的加密

利用站长工具MD5在线加密,对‘password’这个密码进行了测试,发现

password的md5加密测试

与上文c98f9b47a56d685001b94a9827feef36是不一样的

3.3. 对app进行反编译

由于第2步中的两次测试结果不一致,猜测app内部可能使用了(Salt

(Salt,在密码学中,是指在散列之前将散列内容(例如:密码的任意固定位置插入特定的字符串。这个在散列中加入字符串的方式称为“加盐”。其作用是让加盐后的散列结果和没有加盐的结果不相同,在不同的应用情景中,这个处理可以增加额外的安全性。

为了探寻加盐方式和加密逻辑,要对app进行反编译

这里使用apktool
apktool的下载地址:https://ibotpeaches.github.io/Apktool/

将app的apk安装包和apktool放在同一文件夹下

cd到该目录 或 按住shift键在该目录空白处右键,选择在此处打开cmd/powershell窗口

执行如下命令
java -jar .\apktool_【版本号】.jar d .\【apk名字】.apk

发现整个程序的入口被一个桩模块(stub)取代,再看到qihoo,就知道是用了360加固

360加固宝加密了!:

360加固宝加密了!

在assets下发现360加固的内容so二进制文件:

在assets下发现360加固的内容so二进制文件

这下就很棘手了

3.4. 面临抉择

app被加固,我有两条路可以走

  • 给app脱壳
  • 想其他办法

我也在网上搜了不少IDA pro的文章,看的也都似懂非懂,于是还是放弃了这个方法

4. 正文

最后决定使用Xposed模块hook相应方法
hook的话我们需要知道md5加密的方法的方法名,但是由于代码是加固了的,我们无从得知

逆向思维

方法无非有这两大类,一种是我们不知道名字的,一种是系统的类的方法,名字肯定是固定的

既然密码有加盐,那么定然会用到+来做字符串拼接:pass+salt

而字符串拼接会被编译成StringBuilder的字节码,所以只要hook了StringBuildertoString方法,就会得到pass+salt的返回值

StringBuilder在现代化的IDE里面已经不被推荐使用了,因为编译器会把+连接的字符串编译成StringBuilder的append方法,为了保持代码的美观和可读性,IDE都会建议使用+号而不是sb

4.1. Xposed框架安装

xposed分两部分,一个是框架(framework),一个是模块(module)

框架可以直接安装,需要root的手机和兼容的系统
xposed官网下载地址 - XDA论坛
去百度上搜也可以,推荐使用酷安市场下载

安装完毕后像这样

详细的框架安装教程这里不提供,网上可以搜到更为详尽的教程

4.2. 进行模块的开发

4.2.1 准备Android Studio

4.2.2 新建一个项目

不需要添加Activity,建一个空空的项目就好

您可以选择阅读官方开发教程说明:https://github.com/rovo89/XposedBridge/wiki/Development-tutorial

也可以继续看我的表演

4.2.3. 添加如下依赖

我在这里使用kotlin语言来发开

//主要的依赖
provided 'de.robv.android.xposed:api:82'
//注解,可选
provided 'de.robv.android.xposed:api:82:sources'

4.2.4. 在清单文件Application里面加入

<!-- 是否是xposed模块,xposed根据这个来判断是否是模块 -->
<meta-data
    android:name="xposedmodule"
    android:value="true" />
<!-- 模块描述,显示在xposed模块列表那里第二行 -->
<meta-data
    android:name="xposeddescription"
    android:value="测试Xposed模块" />
<!-- 最低xposed版本号(lib文件名可知) -->
<meta-data
    android:name="xposedminversion"
    android:value="30" />

4.2.5. 编写一个普通的类

如Main

/**
 * Created by harbo on 2018/1/16.
 * Email: harbourzeng@gmail.com
 */
class Main : IXposedHookLoadPackage {
    override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
        if (lpparam!!.packageName != "【您要处理的app的包名】")
            return

        XposedHelpers.findAndHookMethod(StringBuilder::class.java,
                "toString",
                object : XC_MethodHook() {
                    override fun beforeHookedMethod(param: MethodHookParam?) {
                        Log.d("xposed抓到了", "before")
                    }

                    override fun afterHookedMethod(param: MethodHookParam?) {
                        Log.d("xposed抓到了", "after")
                        val result = param!!.resultOrThrowable
                        Log.d("xposed抓到了", result.toString())
                    }
                })

    }

}

4.2.6. 代码解释

使用XposedHelpers类的静态方法findAndHookMethod
此方法有两个重载,一个适用于系统类,一个适用于要hook的app自定义的类。

我们使用3个参数的那个方法:

  • 第一个参数:明确hook对象的类
  • 第二个参数:要hook的方法名
  • 第三个参数:一个hook方法的匿名内部类实例

重写 afterHookedMethod,将paramresult打成日志即可

4.2.7. 新建xposed_init文件

在项目上右键new -> Folder -> Assets Folder
新建文件xposed_init,打开它,在里面写上要执行的xposed动作类cn.tellyouwhat.mhook.Main即可

4.2.8. 编译的时候选择不需要activity

选择Nothing,而不是Default Activity:

选择Nothing,而不是Default Activity

4.2.9. 激活模块,硬重启手机(虚拟机可以软重启)

在xposed installer中,点击模块选项,勾中您开发的模块,然后重启手机,就能启用该模块

打开您要hook的app,输入用户名和密码进行登录

4.2.1 在LogCat中查找

找到啦~

找到

就可能会发现加密字符串的盐值
password后面那几个字母就是盐

还可能出现很多情况,比如加密

md5(md5(pass)+salt)
md5(md5(pass+salt))
md5(pass+salt)

等等情况,需要小心调试,慢慢发现

4.2.11. 验证

验证成功

此盐值c98f9b47a56d685001b94a9827feef36匹配

5. 结束语

本次测试成功,纯属机缘巧合,如没有解决您遇到的问题,还请见谅。本文只是提供一个思路,靠谱的还得是内存DUMP。也奉劝各位app安全的从业人员,把重心转移到传输层面上,app无绝对的安全可言。


   转载规则


《通过Xposed的hook机制探究加固的app的密码盐值实战》 Harbor Zeng 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
如何使用Java优雅的破解维吉尼亚密码 如何使用Java优雅的破解维吉尼亚密码
对包括维吉尼亚密码在内的所有多表密码的破译都是以字母频率为基础的,但直接的频率分析却并不适用。例如,如果P是密文中出现次数最多的字母,则P很有可能对应E(前提是明文的语言为英语)。原因在于E是英语中使用频率最高的字母。然而,由于在维吉尼亚密码中,E可以被加密成不同的密文,因而简单的频率分析在这里并没有用。破译维吉尼亚密码的关键在于它的密钥是循环重复的。如果我们知道了密钥的长度,那密文就可以被看作是
2018-03-17
下一篇 
Windows下常用的网络配置命令浅析 Windows下常用的网络配置命令浅析
原文章发表在 简书:https://www.jianshu.com/p/23e52ad9c44c 现在有了自己的静态博客,特意搬过来 一、学习目的 学会使用netsh命令测试本机的TCP/IP网络配置 学会使用netstat命令以及检测网络连接 了解arp原理以及使用arp探索攻击源头 了解nslookup命令的用法 二、学习要求使用netsh命令查看本机的IP地址,并修改本机的静态或者动态
2017-11-09
  目录