HTML5中国

 找回密码
 立即注册

QQ登录

只需一步,快速开始

HTML5中国 首页 教程视频 实例代码 查看内容

移动App入侵与逆向破解技术-iOS篇(下)

2016-9-14 10:05| 发布者: Hyukoh| 查看: 3952| 评论: 1|原作者: Bugly_Tony|来自: uml.org

摘要: 懂得如何着手进行app的分析、追踪、注入等实用的破解技术,另外,通过“入侵”,将帮助您理解如何规避常见的安全漏洞是必不可少的技能

 实现“抢”的动作


  上一节我们已经找到了hook的关键点,那么该如何去实现抢的动作?同样我们需要结合动态分析和静态分析,首先得到红包消息体的数据特征,然后再分析处理消息的关键点


  数据包分析


  首先我们的代码需要分辨哪些才是红包消息,方法很简单,用logify追踪BaseMsgContentViewController,然后向微信群发一个红包,观察手机日志输出,我们可以看出消息的数据结构中有个type字段,值是49,这个type应该就是标记消息类型的,如果不确定,可以再发个图片或者文本之类的消息,这个值是不同的:

Administratorde-iPhone WeChat[47410] <Notice>: [1;36m[WxMsgPreview] [m[0;36mTweak.xm:308[m [0;30;46mDEBUG:[m -[<BaseMsgContentViewController: 0x15e0c9a00> addMessageNode:{m_uiMesLocalID=16, m_ui64MesSvrID=1452438635530425509, m_nsFromUsr=10379**2@chatroom, m_nsToUsr=ccg*675~9, m_uiStatus=4, type=49, msgSource="<msgsource>

<silence>0</silence>

<membercount>3</membercount>

</msgsource>

"} layout:1 addMoreMsg:0]

  现在我们能分辨消息类型了,重点来了,怎么实现抢这个事呢,可能聪明人已经猜到了,从ui入手,先找到微信本身的抢红包函数,我们自己来给它构造参数并调用他不就行了?

  把红包点开后,用cycript打印出当前view的层次,就像下面这个,一眼就可以看到重点,WCRedEnvelopesReceiveHomeView就是开红包弹框的类名

  知道类名后,用cycript追踪它,点击开红包,在日志中找到了下图中的内容,从名字来看,这是一个事件处理函数,我们现在要做的,就是把他还原成oc代码,真正实现抢红包功能

Administratorde-iPhone WeChat[91173] <Notice>:

[1;36m[WxMsgPreview] [m[0;36mTweak.xm:8[m [0;30;46mDEBUG:

[m -[<WCRedEnvelopesReceiveHomeView: 0x13cdda8c0> OnOpenRedEnvelopes]

  静态分析法


  怎么把他还原成oc代码,真正实现抢红包功能呢?还得借助一点点汇编技能,只是一点点而已,因为现在的反汇编工具已经很强大了,我们不需要挨个去看寄存器了

  在pc上用hooper打开微信的二进制文件,搜索OnOpenRedEnvelopes,查看汇编代码,注意在图片中最后一行调用了一个WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes函数

  继续搜索WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes这个方法,找到它的汇编代码

  首先他不知道从哪里获取了一个payinfoitem

  然后又获取了payinfo的m_c2cNativeUrl属性

  然后调用substringfromindex吧navtiveurl的前缀截断,并调用bizutil的一个方法把url参数转换成了一个字典

  最终反解出的代码如下,是不是很简单?

NSString *nativeUrl = [[msgWrap m_oWCPayInfoItem] m_c2cNativeUrl];
nativeUrl = [nativeUrl substringFromIndex:[@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length]];
NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrl separator:@"&"];

  继续往下看, 在这里前面三行创建了一个mutable dictionary:

  紧接着下面三个框框处都是调用了setobject:forkey:向里面填东西,那填的东西是啥呢?

  其实这里已经可以看的很清楚了,第一个key是msgtype,值是字符串1,第二个sendid,值是调用了一个objectforkey从另一个字典中取出来的,很显然,另一个字典就是上面从url解析得到的,后面的channelid也是同样的道理

  最终得到的代码如下:

NSMutableDictionary *args = [[%c(NSMutableDictionary) alloc] init];
[args setObject:nativeUrlDict[@"msgtype"] forKey:@"msgType"];
[args setObject:nativeUrlDict[@"sendid"] forKey:@"sendId"];
[args setObject:nativeUrlDict[@"channelid"] forKey:@"channelId"];

  继续往下看从箭头所指的几处,我们可以看见,它的代码是这样的,共分为四步

  第一个箭头调用了mmservicecenter的defaultcenter方法来获取mmservicecenter实例

  第二个箭头调用了CContactMgr的class方法

  第三个箭头调用了第一步获取的mmservicecenter实例的getservice方法,而这个方法是把第二步得到的class作为参数

  第四个箭头很明白了吧,第三步得到了CContactMgr实例,这里就是调用CContactMgr实例的getselfcontact方法获取自己的账户资料

  最终还原的到的代码如下:

CContactMgr *contactManager = [[%c(MMServiceCenter) defaultCenter] getService:[%c(CContactMgr) class]];

CContact *selfContact = [contactManager getSelfContact];

  继续往下看,这里使用刚刚得到的selfcontact来获取displayname和headimgurl,并把它们设置到刚刚的字典里面了,key分别是nickname和headimg

  最终的代码:

[args setObject:[selfContact getContactDisplayName] forKey:@"nickName"];

[args setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];

  接着看,接下来这两段就比较蛋疼了,完全是从内存地址里面取的值,我也不知道他从哪里来,怎么办呢?有没有不懂汇编就能搞定它的捷径呢,答案是有!

  对于第一个,我可以通过它的key猜出来,还记得最开始的时候我们取过payinfo的一个nativeurl属性吧,我们姑且把他传进去

  对于第二个,我们可以猜测sessionUserName大概是会话名称,也就是群名称的意思,从哪里取这个值呢?我们先把也设置成伪代码

  最终的结果如下:

[args setObject:nativeUrl forKey:@"nativeUrl"];

[args setObject:xxx forKey:@"sessionUserName"];

  继续往下看,接下来这一段还是用mmservicecenter来获取WCRedLogicMgr对象,然后调用WCRedLogicMgr的open方法来拆红包,可以想象open方法的参数就是上面我们辛苦组装的字典

  代码如下:

[[[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) 
                          class]] OpenRedEnvelopesRequest:args];


  领红包逻辑


  到这里,我们再总结一下我们上面分析的过程…

  得到m_oWCPayInfoItem属性

  解析m_oWCPayInfoItem的m_c2cNativeUrl属性

  得到selfcontact

  组装相关参数

  调用OpenRedEnvelopesRequest:领取红包

  最终的抢红包代码合并起来如下:

#import "WxMsgPreview.h"

%hook CMessageMgr

-(void)AsyncOnAddMsg:(id)message MsgWrap:(CMessageWrap* )msgWrap {

%log;

%orig;

if(msgWrap.m_uiMessageType == 49){

CContactMgr *contactManager = [[%c(MMServiceCenter) defaultCenter] getService:[%c(CContactMgr) class]];

CContact *selfContact = [contactManager getSelfContact];

if ([msgWrap.m_nsContent rangeOfString:@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao"].location != NSNotFound) { // 红包

NSString *nativeUrl = [[msgWrap m_oWCPayInfoItem] m_c2cNativeUrl];

nativeUrl = [nativeUrl substringFromIndex:[@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length]];

NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrl separator:@"&"];

NSMutableDictionary *args = [[%c(NSMutableDictionary) alloc] init];

[args setObject:nativeUrlDict[@"msgtype"] forKey:@"msgType"];

[args setObject:nativeUrlDict[@"sendid"] forKey:@"sendId"];

[args setObject:nativeUrlDict[@"channelid"] forKey:@"channelId"];

[args setObject:[selfContact getContactDisplayName] forKey:@"nickName"];

[args setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];

[args setObject:nativeUrl forKey:@"nativeUrl"];

[args setObject:msgWrap.m_nsFromUsr forKey:@"sessionUserName"];

[[[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]] OpenRedEnvelopesRequest:args];

}

}

}

%end

  刚才说了,有两个疑难点没有解决:

  第一:我们不知道payinfo是哪里来的,

  第二:sessionusername我们也不知道是哪里来的

  这时候我们可以从我们注入点的参数入手,首先用logify打印出addmsg方法的参数信息,会发现,它的第二个参数刚好有一个payinfo的属性,这样第一个问题迎刃而解了

  第二个我们已经猜测到它代表群名称,所以我们从修改几次群名称,然后再观察logify打印出的参数值的变化,就可以确认出从哪里取了

  通过一番折腾,得出了抢红包的核心代码,再结合上面章节所讲的theos制作tweak包的方法,打包并安装到手机,发个红包试试,是不是秒抢?

  免越狱插件

  检查依赖项

  如果设备没有越狱,是没有mobilesubstrate等环境的,而且一些系统目录是没有读写权限的,这时我么只能从目标app的二进制文件入手,通过手动修改load commands来加载自己的dylib,那么上面我们的插件又是使用theos基于mobilesubstrate编译的,有没有办法确定我们的dylib有没有依赖其他的库呢?

  使用osx自带的otool工具即可,可以看出,我们的lib是依赖于substrate库的,其他的都是系统库,所以我们从越狱设备中把cydiasubstrate文件copy出来重命名为libsunstrate.dylib,和我们的dylib一起放入wechat.app目录中

  最后使用install_name_tool命令修改动态库的路径把它指向app二进制文件的同级目录

  制作安装包

  解决了依赖问题,然后要把我们的库注入到二进制weixin的二进制文件,这一步使用开源的insert_dylib即可 (@executable_path是一个环境变量,指的是二进制文件所在的路径)

insert_dylib命令格式:
./insert_dylib 动态库路径 目标二进制文件
//注入动态库
./insert_dylib [@executable_path](/user/name/executable_path)/wxmsgpreview.dylib WeChat
//打包成ipa
xcrun -sdk iphoneos PackageApplication -v WeChat.app -o ~/WeChat.ipa

  最后使用用企业证书或者开发证书签名对ipa重新签名,就可以放到自己的渠道进行发布了!


  结语


  通过综合运用各种工具,进行静态和动态分析,我们通过实战破解了微信的抢红包逻辑,明白了入侵常用的工具,上面的抢红包代码还有很多改进之处,比如没有判断红包的发送者是不是自己、也没有判断红包里面的文字是不是抢错三倍,有兴趣的童鞋可以尝试优化一下!


 原文链接:http://www.uml.org.cn/mobiledev/201609131.asp

   来源作者:Bugly_Tony

更多

鲜花

握手

雷人

路过

鸡蛋

相关阅读

发表评论

最新评论

引用 linedd963 2017-4-6 22:33
愛欲是創建文明的動力,想交個朋友 :男人尋樂秘密基地+L I N E:d d 9 6 3

查看全部评论(1)

HTML5中国微信

小黑屋|关于我们|HTML5论坛|友情链接|手机版|HTML5中国 ( 京ICP备11006447号 京公网安备:11010802018489号  

GMT+8, 2017-4-27 05:39

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

返回顶部