欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]IOS应用程序攻防-XX瑜伽

[原创]IOS应用程序攻防-XX瑜伽

去年年底在APP STORE接触到这款软件,准备练一字马,下载来发现里面的某些课要花钱啊,于是就把数据库导出来折腾了一番塞回去,所有课程都免费了;跟着练了4个月,一字马也没劈下去,大概瘦了3公斤吧;后来就一直没练,前不久想练一下,点开软件要注册还要登陆,注册后发现以前明码标价的课程都改成VIP课程了,又想着去折腾数据库,可是这次失败了,软件会联网实时获取课程信息,并把课程信息写在本地数据库里以备断网时用;目前注册用户采用积分制,开通一季度要2700积分,做一个任务大概就是10-50积分的样子,哪有那个精力,刚好最近开始研究ios安全,练练手吧.
所需工具:cycript,ida,class-dump,Clutch
XX瑜伽版本:6.1.7
测试环境:ios8.1.2,iPhone 5s
备注:已提前脱壳并导出头文件
SSH到手机,找到XX瑜伽进程,把cycript附加上去

iPhone:~ root# ps aux | grep Yoga
mobile   36568   0.0  6.6   757060  67944   ??  Ss    1:50PM   0:05.17 /var/mobile/Containers/Bundle/Application/190D5770-9A19-4B5C-96F2-7DCE57C7A725/DailyYoga.app/DailyYoga
root     36606   0.0  0.1   544488    536 s000  S+    1:52PM   0:00.01 grep Yoga
iPhone:~ root# cycript -p 36568

找到<全部课程>导航页面,从这个页面入手.

获取rootViewController
cy# UIApp.keyWindow.rootViewController
#"<YGTabBarViewController: 0x15ce9e0c0>"

YGTabBarViewController类信息:

YGTabBarViewController是UITabBarController的子类,所以直接用selectedViewController可以获取当前tab页视图.
cy# #0x15ce9e0c0.selectedViewController
#"<RotationAwareNavigationController: 0x15ceb83b0>"

RotationAwareNavigationController类信息:

RotationAwareNavigationController里面没有什么有价值的,直接viewControllers获取当前正在显示的view
cy# #0x15ceb83b0.viewControllers
@[#"<YGHomeViewController: 0x15cd77140>"]

YGHomeViewController类信息:

从名字能猜出一二了,3个Controller对应导航栏的’推荐课程’,’全部课程’,’瑜伽计划’,所以直接查看当前页面对应的控制器totalSessionViewController
cy# #0x15cd77140.totalSessionViewController
#"<YGTotalSessionViewController: 0x15cd78830>"

YGTotalSessionViewController类信息:

sessionsArray很可能就放着全部课程的信息,cycript验证下

YGSessionInfo类信息:

明显YGSessionInfo存放着当前view中课程的所有信息.编写cycript函数验证下, 获取所有vip课程的名称
function printVipSession(s)
{
  var vipArray = []
  for(view of s)
  {
    if([[view isVip] isEqual:[NSNumber numberWithBool:true]])
    {
      vipArray.push(view.sessionName)
    }
  }
  return vipArray
}

执行结果:

总共有7个VIP课程.要想下载VIP课程,最先想到的就是取消课程的vip标志,把所有课程的isVip都设置为false,可以cycript验证下

命令执行完后,所有YGSessionInfo的isVip都设置为false了,那么在手机上点击下VIP课程看下效果
点击后进入了课程详情,说明验证通过了,那么继续点击”下载”按钮,可怕事情出现了.

应了那句话”然而并没有什么卵用”.再次调用isVip,发现并没有被置回true
cy# [view.isVip  for (view of s)]
[@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false,@false]

既然不是vip课程,为什么还会提示购买vip,其实是当前view并不读取YGTotalSessionViewController下的YGSessionInfo的信息.
继续找出当前view视图:


YGSessionInfoViewController类信息:

一眼就能看到isBuy,这里修改下isBuy为true

点击”下载”按钮,发现依然弹出购买VIP窗口,查看isBuy的值发现已经被更改为false
cy# #0x1392560e0->isBuy
false
cy#

这里的值显然不是作为最终的参考,一定有其他地方有vip标记的,看了下这个类,里面还有一个YGSessionInfo *_sessionInfo,打印下里面的值:

修改这里的isVip值为false,表示这个课程不是VIP专属课程
Cy# #0x1392560e0.sessionInfo.isVip = false

点击”下载”,该有的都有了,已经可以下载了.

接下来就应该看看YGSessionInfo的数据来自哪里,要从控制器里找原因了,看一下YGSessionInfoViewController的初始化函数viewDidLoad,此函数有两处代码与加载课程相关
第一段:

可见这一段仅仅是获取下瑜伽课程的分解动作.
第二段:

直接去查看loadSessionDetailWithSessionId的代码吧

看样子是要联网获取数据了,格式化GET的数据包.

这是XX瑜伽的api接口,目前版本(6.1.7)将近100个接口.
http请求的格式这样的

返回的信息包含了课程的详细信息

回调函数里面:

再去看看[YGSessionInfo sessionInfoWithDictionary]

这里设置YGSessionInfo所需的数据,所以XX瑜伽的下载页面每次刷新都会由YGSessionService重新拉取服务器的数据,看一下YGSessionService可以发现一些有意思的东西

目测loadAllSessionsArray是拉取所有课程信息,IDA进去看下:

原理弄清楚之后写代码就简单了,可以hook的地方很多,可以在YGSessionInfo中勾住isBuy,isVip或者勾住NSUserDefaults中的sessionHasPurchased等等.随便选个吧.
在<XX瑜伽>中还有另外两种收费项目,<瑜伽计划>以及<瑜伽音乐>

破解思路一致, <瑜伽计划>的类是YGProgram:变量名已经自解释了.

<瑜伽音乐>的类是YGAlbum

Theos源代码:
@interface NSUserDefaults (Addition)
@end
%hook NSUserDefaults
+ (_Bool)sessionHasPurchased:(id)arg1
{
	return true;
}
+ (_Bool)musicHasPurchased:(id)arg1
{
	return true;
}
%end
@interface YGProgram : NSObject
{
	 _Bool _isVip;
}
@property(nonatomic) _Bool isVip; // @synthesize isVip=_isVip;
@end
%hook YGProgram
- (void) setIsVip:(bool)bIsVip
{
	%orig(false);
}
%end

效果图:

上传的附件 2.jpg
3.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg
10.jpg
11.jpg
12.jpg
13.jpg
14.jpg
15.jpg
16.jpg
17.jpg
18.jpg
19.jpg
20.jpg
21.jpg
22.jpg
23.jpg
24.jpg
25.jpg
26.jpg
27.jpg
28.jpg
29.jpg
30.jpg
conent.jpg
1.jpg

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功