移动安全逆向实战(一)

news2025/1/20 18:40:08

小杂谈

搞了差不多两年移动安全发现多动手才能学到新东西,故此推出app逆向实战系列用于记录破解各个app的安全防护,以此勉励。

一些括号内词句读者自动脑补表情包,狗头保命[doge]

正文

frida反调试

将某8样本app塞进jadx查壳,数据多的亚比,恭喜没加壳,前进第一步!(加壳了就没有后面doge)

image-20230515183441739

打开app查看http数据包(美滋滋),看到以下数据,所有请求都统一封装了并且还有加密、签名。(日瑞玛,退钱!)

要弄掉以下防护需要几个步骤:(柯南思考)

1、sign应该是签名,需要弄清和哪些参数有关

2、请求没有body和param参数,应该是加密存在hbody字段内

3、有key参数,再加上返回包返回的result猜测是AES加密

4、uuid用来防重放攻击

image-20230515183945901

将数据包发到repeater看看到底是什么妖魔鬼怪。我敲,难道是传说中的防重放攻击?原地退役想法+1

image-20230515184229136

找一个没有防重放攻击的,一般是静态资源类的,修改任意参数,哦豁中奖(摇头)。签名+防重放攻击,web方面的测试没戏了。

image-20230515185341692

掏出我的大杀器–frida!(杰哥摘眼镜,真拿你没办法),frida直接退出,但是程序还在运行(怀疑人生)

image-20230515185901234

首先出现以上问题我们得用排除法来定位原因,学习嘛总是在试错与排错中进行

1、设备原因,电脑、手机,重启大法没能解决,拿别的设备运行也是一样,排除。

2、app有hook检测,检测到直接终止进程

幸好本人平时喜欢游走在各个安全论坛,记起来一位大佬曾写过的frida反调试文章(其实是某位大哥提醒的),文章链接如下:

https://bbs.kanxue.com/thread-277034.htm、https://www.jianshu.com/p/74b7803701b6

通过结合两位大佬的代码集成hook代码成功绕过检测,so文件的检测原理后面再分析,留个坑。

image-20230515190911099

绕过hook检测后就可以为所欲为了(逐渐变态)

签名

对apk反编译,定位签名方法,因为请求体里面sign是在body请求体里面,客户端生成方式一般就是使用map进行封装,所以jadx的搜索关键词:“sign”

此时有多个符合条件的类,可以通过排除法一步步缩小范围。第三方sdk可以直接忽略,一般是和包名类似的类,如果不确定可以对该类进行hook,通过多次测试后发现如下类调用了签名的方法,跟进去

image-20230516101856890

从类名来看应该就是http请求的签名加密类,定义了一个sign的常量

image-20230516102400603

使用map添加SIGN、this.sign键值对,sign的值来源于zdo4i1uyyhqsmvpopdtoaa方法,查看具体的签名方法继续跟进

image-20230516102656814

签名方法是调用so层的接口,参数是字符串数组,使用frida直接hook看入参和返回值

image-20230516103001252

function signs(){
let JNIHelper = Java.use("com.wuba.bangjob.secret.JNIHelper");
JNIHelper["zdo4i1uyyhqsmvpopdtoaa"].implementation = function (context, strArr) {
    console.log('zdo4i1uyyhqsmvpopdtoaa is called' + 'strArr: ' + strArr);
    let ret = this.zdo4i1uyyhqsmvpopdtoaa(context, strArr);
    console.log('zdo4i1uyyhqsmvpopdtoaa ret value is ' + ret + '\n');
    return ret;
};
}

入参为body的参数,也就是说签名只鉴别这几个参数,其实从前面定位的sign方法也能知道入参有哪些

image-20230516103609795

对入参进行分析:

  • uuid,防重放攻击
  • hbody,加密后的body参数
  • cmd,http请求接口
  • key,可能是AES加密后的密钥
  • index,暂不明确

签名接口的调用有两种方式,其一,被动调用:通过程序正常流程调用到方法,修改入参获取sign。其二,主动调用:通过frida-rpc方式对sign方法直接调用

本文只展示第一种,rpc没法调用绕过hook检测的代码(后续研究),index参数添加单引号,调用方法生成sign绕过签名校验

image-20230516105452674

function asign(){ //因为rpc没法正常调用绕过hook的代码,故只能通过修改入参来获取sign,生成对应的字符串数组就好
    let ZCMBusinessMgr = Java.use("com.wuba.bangjob.secret.ZCMBusinessMgr");
    ZCMBusinessMgr["zdo4i1uyyhqsmvpopdtoaa"].implementation = function (strArr) {
        console.log('zdo4i1uyyhqsmvpopdtoaa is called' + '\n' + 'strArr: ');
        const dataString = "2425f470209f44b09b78bfae18e99694,jZvBbkCB3VYRSHFtw6yCVA==,recswitch.getsw,BSG8C+iTDpbExiNqb5uRI2bYg2kdXXFtzN8sYh5+XblZzDwloEWzvNd9NkEEwsByRgdwEn7M6GzD0TESbazzGg==,1'";
        const dataArray = dataString.split(',');
        console.log("call  strArr" + dataArray)
        let ret = this.zdo4i1uyyhqsmvpopdtoaa(dataArray);
        console.log('zdo4i1uyyhqsmvpopdtoaa ret value is ' + ret +'\n');
        return ret;
    };
}

image-20230516105854803

将sign进行替换,结果返回参数校验失败说明已经绕过签名限制,猜测后端判定index是个int类型所以传入’返回错误提示。

image-20230516105945454

解密

签名部分搞定了接下来就是请求体和返回包中的数据解密,还是在 EncrptyInterceptorModel类中

hbody

image-20230516110828179

function hbody(){
let JNIHelper = Java.use("com.wuba.bangjob.secret.JNIHelper");
JNIHelper["unz5pzfix1jfy3hqyuyvqq"].implementation = function (context, str, str2) {
    console.log('请求参数为: ' + str2);   //str为uuid
    let ret = this.unz5pzfix1jfy3hqyuyvqq(context, str, str2);
    console.log('unz5pzfix1jfy3hqyuyvqq ret value is ' + ret);
    return ret;
};
}

image-20230516111528090

result

通过多次调试定位到nuvbtdxcz2tnbyzxugrfxg方法就是对返回包的result参数进行解密的

image-20230516111732658

image-20230516112011138

因为返回的是ASCII码,所以需要进行多次转换才能输出可见字符,hook代码如下:

function result(){
let EncrptyInterceptorModel = Java.use("com.wuba.client.framework.rx.retrofit.secure.EncrptyInterceptorModel");
EncrptyInterceptorModel["nuvbtdxcz2tnbyzxugrfxg"].overload('java.lang.String').implementation = function (str) {
    //console.log('返回的加密result: ' + str);
    let ret = this.nuvbtdxcz2tnbyzxugrfxg(str);
    //console.log('nuvbtdxcz2tnbyzxugrfxg ret value is ' + ret);
    var decodedStr = decodeURIComponent(escape(bytesToString(ret)));
    var urlstr = decodeURI(decodedStr);
    var unistr = unescape(urlstr.replace(/\\u/g, "%u"));
    console.log("解密后的数据为:   "+ unistr );
    return ret;
};
}

image-20230516112443836

防重放攻击

防重放攻击解决方案看:https://blog.csdn.net/weixin_42806958/article/details/118971184

该app使用的是第二种方式,

1、客户端每次发起请求,都需要携带uuid(要求唯一即可)

2、服务端接收到请求后,先校验用户携带的uuid是否存在,不存在:将uuid存储到数据库或缓存服务器中,存在:既认为是重播攻击

总结:实现简单有效,但随着请求量越多,存储的数据会越来越大。

image-20230516112830900

没有特别的生成方式,直接导入uuid库生成一个uuid

image-20230516113245984

原本已经提示繁忙

image-20230516143658688

修改uuid后也是提示的繁忙(丢撵了),而且是部分接口才有这种情况,经过多次测试数据包隔一段时间可以再次请求,如果是uuid决定的重放,使用上述方式就可以绕过了,但是目前不成功。关键点应该是后端要么就是风控,不好判断。关于key参数的值来源于so文件里面,输出的是加密后的key,可能是动态key也可能是带有IV的加密模式。

总结

虽然最后一步暂不明确是否是uuid决定重放,也不知道是否是防重放手段,但是从该app上学到了防重放的一些防护手段。且从整个流程上来看,想对web层进行测试只需hook入参就好,后续的参数加密、签名等机制会自动运行,并不需要逐一绕过。frida玩得好,国家饭吃得饱,打完收工。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/532115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Agitek安泰测试与您相约第5届中国国际计量测试技术与设备博览会

展会时间:2023年5月17日至19日 展会地点:上海世博展览馆(上海.浦东) 展位号:2号馆423 2023年5月17日至19日,第5届中国国际计量测试技术与设备博览会将在上海世博展览馆举办,西安安泰测试Agite…

硬科技,创未来!第十五届深创赛福田预选赛-华秋第九届硬创大赛正式启幕

自2015年首次启动至今,由深圳华秋电子有限公司主办的“华秋中国硬件创新创客大赛”不断提升,赛事范围覆盖华南、华东、华北三大地区,累计影响超过45万工程师群体,吸引了35000多名硬创先锋报名参与。 2023年华秋第九届中国硬件创新…

​文生视频: 任务、挑战及现状

示例视频由 ModelScope 生成。 最近生成模型方向的进展如排山倒海,令人目不暇接,而文生视频将是这一连串进展的下一波。尽管大家很容易从字面上理解文生视频的意思,但它其实是一项相当新的计算机视觉任务,其要求是根据文本描述生成…

润秋商业案例分析,带你了解商业背后的秘密~~

商润秋商业案例分析,带你了解商业背后的秘密~~业模式的好坏直接奠定了公司未来的发展和当前的盈利能力。确实我们一个好的商业模式,往往可以让业务更稳定,发展更快。但一个好的商业模式必须满足几个条件: 1.帮助解决用户的流量问…

【C++】类和对象详解(2)

【C】类和对象(1) 文章目录 一、类的6个默认成员函数1.1 构造函数1.2 析构函数1.3 拷贝构造函数1.4 赋值运算符重载1.5 取地址及const取地址操作符重载const成员 一、类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真…

吴恩达OpenAI基于ChatGPT的Prompt开发教程

吴恩达OpenAI基于ChatGPT的Prompt开发教程 1.如何给出清晰具体的提示 1.1大模型分类: Base LLM基础大语言模型来源于预训练模型:用已有单词推测下一个单词。 Instruction Tuned LLM指令大语言模型:用人类反馈微调大语言模型优化回答。 当我们…

AMS启动报错 hbase-ams-master.pid doesn‘t exist after starting of the component

感谢点赞和关注 ,每天进步一点点!加油! 目录 ​ 一、问题描述 二、解决办法 一、问题描述 Ambari Metrics, Metrics Collector 启动报错如下: stderr: Traceback (most recent call last):File "/var/lib/ambari-agen…

网站被黑后的紧急处理恢复正常步骤是什么?

随着时代的发展网站使用的频率是逐步增加。然而,随着互联网技术的不断进步,网站安全问题也引起了广泛关注。其中,最严重的问题是网站被黑客攻击。那么,何谓网站被黑?它可能会给企业和用户带来哪些风险? 一、…

屏幕录像工具哪个好?这3款录屏工具就很不错!

案例:有没有好用的录屏工具分享? 【每次对电脑屏幕进行录制都要花费我很多时间,录制的内容质量还差,真是事倍功半。听说使用好的录屏工具可以提高录屏的效率,那录屏软件哪款好用?在线蹲一款!】…

【AIGC】阿里云服务器配置stable-diffusion-webui

阿里云服务器部署SD全流程, 正在更新!!! 购买阿里云实例开始部署开始运行安装插件中文插件从civitai上下载模型, 加载并利用其绘图 购买阿里云实例 我感觉应该不止我一个,点进阿里云的官网后,发现里面的内容太多&…

【爬虫逆向】Python加密算法大揭秘:应用场景与实现技巧

前言:​ 在我们进行js逆向的时候. 总会遇见一些我们人类无法直接能理解的东西出现. 此时你看到的大多数是被加密过的密文.今天在这里教大家各种加密的逻辑。 Python助学大礼包点击跳转获取 目录 一、一切从MD5开始二、URLEncode和Base64三、对称加密四、非对称加密…

Neo4j之APOC安装与使用样例

1 APOC简介 APOC即Awesome Procedures on Cypher ,是 Neo4j 最大和最广泛使用的扩展库,是Neo4j过程和函数的标准实用程序库。它包括 450 多个标准程序,提供实用程序、转换、图形更新等功能。它们得到很好的支持,并且很容易作为单…

超详细canal入门

我们都知道一个系统最重要的是数据,数据是保存在数据库里。但是很多时候不单止要保存在数据库中,还要同步保存到Elastic Search、HBase、Redis等等 一、什么是canal 我们先看官网的介绍 canal,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供 增量…

MATLAB绘制动画(三)电影动画

就像是电影拍摄一样,MATLAB存储一系列图形,并将这些图像组成一个特殊的矩阵,由函数movie()播放 Z peaks; figure(Renderer,zbuffer); surfc(Z); axis tight manual; set(gca,NextPlot,replaceChildren); for j 1:20surfc(sin(2*pi*j/20)*…

【微信小程序】阶段开发总结

【微信小程序】阶段开发总结 《工欲善其事,必先利其器》 一、页面代码量过多的解决方案 最近开发的小程序页面里面包含非常多的代码,而且一个页面里面分为了很多步骤,根据不同的进度去显示不同的填写内容,因此,首先我…

Jenkins安装详细教程

Jenkins简介 Jenkins是一个开源的软件项目,是基于java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。 1.持续的软件版本发布/测试项目 2.监控外部调用执行的工作 最近…

Redis 下载安装

一、redis介绍 redis官网地址:http://www.redis.cn/ Redis是当前比较热门的NoSQL系统之一它是一个开源的、使用ANSI C语言编写的key-value存储系统(区别于MySQL的二维表格形式存储)和Memcache类似,但很大程度补偿了Memcache的不…

k8s系列-前端镜像打包集成Jenkin spush到仓库

1.General-->源码管理-->构建触发器-->构建环境-->构建-->构建后操作 General-->源码管理-->构建触发器-->构建环境-->构建-->构建后操作 General-->源码管理-->构建触发器-->构建环境-->构建-->构建后操作 General-->源码管…

阿里云ICP备案服务码在哪里申请查看?教程来了

阿里云备案服务码是什么?ICP备案服务码怎么获取?阿里云备案服务码分为免费和付费两种,申请备案服务码是有限制条件的,需要你的阿里云账号下有可用于申请备案服务码的云产品,如云服务器、建站产品、虚拟主机等&#xff…

详解C语言可变参数列表(stdarg头文件及其定义的宏)

前言:在一些函数定义时,()内的参数并不是所有的函数参数都是唯一的,如printf函数的定义 这里的省略号就代表printf函数的参数是可以变化的,而对于一些函数其参数是固定的,如strlen 之所以有这样…