对某APP逆向分析的实战

下文通过对某APP进行逆向分析过程,主要是为了更好的学习分析过程的思路和方案,以便在后续过程中能够快速的进行对APP功能的分析。

root检测

将APP包安装在root过的手机上并打开,结果有提示:这应该是检测到root了。

使用jadx加载APK,全局搜索关键字:检测到当前设备

已搜索到这个字符串信息,它的ID名叫 toast_app_fail,再次搜索这个ID定位哪里引用了这个字符串。

搜索到许多处调用,主要在MainActivity与StartActivity这两个文件里,因为这两个文件通常是APP中最早启动的两个类,很多检测都会放在启动阶段去实现调用。

注意到每次调用有不同的后缀,逗号,叹号等等。提示的字符串是逗号,所以选择后缀为逗号的进入。

看到调用了DeviceUtils.a()函数,如果返回true就会弹出检测信息的字符串,然后退出。接下来就是分析.a()函数具体怎么实现

上面的代码是通过检查文件方式进行判断是否运行环境已经root了,检测是否root的常规方式就是尝试打开这些/system目录下的su文件,如果能打开,则说明有root权限。

可以使用MT管理器打开APK包,找到DeviceUtils类中a函数,通过修改smali代码,让a函数不检测而直接返回false即可(也可以用androidkiller、jeb等)。

将返回值中修改成返回v0即可。重新打包,安装。又弹出那串文字,不过后缀变成了感叹

号!

继续查找字符串信息,定位这个感叹号出现的位置:

定位到DeviceUtils.AntiRoot()逻辑下面。如此欲盖弥彰的安全保护,真令破解者狂喜。接下来定位分析下AntiRoot函数,点发现它是一个native函数,加载的so是myapplication:在通过ida在so中全局搜索AntiRoot关键字

发现还是在检查 su 文件,如果check_su_files()检测到是root就返回“yes”,没有就返回“no”,这和java代码中检测相对应

接下来可以直接用MT管理器修改java代码,将比对的“yes”改成“f*ck”,这样就算检测到root,java层的检测比对也会失败。

以上root检测就全部绕过了。可以正常打开app了。但是打开后一片空白,

这种情况通常是因为没有拿到正确的返回数据导致的。

APP打开后肯定会向后端请求各种数据,如果数据异常,则无法正常显示。这时候就要抓包看看了。

代理检测

打开手机代理,启动fiddler工具抓包,结果APP又无法正常启动,这次弹出了这个对话框:

APP生怕不知道他在检测代理,给出了非常温馨的提示。那就继续搜字符串分析。

看到字符串id是 toast_api_proxy_fail,查找引用:

和root检测的流程基本相同。不过是调用了一个b函数来检测是否有代理的,分析下b函数:

代理检测的逻辑是要确保 http.proxyHost(代理地址) 为空字符串,或者http.proxyPort(代理端口)为-1。

接下来还是直接修改java代码让他始终返回false就好。这样之后,就可以成功打开app,并且抓到了数据包:

但是,APP内部依然是一片白,查看返回的数据,发现是加密的:接下来就分析下数据解密。

数据解密

一般情况下APP客户端会使用okhttp作为http客户端进行收发请求。(目前还有cronet做客户端的,但仅限于大厂使用,而且大多是在okhttp上定制的)

okhttp工作方式是责任链,也叫管道传输(pipelien),每一环节处理一些事情,比如在发送阶段,第一个pipline是添加基本信息,如设备id,时间戳等等。第二个pipline是计算签名值,第三个pipline是把发送数据加密,然后发出去。

分析APP中的okhttp,发现被混淆保护了:

okhttp的创建是在okhttpclient这个类里做的。混淆通常只能混淆函数名,类名,但无法混淆函数的具体实现,包括一些特殊的字符串,可以从字符串入手,找到okhttpclient。

下载一份okhttp的源码,查看okhttpclient这个类有什么特征:

源码地址:

https://github.com/square/okhttp

发现在内部的builder里,有三个连续的字符串“timeout”,而这是无法被混淆的。我们在jadx里全局搜索“timeout”:

点进去看看,发现结构和okhttpclient的结构如出一辙,这样就可以判断这就是okhttpclient类。

查看引用,我们也因此找到APP创建okhttpclient的位置:

okhttp中客户端另一个特征,对读写超时的设置,从TimeUnit可以看出这是在设置http请求的读写超时。

同时,看到后面一连串的.a函数,这是在添加一个一个pipline。(okhttp中叫拦截器,不过我个人感觉本质就是pipline).

分别查看这些pipline,一个是添加请求头的:

还有一个它是和数据处理有关的:

看到里面的response,bodystring字符串,还有d_key_three,这是在做什么,为什么出现了秘钥和返回体?,点进去看f5865a.a这个函数:

看到了password,iv,SecretKeySpec,Cipher,doFinal这些特征。显然是在做aes解密,通过在用AES解密,模式是 CBC,填充方式是PKCS5padding。

用frida hook这个a函数,看看解密后的值是什么?

直接将正确的秘钥强行塞给解密函数,终于解密完成了

返回的数据显示“签名验证失败”,接下来就是要分析下签名验证功能。

签名校验

因为签名验证失败,所以没有拿到正确的返回数据。需要分析下签名是怎么计算的。

在http请求头里看到了sign字段:

一般情况下,签名的命名方式为sign,sig,authcode,sec之类。特殊的例如某音,使用了希腊神话中的神的名字来命名。

jadx全局搜 “sign”。(注意用带双引号的sign来搜索,这样会提高搜索效率。因为通常生成sign时会把sign作为key,put进一个map里。而key是一个String,所以代码中生成sign的地方一定有字符串"sign")

分析下a7的生成过程,因为sign来源a7赋值。

先加入了ts参数作为时间戳。然后把所有参数首尾相连。再添加类似于aes秘钥的后缀。然后通过另一个a函数计算a2,再将a2全部小写。这就是签名的生成过程。

看看另一个a函数:

是在计算MD5摘要。那么问题就出在了那个类似于秘钥的后缀上。

确实,因为签名错误了所以也返回了错误的后缀,不过使用的是aaxx函数,不同于aes时候使用的ddmm函数。

同样的套路,签名不正确就返回error,正确才返回真正的后缀。

看看本地是怎么做签名校验的?

通过反射获取signature,然后计算MD5,与硬编码的正确SIGN_MD5进行比对。

既然如此,我们hook aaxx函数让他返回正确的值:

再次运行frida 脚本后,成功得到了正确的数据:

同时,app界面也正常了,不过显示已到期:)

绕过限制

成功绕过了root检测,代理检测,签名校验。但是每一台设备只有2小时的免费机会,我们想要白嫖,怎么办?

通常APP会通过唯一设备标识来跟踪设备,即设备指纹技术。Deviceid可以直接获取安卓设备本身的唯一标志(高版本android禁用了),也可以获取设备的MAC地址,也可以生成一个UUID,或者随机字符串,藏在设备的某个角落。当apk重新安装时,先去看看之前这里有没有藏过相关的文件,如果有,就直接读出来当做设备ID,如果没有,则创建一个。这样做可以保证apk删除前后依然能跟踪设备。当然,如果你能发现这个文件,并且把它删掉,那么下次安装的时候app就会认为是一个新的设备了。

先找找deviceid在哪,全局搜索deviceid:

发现了许多地方,有from app,有from sdcard,跟入一个sdcard相关的函数:

看到了是从f文件读取的设备id。看看f文件的路径:

果然,sd卡下的alarm文件下有一个文件,打开后的确是发送数据时使用的设备id。

删掉这个文件,重新启动,发现设备id还是没有变化,难道还有其他地方存着?

注意到上面的from app:

看到deviceid是从b函数获取的,看看b函数:

原来是从sharedpreferences里拿的。SharedPreferences 是app内部存储数据的一种方式,而sd卡是一种外部存储方式。

我们打开sharedPreferences,果然看到了customdeviceid:

看看他的设备id是怎么获取到的?

首先通过a(10)获取了一个10位的随机字符串a2,

所以设备id是随机生成的。每台新设备有2小时的免费时间,也就是7200秒。我们考虑每7000秒重新生成一次设备id,不就可以无限续杯了吗?

看看app在那里获取到这个deviceid并发送给服务器的,注意到之前的okhttp 的pipline中有一个就是添加http头的:

看到deviceid是通过a()方法获得的。查看a()方法

最终是返回了一个字符串。其实不用继续跟下去了,无非是从APP获得或者从sd卡获得。我们在这里hook就行。

理论上只要写一个字符串随机生成算法,保证2小时内保持一直就行了。我这里使用时间戳除以7000的方式获取:

写一个函数,然后使用android studio编译出smali代码。将对应的smalidaima插入到a()函数返回之前即可:

随机设备id的smali代码:

插入到a()函数返回之前,这样,我们每隔两小时会使用全新的deviceid,对服务端来说好像是新的设备安装了他的app,然后就可以又白嫖两小时的免费时间了。

原文链接

https://bbs.kanxue.com/thread-275423.htm

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

猜你喜欢

转载自blog.csdn.net/Python_0011/article/details/133603606